[RFC PATCH 11/28] mm/mmap: mark VMAs as locked before merging or splitting them

From: Suren Baghdasaryan
Date: Mon Aug 29 2022 - 17:26:54 EST


Decisions about whether VMAs can be merged or split must be made while
VMAs are protected from the changes which can affect that decision.
For example, merge_vma uses vma->anon_vma in its decision whether the
VMA can be merged. Meanwhile, page fault handler changes vma->anon_vma
during COW operation.
Mark all VMAs which might be affected by a merge or split operation as
locked before making decision how such operations should be performed.

Signed-off-by: Suren Baghdasaryan <surenb@xxxxxxxxxx>
---
mm/mmap.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/mm/mmap.c b/mm/mmap.c
index ed58cf0689b2..ade3909c89b4 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1147,10 +1147,17 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
if (vm_flags & VM_SPECIAL)
return NULL;

+ if (prev)
+ vma_mark_locked(prev);
next = vma_next(mm, prev);
area = next;
- if (area && area->vm_end == end) /* cases 6, 7, 8 */
+ if (area)
+ vma_mark_locked(area);
+ if (area && area->vm_end == end) { /* cases 6, 7, 8 */
next = next->vm_next;
+ if (next)
+ vma_mark_locked(next);
+ }

/* verify some invariant that must be enforced by the caller */
VM_WARN_ON(prev && addr <= prev->vm_start);
@@ -2687,6 +2694,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
struct vm_area_struct *new;
int err;

+ vma_mark_locked(vma);
if (vma->vm_ops && vma->vm_ops->may_split) {
err = vma->vm_ops->may_split(vma, addr);
if (err)
--
2.37.2.672.g94769d06f0-goog