summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlice Ryhl <aliceryhl@google.com>2026-05-07 11:07:47 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-05-23 13:47:32 +0200
commit908ad5bcccdcd8ab5582c0b7fe3091c5146c0b7a (patch)
treec76885857bee996fefd8cfe221b0ba628264a3fb
parent570ff5c850e71b0d038758b91b5bbccea534d877 (diff)
rust_binder: use lock_vma_under_rcu() in shrinker
The shrinker callback currently uses the mmap read trylock operation to attempt to access the vma, but it's generally better to only lock the vma instead of the whole mmap when you can. When lock_vma_under_rcu() fails, there is no reason to lock the mmap lock instead because it's already a trylock operation that is allowed to fail. Signed-off-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Lorenzo Stoakes <ljs@kernel.org> Link: https://patch.msgid.link/20260507-binder-shrinker-lockvma-v1-1-76e3406bbfa6@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/android/binder/page_range.rs24
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/android/binder/page_range.rs b/drivers/android/binder/page_range.rs
index e54a90e62402..e82a5523804f 100644
--- a/drivers/android/binder/page_range.rs
+++ b/drivers/android/binder/page_range.rs
@@ -705,7 +705,7 @@ unsafe extern "C" fn rust_shrink_free_page(
let page;
let page_index;
let mm;
- let mmap_read;
+ let vma_read;
let mm_mutex;
let vma_addr;
let range_ptr;
@@ -728,17 +728,18 @@ unsafe extern "C" fn rust_shrink_free_page(
None => return LRU_SKIP,
};
- mmap_read = match mm.mmap_read_trylock() {
- Some(guard) => guard,
- None => return LRU_SKIP,
- };
-
// We can't lock it normally here, since we hold the lru lock.
let inner = match range.lock.try_lock() {
Some(inner) => inner,
None => return LRU_SKIP,
};
+ vma_addr = inner.vma_addr;
+ vma_read = match mm.lock_vma_under_rcu(vma_addr) {
+ Some(guard) => guard,
+ None => return LRU_SKIP,
+ };
+
// SAFETY: The item is in this lru list, so it's okay to remove it.
unsafe { bindings::list_lru_isolate(lru, item) };
@@ -751,7 +752,6 @@ unsafe extern "C" fn rust_shrink_free_page(
// `zap_page_range` before we release the mmap lock, so `use_page_slow` will not be able to
// insert a new page until after our call to `zap_page_range`.
page = unsafe { PageInfo::take_page(info) };
- vma_addr = inner.vma_addr;
// From this point on, we don't access this PageInfo or ShrinkablePageRange again, because
// they can be freed at any point after we unlock `lru_lock`. This is with the exception of
@@ -761,14 +761,12 @@ unsafe extern "C" fn rust_shrink_free_page(
// SAFETY: The lru lock is locked when this method is called.
unsafe { bindings::spin_unlock(&raw mut (*lru).lock) };
- if let Some(unchecked_vma) = mmap_read.vma_lookup(vma_addr) {
- if let Some(vma) = check_vma(unchecked_vma, range_ptr) {
- let user_page_addr = vma_addr + (page_index << PAGE_SHIFT);
- vma.zap_vma_range(user_page_addr, PAGE_SIZE);
- }
+ if let Some(vma) = check_vma(&vma_read, range_ptr) {
+ let user_page_addr = vma_addr + (page_index << PAGE_SHIFT);
+ vma.zap_vma_range(user_page_addr, PAGE_SIZE);
}
- drop(mmap_read);
+ drop(vma_read);
drop(mm_mutex);
drop(mm);
drop(page);