]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm: perform VMA walk in find_mergeable_anon_vma under RCU read lock
authorSuren Baghdasaryan <surenb@google.com>
Wed, 19 Oct 2022 20:12:19 +0000 (20:12 +0000)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Wed, 4 Jan 2023 20:59:26 +0000 (15:59 -0500)
find_mergeable_anon_vma walks VMA tree unders assumption that the caller
holds mmap_lock for write. Perform this walk under RCU protection to make
it safe without holding this lock.

Signed-off-by: Suren Baghdasaryan <surenb@google.com>
mm/mmap.c

index c9291fb0018af5095886094ee500ecf0086a2d4e..bd73441548d77a9f320e9b94d585050b809c3542 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1169,12 +1169,20 @@ struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma)
        struct anon_vma *anon_vma = NULL;
        struct vm_area_struct *prev, *next;
 
+       /*
+        * This search can be done with per-vma lock and without mmap_lock,
+        * therefore acquire RCU read lock to prevent the tree from changing.
+        */
+       rcu_read_lock();
+
        /* Try next first. */
        next = mas_walk(&mas);
        if (next) {
                anon_vma = reusable_anon_vma(next, vma, next);
-               if (anon_vma)
+               if (anon_vma) {
+                       rcu_read_unlock();
                        return anon_vma;
+               }
        }
 
        prev = mas_prev(&mas, 0);
@@ -1184,6 +1192,7 @@ struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma)
        if (prev)
                anon_vma = reusable_anon_vma(prev, prev, vma);
 
+       rcu_read_unlock();
        /*
         * We might reach here with anon_vma == NULL if we can't find
         * any reusable anon_vma.