From: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: David Hildenbrand <david@kernel.org>,
"Liam R . Howlett" <Liam.Howlett@oracle.com>,
Vlastimil Babka <vbabka@suse.cz>, Mike Rapoport <rppt@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Michal Hocko <mhocko@suse.com>,
Shakeel Butt <shakeel.butt@linux.dev>,
Jann Horn <jannh@google.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linux-rt-devel@lists.linux.dev,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>, Will Deacon <will@kernel.org>,
Boqun Feng <boqun.feng@gmail.com>,
Waiman Long <longman@redhat.com>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Clark Williams <clrkwllms@kernel.org>,
Steven Rostedt <rostedt@goodmis.org>
Subject: [PATCH RESEND 3/3] mm: add + use vma_is_stabilised(), vma_assert_stabilised() helpers
Date: Fri, 16 Jan 2026 13:36:47 +0000 [thread overview]
Message-ID: <87b36e11c632fee6c965b944974d8dc4357b5904.1768569863.git.lorenzo.stoakes@oracle.com> (raw)
In-Reply-To: <cover.1768569863.git.lorenzo.stoakes@oracle.com>
Sometimes we wish to assert that a VMA is stable, that is - the VMA cannot
be changed underneath us. This will be the case if EITHER the VMA lock or
the mmap lock is held.
In order to be able to do so this patch adds a vma_is_stabilised()
predicate.
We specify this differently based on whether CONFIG_PER_VMA_LOCK is
specified - if it is then naturally we check both whether a VMA lock is
held or an mmap lock held, otherwise we need only check the mmap lock.
Note that we only trigger the assert is CONFIG_DEBUG_VM is set, as having
this lock unset would indicate a programmatic error, so a release kernel
runtime assert doesn't make much sense.
There are a couple places in the kernel where we already do this check -
the anon_vma_name() helper in mm/madvise.c and vma_flag_set_atomic() in
include/linux/mm.h, which we update to use vma_assert_stabilised().
These were in fact implemented incorrectly - if neither the mmap lock nor
the VMA lock were held, these asserts did not fire.
However since these asserts are debug-only, and a large number of test
configurations will have CONFIG_PER_VMA_LOCK set, it has likely had no
real-world impact.
This change corrects this mistake at any rate.
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
include/linux/mm.h | 4 +---
include/linux/mmap_lock.h | 23 ++++++++++++++++++++++-
mm/madvise.c | 4 +---
3 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 44a2a9c0a92f..8707059f4d37 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1008,9 +1008,7 @@ static inline void vma_flag_set_atomic(struct vm_area_struct *vma,
{
unsigned long *bitmap = ACCESS_PRIVATE(&vma->flags, __vma_flags);
- /* mmap read lock/VMA read lock must be held. */
- if (!rwsem_is_locked(&vma->vm_mm->mmap_lock))
- vma_assert_locked(vma);
+ vma_assert_stabilised(vma);
if (__vma_flag_atomic_valid(vma, bit))
set_bit((__force int)bit, bitmap);
diff --git a/include/linux/mmap_lock.h b/include/linux/mmap_lock.h
index 9f6932ffaaa0..711885cb5372 100644
--- a/include/linux/mmap_lock.h
+++ b/include/linux/mmap_lock.h
@@ -66,7 +66,6 @@ static inline void __mmap_lock_trace_released(struct mm_struct *mm, bool write)
#endif /* CONFIG_TRACING */
-
static inline bool mmap_lock_is_contended(struct mm_struct *mm)
{
return rwsem_is_contended(&mm->mmap_lock);
@@ -272,6 +271,11 @@ static inline bool vma_is_locked(struct vm_area_struct *vma)
return vma_is_read_locked(vma) || vma_is_write_locked(vma);
}
+static inline bool vma_is_stabilised(struct vm_area_struct *vma)
+{
+ return vma_is_locked(vma) || mmap_is_locked(vma->vm_mm);
+}
+
static inline void vma_assert_write_locked(struct vm_area_struct *vma)
{
VM_BUG_ON_VMA(!vma_is_write_locked(vma), vma);
@@ -358,6 +362,11 @@ static inline struct vm_area_struct *lock_vma_under_rcu(struct mm_struct *mm,
return NULL;
}
+static inline bool vma_is_stabilised(struct vm_area_struct *vma)
+{
+ return mmap_is_locked(vma->vm_mm);
+}
+
static inline void vma_assert_locked(struct vm_area_struct *vma)
{
mmap_assert_locked(vma->vm_mm);
@@ -463,4 +472,16 @@ static inline void mmap_read_unlock_non_owner(struct mm_struct *mm)
up_read_non_owner(&mm->mmap_lock);
}
+/**
+ * vma_assert_stabilised() - assert that this VMA cannot be changed from
+ * underneath us either by having a VMA or mmap lock held.
+ * @vma: The VMA whose stability we wish to assess.
+ *
+ * Note that this will only trigger an assert if CONFIG_DEBUG_VM is set.
+ */
+static inline void vma_assert_stabilised(struct vm_area_struct *vma)
+{
+ VM_BUG_ON_VMA(!vma_is_stabilised(vma), vma);
+}
+
#endif /* _LINUX_MMAP_LOCK_H */
diff --git a/mm/madvise.c b/mm/madvise.c
index 4bf4c8c38fd3..1f3040688f04 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -109,9 +109,7 @@ void anon_vma_name_free(struct kref *kref)
struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma)
{
- if (!rwsem_is_locked(&vma->vm_mm->mmap_lock))
- vma_assert_locked(vma);
-
+ vma_assert_stabilised(vma);
return vma->anon_name;
}
--
2.52.0
next prev parent reply other threads:[~2026-01-16 13:37 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-16 13:36 [PATCH RESEND 0/3] add and use vma_assert_stabilised() helper Lorenzo Stoakes
2026-01-16 13:36 ` [PATCH RESEND 1/3] locking: add rwsem_is_write_locked(), update non-lockdep asserts Lorenzo Stoakes
2026-01-16 15:08 ` Zi Yan
2026-01-16 16:29 ` Lorenzo Stoakes
2026-01-16 15:12 ` Peter Zijlstra
2026-01-16 15:50 ` Lorenzo Stoakes
2026-01-16 15:57 ` Sebastian Andrzej Siewior
2026-01-16 16:21 ` Lorenzo Stoakes
2026-01-16 16:41 ` Sebastian Andrzej Siewior
2026-01-16 16:56 ` Lorenzo Stoakes
2026-01-17 2:30 ` Boqun Feng
2026-01-16 13:36 ` [PATCH RESEND 2/3] mm/vma: add vma_is_*_locked() helpers Lorenzo Stoakes
2026-01-16 13:36 ` Lorenzo Stoakes [this message]
2026-01-16 20:45 ` [PATCH RESEND 3/3] mm: add + use vma_is_stabilised(), vma_assert_stabilised() helpers Zi Yan
2026-01-16 20:47 ` Zi Yan
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=87b36e11c632fee6c965b944974d8dc4357b5904.1768569863.git.lorenzo.stoakes@oracle.com \
--to=lorenzo.stoakes@oracle.com \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=bigeasy@linutronix.de \
--cc=boqun.feng@gmail.com \
--cc=clrkwllms@kernel.org \
--cc=david@kernel.org \
--cc=jannh@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=longman@redhat.com \
--cc=mhocko@suse.com \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=rppt@kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=surenb@google.com \
--cc=vbabka@suse.cz \
--cc=will@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox