fixup: remove wrong assumption in find_mergeable_anon_vma
authorSuren Baghdasaryan <surenb@google.com>
Fri, 9 Dec 2022 20:11:56 +0000 (12:11 -0800)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Wed, 4 Jan 2023 20:59:27 +0000 (15:59 -0500)
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
mm/memory.c
mm/mmap.c

index b90f72db83d2013a0f1b166cba21832121b5569f..e4e958ec75ea7efb1ddaedf7fa89fa4a18303341 100644 (file)
@@ -5281,6 +5281,10 @@ retry:
        if (!vma_is_anonymous(vma))
                goto inval;
 
+       /* find_mergeable_anon_vma uses adjacent vmas which are not locked */
+       if (!vma->anon_vma)
+               goto inval;
+
        /*
        * Due to the possibility of userfault handler dropping mmap_lock, avoid
        * it for now and fall back to page fault handling under mmap_lock.
index f0c6f122a60b2c7301a4323bfc4dc87845d4b548..e12a8b21726bf6452052b1bd705d72fd9d55f84e 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1169,20 +1169,12 @@ 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) {
-                       rcu_read_unlock();
+               if (anon_vma)
                        return anon_vma;
-               }
        }
 
        prev = mas_prev(&mas, 0);
@@ -1192,7 +1184,6 @@ 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.