From: Suren Baghdasaryan <surenb@google.com>
To: akpm@linux-foundation.org
Cc: dave.hansen@linux.intel.com, Liam.Howlett@oracle.com,
ljs@kernel.org, david@redhat.com, willy@infradead.org,
shakeel.butt@linux.dev, vbabka@kernel.org, jannh@google.com,
aliceryhl@google.com, arve@android.com, cmllamas@google.com,
christian@brauner.io, tkjos@android.com, dsahern@kernel.org,
davem@davemloft.net, gregkh@linuxfoundation.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
netdev@vger.kernel.org, surenb@google.com
Subject: [PATCH v7 4/5] binder: Remove mmap_lock fallback
Date: Mon, 31 Aug 2026 13:30:55 -0700 [thread overview]
Message-ID: <20260831203056.838265-5-surenb@google.com> (raw)
In-Reply-To: <20260831203056.838265-1-surenb@google.com>
From: Dave Hansen <dave.hansen@linux.intel.com>
Previously, the per-VMA locking could fail in the face of writers
which necessitate a fallback to mmap_lock. The new
vma_start_read_unlocked() will wait for writers instead of failing.
Use the new helper. Wait for writers. Remove the fallback to mmap_lock.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: linux-mm@kvack.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arve Hjønnevåg <arve@android.com>
Cc: Todd Kjos <tkjos@android.com>
Cc: Christian Brauner <christian@brauner.io>
Cc: Carlos Llamas <cmllamas@google.com>
Cc: Alice Ryhl <aliceryhl@google.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: David Ahern <dsahern@kernel.org>
Cc: netdev@vger.kernel.org
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
---
drivers/android/binder/page_range.rs | 19 +++----------------
drivers/android/binder_alloc.c | 17 +++++------------
rust/kernel/mm.rs | 28 ++++++++++++++++++++++++++++
3 files changed, 36 insertions(+), 28 deletions(-)
diff --git a/drivers/android/binder/page_range.rs b/drivers/android/binder/page_range.rs
index 52ffbf3504e7..71febd3d5b07 100644
--- a/drivers/android/binder/page_range.rs
+++ b/drivers/android/binder/page_range.rs
@@ -439,22 +439,9 @@ unsafe fn use_page_slow(&self, i: usize) -> Result<()> {
// workqueue.
let mm = MmWithUser::into_mmput_async(self.mm.mmget_not_zero().ok_or(ESRCH)?);
{
- let vma_read;
- let mmap_read;
- let vma = if let Some(ret) = mm.lock_vma_under_rcu(vma_addr) {
- vma_read = ret;
- check_vma(&vma_read, self)
- } else {
- mmap_read = mm.mmap_read_lock();
- mmap_read
- .vma_lookup(vma_addr)
- .and_then(|vma| check_vma(vma, self))
- };
-
- match vma {
- Some(vma) => vma.vm_insert_page(user_page_addr, &new_page)?,
- None => return Err(ESRCH),
- }
+ let vma_read_guard = mm.vma_start_read_unlocked(vma_addr).ok_or(ESRCH)?;
+ let vma = check_vma(&vma_read_guard, self).ok_or(ESRCH)?;
+ vma.vm_insert_page(user_page_addr, &new_page)?;
}
let inner = self.lock.lock();
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index fcb744088e77..d6eae0aa7085 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -259,21 +259,14 @@ static int binder_page_insert(struct binder_alloc *alloc,
struct vm_area_struct *vma;
int ret = -ESRCH;
- /* attempt per-vma lock first */
- vma = lock_vma_under_rcu(mm, addr);
- if (vma) {
- if (binder_alloc_is_mapped(alloc))
- ret = vm_insert_page(vma, addr, page);
- vma_end_read(vma);
+ vma = vma_start_read_unlocked(mm, addr);
+ if (!vma)
return ret;
- }
- /* fall back to mmap_lock */
- mmap_read_lock(mm);
- vma = vma_lookup(mm, addr);
- if (vma && binder_alloc_is_mapped(alloc))
+ if (binder_alloc_is_mapped(alloc))
ret = vm_insert_page(vma, addr, page);
- mmap_read_unlock(mm);
+
+ vma_end_read(vma);
return ret;
}
diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs
index f4fa54616085..58bc1793fdaf 100644
--- a/rust/kernel/mm.rs
+++ b/rust/kernel/mm.rs
@@ -186,6 +186,34 @@ pub fn lock_vma_under_rcu(&self, vma_addr: usize) -> Option<VmaReadGuard<'_>> {
})
}
+ /// Find the VMA covering 'address' and read-lock it.
+ ///
+ /// The fast path does not take mmap_lock. Waits for writers to finish if the
+ /// VMA is being modified by taking mmap_lock.
+ /// Use when mmap_lock is not held, otherwise use vma_start_read_locked().
+ /// Nothing prevents VMAs being unmapped/mapped before or after the VMA is
+ /// looked up, if a stronger guarantee is required, take an mmap_lock.
+ ///
+ /// Return: If a VMA exists which spans @address, return that VMA, read-locked.
+ /// If no VMA is mapped there or, very unlikely, a reference count overflow
+ /// occurred, return NULL.
+ #[inline]
+ pub fn vma_start_read_unlocked(&self, vma_addr: usize) -> Option<VmaReadGuard<'_>> {
+ // SAFETY: We may invoke `vma_start_read_unlocked` because we know this `mm` has non-zero
+ // `mm_users`.
+ let vma = unsafe { bindings::vma_start_read_unlocked(self.as_raw(), vma_addr) };
+ if vma.is_null() {
+ return None;
+ }
+ // INVARIANT: We just acquired the VMA read lock.
+ Some(VmaReadGuard {
+ // SAFETY: If `vma_start_read_unlocked` returns a non-null ptr, then it points at a
+ // valid vma. The vma is stable for as long as the vma read lock is held.
+ vma: unsafe { VmaRef::from_raw(vma) },
+ _nts: NotThreadSafe,
+ })
+ }
+
/// Lock the mmap read lock.
#[inline]
pub fn mmap_read_lock(&self) -> MmapReadGuard<'_> {
--
2.55.0.966.g6673acef38-goog
next prev parent reply other threads:[~2026-08-31 20:31 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 20:30 [PATCH v7 0/5] mm: Unconditional per-VMA locks and cleanups Suren Baghdasaryan
2026-08-31 20:30 ` [PATCH v7 1/5] mm: Make per-VMA locks available universally Suren Baghdasaryan
2026-09-10 10:09 ` David Hildenbrand (Arm)
2026-09-10 14:50 ` Suren Baghdasaryan
2026-09-10 15:20 ` David Hildenbrand (Arm)
2026-08-31 20:30 ` [PATCH v7 2/5] binder: Make shrinker rely solely on per-VMA lock Suren Baghdasaryan
2026-08-31 20:30 ` [PATCH v7 3/5] mm: Add RCU-based VMA lookup helper that waits for writers Suren Baghdasaryan
2026-08-31 20:30 ` Suren Baghdasaryan [this message]
2026-08-31 20:30 ` [PATCH v7 5/5] tcp: Remove mmap_lock fallback path Suren Baghdasaryan
2026-09-01 7:37 ` Paolo Abeni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260831203056.838265-5-surenb@google.com \
--to=surenb@google.com \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=aliceryhl@google.com \
--cc=arve@android.com \
--cc=christian@brauner.io \
--cc=cmllamas@google.com \
--cc=dave.hansen@linux.intel.com \
--cc=davem@davemloft.net \
--cc=david@redhat.com \
--cc=dsahern@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=jannh@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=tkjos@android.com \
--cc=vbabka@kernel.org \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.