]> 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)
committerSuren Baghdasaryan <surenb@google.com>
Wed, 23 Nov 2022 02:09:46 +0000 (02:09 +0000)
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 5e2193f59a8d647b3769b7832d1d009d1ae91aba..ee8dc559a66cf2b00e96779847931936c0f73fb0 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.