From nobody Wed Dec 31 14:26:50 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3DBA9C4332F for ; Thu, 2 Nov 2023 19:01:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377563AbjKBTB5 (ORCPT ); Thu, 2 Nov 2023 15:01:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377485AbjKBTBc (ORCPT ); Thu, 2 Nov 2023 15:01:32 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A96951B3 for ; Thu, 2 Nov 2023 12:01:07 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id 41be03b00d2f7-5b9a1494e65so955006a12.2 for ; Thu, 02 Nov 2023 12:01:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1698951667; x=1699556467; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=aVzeNsrhFxDI/jOpRx8dBpYw5Z5e6SHn+B/lZdoXIWc=; b=O0kw0Mgoje4pYGsmFeJcdjG1CJO06LpZC1UU0bYWUZsrVBdz6EcCfjyTCpIS13cJO5 SKkeRR3er7hN12nPml93bUKVjMCVctVKLSS0ctZRrnjO9kvUOj1CtymP7BDnsQAj/MRS TEHXbWoc3XtYLzKOw5Zol+YsIJY6bLXWaGs1UyDFoSm6HRlg4GyrQmYa+V1URa+8TUms /JIwitUra/r0A0Pfy3LqVpYvSPucPZj0PBDDec1byWh5W5YaFadYSwd7uBGuTc4Sihti qkVNOe6Bm9iUAQ09ujkhYyjqnknh/kymBCTQOusCP0S2hGegUwmnZgFDKdttzRupCxBK e5rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698951667; x=1699556467; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=aVzeNsrhFxDI/jOpRx8dBpYw5Z5e6SHn+B/lZdoXIWc=; b=Vmh4zFofdCgShnVud1otQo86ieZ+lRsnJfXAqiGi1YSaT7qkev6TNK/r+0+w2YMKrD XHlm2Pg9XPKxcc5Dazi+3d4xoWomFNOhWgYOlFkOCbOsGp8YS0fTltChRDGQTofUOTzg rOxWpHDglJTBGFbzA2ilbGms7Ulg2XISkyo/1p4i3yNfAhe+Zmia6T+JC9YVioNKkBvv qaUjo3Tu/VLOctp1qXpItlyPo7/68g+65E2UieNK7Ygo+c9fYAuOaKIbCibaI9YYnqMp xe/P5SDkG5Az4AT5PdpbAS0mT0C2uwEFvPf7e2QewW6bTVYG5scsdsgWs0E66r/QZq90 uw7A== X-Gm-Message-State: AOJu0YwX0BGXsV9OPa7NcdLUeyDPYP+Su6kOHi+yFyxFkQCuddiwKHW4 +Gecac0wLYCw533PzcS36MI6SYigbR3ruA== X-Google-Smtp-Source: AGHT+IGC+gTosBpbNifDSoF4YeNYx4QzxVdvqPxSVnhtp5e49MURkp36/roScjs4oz5FkSSIQbXiXmkQBVFgMA== X-Received: from xllamas.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5070]) (user=cmllamas job=sendgmr) by 2002:a63:4106:0:b0:5bd:3e1c:c163 with SMTP id o6-20020a634106000000b005bd3e1cc163mr14660pga.1.1698951667091; Thu, 02 Nov 2023 12:01:07 -0700 (PDT) Date: Thu, 2 Nov 2023 18:59:17 +0000 In-Reply-To: <20231102185934.773885-1-cmllamas@google.com> Mime-Version: 1.0 References: <20231102185934.773885-1-cmllamas@google.com> X-Mailer: git-send-email 2.42.0.869.gea05f2083d-goog Message-ID: <20231102185934.773885-17-cmllamas@google.com> Subject: [PATCH 16/21] binder: refactor page range allocation From: Carlos Llamas To: Greg Kroah-Hartman , "=?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?=" , Todd Kjos , Martijn Coenen , Joel Fernandes , Christian Brauner , Carlos Llamas , Suren Baghdasaryan Cc: linux-kernel@vger.kernel.org, kernel-team@android.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Instead of looping through the page range twice to first determine if the mmap lock is required, simply do it per-page as needed. Split out all this logic into a separate binder_get_user_page_remote() function. Signed-off-by: Carlos Llamas Reviewed-by: Alice Ryhl --- drivers/android/binder_alloc.c | 107 +++++++++++++++------------------ 1 file changed, 47 insertions(+), 60 deletions(-) diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 4821a29799c8..56936430954f 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -203,14 +203,51 @@ static void binder_free_page_range(struct binder_allo= c *alloc, } } =20 +static int binder_get_user_page_remote(struct binder_alloc *alloc, + struct binder_lru_page *lru_page, + unsigned long addr) +{ + struct page *page; + int ret =3D 0; + + if (!mmget_not_zero(alloc->mm)) + return -ESRCH; + + mmap_write_lock(alloc->mm); + if (!alloc->vma) { + pr_err("%d: %s failed, no vma\n", alloc->pid, __func__); + ret =3D -ESRCH; + goto out; + } + + page =3D alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO); + if (!page) { + pr_err("%d: failed to allocate page\n", alloc->pid); + ret =3D -ENOMEM; + goto out; + } + + ret =3D vm_insert_page(alloc->vma, addr, page); + if (ret) { + pr_err("%d: %s failed to insert page at %lx with %d\n", + alloc->pid, __func__, addr, ret); + __free_page(page); + ret =3D -ENOMEM; + goto out; + } + + lru_page->page_ptr =3D page; +out: + mmap_write_unlock(alloc->mm); + mmput_async(alloc->mm); + return ret; +} + static int binder_allocate_page_range(struct binder_alloc *alloc, unsigned long start, unsigned long end) { - struct vm_area_struct *vma =3D NULL; struct binder_lru_page *page; - struct mm_struct *mm =3D NULL; unsigned long page_addr; - bool need_mm =3D false; =20 binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: allocate pages %lx-%lx\n", @@ -222,32 +259,9 @@ static int binder_allocate_page_range(struct binder_al= loc *alloc, trace_binder_update_page_range(alloc, true, start, end); =20 for (page_addr =3D start; page_addr < end; page_addr +=3D PAGE_SIZE) { - page =3D &alloc->pages[(page_addr - alloc->buffer) / PAGE_SIZE]; - if (!page->page_ptr) { - need_mm =3D true; - break; - } - } - - if (need_mm && mmget_not_zero(alloc->mm)) - mm =3D alloc->mm; - - if (mm) { - mmap_write_lock(mm); - vma =3D alloc->vma; - } - - if (!vma && need_mm) { - binder_alloc_debug(BINDER_DEBUG_USER_ERROR, - "%d: binder_alloc_buf failed to map pages in userspace, no vma\n", - alloc->pid); - goto err_no_vma; - } - - for (page_addr =3D start; page_addr < end; page_addr +=3D PAGE_SIZE) { - int ret; + unsigned long index; bool on_lru; - size_t index; + int ret; =20 index =3D (page_addr - alloc->buffer) / PAGE_SIZE; page =3D &alloc->pages[index]; @@ -262,26 +276,15 @@ static int binder_allocate_page_range(struct binder_a= lloc *alloc, continue; } =20 - if (WARN_ON(!vma)) - goto err_page_ptr_cleared; - trace_binder_alloc_page_start(alloc, index); - page->page_ptr =3D alloc_page(GFP_KERNEL | - __GFP_HIGHMEM | - __GFP_ZERO); - if (!page->page_ptr) { - pr_err("%d: binder_alloc_buf failed for page at %lx\n", - alloc->pid, page_addr); - goto err_alloc_page_failed; - } + page->alloc =3D alloc; INIT_LIST_HEAD(&page->lru); =20 - ret =3D vm_insert_page(vma, page_addr, page->page_ptr); + ret =3D binder_get_user_page_remote(alloc, page, page_addr); if (ret) { - pr_err("%d: binder_alloc_buf failed to map page at %lx in userspace\n", - alloc->pid, page_addr); - goto err_vm_insert_page_failed; + binder_free_page_range(alloc, start, page_addr); + return ret; } =20 if (index + 1 > alloc->pages_high) @@ -289,24 +292,8 @@ static int binder_allocate_page_range(struct binder_al= loc *alloc, =20 trace_binder_alloc_page_end(alloc, index); } - if (mm) { - mmap_write_unlock(mm); - mmput_async(mm); - } - return 0; =20 -err_vm_insert_page_failed: - __free_page(page->page_ptr); - page->page_ptr =3D NULL; -err_alloc_page_failed: -err_page_ptr_cleared: - binder_free_page_range(alloc, start, page_addr); -err_no_vma: - if (mm) { - mmap_write_unlock(mm); - mmput_async(mm); - } - return vma ? -ENOMEM : -ESRCH; + return 0; } =20 static inline void binder_alloc_set_vma(struct binder_alloc *alloc, --=20 2.42.0.869.gea05f2083d-goog