Thread (33 messages) 33 messages, 7 authors, 2026-06-16

Re: [PATCH v2 2/5] binder: Make shrinker rely solely on per-VMA lock

From: Suren Baghdasaryan <surenb@google.com>
Date: 2026-06-12 16:01:54
Also in: linux-mm, lkml

On Fri, Jun 12, 2026 at 8:41 AM Vlastimil Babka (SUSE)
[off-list ref] wrote:
On 6/11/26 21:59, Suren Baghdasaryan wrote:
quoted
On Thu, Jun 11, 2026 at 12:53 AM Alice Ryhl [off-list ref] wrote:
quoted
quoted
 b/drivers/android/binder_alloc.c |   26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff -puN drivers/android/binder_alloc.c~binder-try-vma-lock drivers/android/binder_alloc.c
--- a/drivers/android/binder_alloc.c~binder-try-vma-lock      2026-06-10 15:57:55.274412018 -0700
+++ b/drivers/android/binder_alloc.c  2026-06-10 15:57:55.277412124 -0700
@@ -1142,7 +1142,6 @@ enum lru_status binder_alloc_free_page(s
      struct vm_area_struct *vma;
      struct page *page_to_free;
      unsigned long page_addr;
-     int mm_locked = 0;
      size_t index;

      if (!mmget_not_zero(mm))
@@ -1151,15 +1150,12 @@ enum lru_status binder_alloc_free_page(s
      index = mdata->page_index;
      page_addr = alloc->vm_start + index * PAGE_SIZE;

-     /* attempt per-vma lock first */
+     /*
+      * Attempt per-vma lock. This is essentially a
+      * "trylock". It can fail even if the VMA exists
+      * for 'page_addr'.
+      */
      vma = lock_vma_under_rcu(mm, page_addr);
-     if (!vma) {
-             /* fall back to mmap_lock */
-             if (!mmap_read_trylock(mm))
-                     goto err_mmap_read_lock_failed;
-             mm_locked = 1;
-             vma = vma_lookup(mm, page_addr);
-     }

      if (!mutex_trylock(&alloc->mutex))
              goto err_get_alloc_mutex_failed;
@@ -1188,13 +1184,11 @@ enum lru_status binder_alloc_free_page(s
              zap_vma_range(vma, page_addr, PAGE_SIZE);

              trace_binder_unmap_user_end(alloc, index);
+
+             vma_end_read(vma);
      }

      mutex_unlock(&alloc->mutex);
-     if (mm_locked)
-             mmap_read_unlock(mm);
-     else
-             vma_end_read(vma);
      mmput_async(mm);
      binder_free_page(page_to_free);
@@ -1203,11 +1197,9 @@ enum lru_status binder_alloc_free_page(s
 err_invalid_vma:
      mutex_unlock(&alloc->mutex);
 err_get_alloc_mutex_failed:
-     if (mm_locked)
-             mmap_read_unlock(mm);
-     else
+     if (vma)
              vma_end_read(vma);
-err_mmap_read_lock_failed:
+err_vma_lock_failed:
This label is unused btw, which is related to Alice's point.
quoted
quoted
quoted
      mmput_async(mm);
If the vma lookup fails because the mmap write lock is held, but the vma
actually exists (has not been unmapped), then this code might "successfully"
remove the page without invoking zap_vma_range(). This means that the
page does not actually get freed and will just hang around forever until
the process owning the vma exits or Binder needs this page and maps a
new page on top of the page.
Yeah, I think if lock_vma_under_rcu() returns NULL you just need to
jump to err_mmap_read_lock_failed, like we currently do if
mmap_read_trylock() fails.
I don't think that will be enough as well, as the current code AFAICS does
something meaninfgul when mmap_read_trylock() suceeds but vma_lookup returns
NULL because there's no vma at that address. Now we would just assume the
trylock failed even if the reason was that vma lookup found nothing for the
address. The problem is that lock_vma_under_rcu() can't distinguish those
two outcomes, so we would need something that does?
Ah, you are right. I misread the condition in that code.
Changing lock_vma_under_rcu() to distinguish between lock failure and
no-VMA case would require some refactoring. vma_start_read() should
return -ESRCH if VMA was not found and then we handle that in
lock_vma_under_rcu(). That part is not hard because vma_start_read()
has only 2 users but then we have to propagate that error code to
lock_vma_under_rcu() users and there are many of them. Though
converting these users is straght forward. Instead of checking if
(vma) they would have to check if (IS_ERR_OR_NULL(vma)).
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help