Thread (48 messages) flat view 48 messages, 6 authors, 4h ago

Re: [PATCH v3 1/5] mm: Make per-VMA locks available universally

From: Suren Baghdasaryan <surenb@google.com>
Date: 2026-08-03 17:52:20
Also in: linux-mm, lkml

On Mon, Aug 3, 2026 at 7:01 AM Vlastimil Babka (SUSE) [off-list ref] wrote:
On 8/2/26 23:54, Suren Baghdasaryan wrote:
quoted
From: Dave Hansen <dave.hansen@linux.intel.com>

The per-VMA locks have been around for several years. They've had some
bugs worked out of them and have seen quite wide use. However, they
are still only available when architectures explicitly enable them.
Remove the conditional compilation around the per-VMA locks, making
them available on all architectures and configs.

The approach up to now seemed to be to add ARCH_SUPPORTS_PER_VMA_LOCK
when the architecture started using per-VMA locks in the fault
handler. But, contrary to the naming, the Kconfig option does not
really indicate whether the architecture supports per-VMA locks or
not. It is more of a marker for whether the architecture is likely to
benefit from per-VMA locks.

To me, the most important thing side-effect of universal availability
is letting per-VMA locks be used in SMP=n configs. This lets us use
per-VMA locking in all x86 code without fallbacks.

Overall, this just generally makes the kernel simpler. Just look at
the diffstat. It also opens the door to users that want to use the
per-VMA locks in common code. Doing *that* brings additional
simplifications.

The downside of this is adding some fields to vm_area_struct and
mm_struct. There are likely ways to optimize this, especially for
things like SMP=n configs. For now, do the simplest thing: use the
same implementation everywhere.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>

Nits:
quoted
diff --git a/mm/Kconfig b/mm/Kconfig
index 060190e12bce..77103b46b679 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1425,19 +1425,6 @@ config LRU_GEN_STATS
 config LRU_GEN_WALKS_MMU
      def_bool y
      depends on LRU_GEN && ARCH_HAS_HW_PTE_YOUNG
-# }
I think either leave this in place, or remove the line above with "#
multi-gen LRU {" as well?
Ah, missed it. I'll keep it in place.
quoted
-
-config ARCH_SUPPORTS_PER_VMA_LOCK
-       def_bool n
-
-config PER_VMA_LOCK
-     def_bool y
-     depends on ARCH_SUPPORTS_PER_VMA_LOCK && MMU && SMP
-     help
-       Allow per-vma locking during page fault handling.
-
-       This feature allows locking each virtual memory area separately when
-       handling page faults instead of taking mmap_lock.

 config LOCK_MM_AND_FIND_VMA
      bool
...
quoted
diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs
index 4764d7b68f2a..2633e704c83d 100644
--- a/rust/kernel/mm.rs
+++ b/rust/kernel/mm.rs
@@ -174,26 +174,20 @@ pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_struct) -> &'a MmWithUser {
     /// When per-vma locks are disabled, this always returns `None`.
     #[inline]
     pub fn lock_vma_under_rcu(&self, vma_addr: usize) -> Option<VmaReadGuard<'_>> {
-        #[cfg(CONFIG_PER_VMA_LOCK)]
         {
             // SAFETY: Calling `bindings::lock_vma_under_rcu` is always okay given an mm where
             // `mm_users` is non-zero.
             let vma = unsafe { bindings::lock_vma_under_rcu(self.as_raw(), vma_addr) };
-            if !vma.is_null() {
-                return Some(VmaReadGuard {
-                    // SAFETY: If `lock_vma_under_rcu` 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,
-                });
+            if vma.is_null() {
+                return None;
             }
+            Some(VmaReadGuard {
+                // SAFETY: If `lock_vma_under_rcu` 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,
+            })
         }
With the "#[cfg(CONFIG_PER_VMA_LOCK)]" does this still need to be in a { }
block?
I don't think it needs to be. I'll remove the extra braces.
Thanks!
quoted
-
-        // Silence warnings about unused variables.
-        #[cfg(not(CONFIG_PER_VMA_LOCK))]
-        let _ = vma_addr;
-
-        None
     }

     /// Lock the mmap read lock.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help