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

From: Vlastimil Babka (SUSE)

Date: Mon Aug 03 2026 - 10:23:00 EST


On 8/2/26 23:54, Suren Baghdasaryan wrote:
> From: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>
>
> 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@xxxxxxxxxxxxxxx>
> Signed-off-by: Suren Baghdasaryan <surenb@xxxxxxxxxx>

Reviewed-by: Vlastimil Babka (SUSE) <vbabka@xxxxxxxxxx>

Nits:

> 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?

> -
> -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

...

> 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?

> -
> - // Silence warnings about unused variables.
> - #[cfg(not(CONFIG_PER_VMA_LOCK))]
> - let _ = vma_addr;
> -
> - None
> }
>
> /// Lock the mmap read lock.