mm/mmap: Combine multiple if statements in vma_merge() maple_v6.0-rc1_extras
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Wed, 24 Aug 2022 19:37:56 +0000 (15:37 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Fri, 26 Aug 2022 17:57:56 +0000 (13:57 -0400)
Currently vma_merge() searches from 0 upwards if there is no prev vma,
or from prev->vm_end if there is a prev vma.  The check for merging with
prev also checks if prev exists.  The ordering is not important at this
stage, so move the merging check above finding the next vma so that prev
can be checked only once.

Also start searching from vma_start as apposed to 0.  If there is no
previous then there won't be a vma before vma_start.  The code reads
more clearly this way.

Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
mm/mmap.c

index 8ab6b59432f7e8180882f47c2b6c6c100b8a16b8..985ee98a89656752af7af5a7ffb25684d4722bce 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -903,7 +903,7 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
        unsigned long vma_end = end;
        long adj_next = 0;
        unsigned long vma_start = addr;
-       MA_STATE(mas, &mm->mm_mt, 0, 0);
+       MA_STATE(mas, &mm->mm_mt, vma_start, vma_start);
 
        validate_mm(mm);
        /*
@@ -913,17 +913,8 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
        if (vm_flags & VM_SPECIAL)
                return NULL;
 
-       next = find_vma(mm, prev ? prev->vm_end : 0);
-       mid = next;
-       if (next && next->vm_end == end)                /* cases 6, 7, 8 */
-               next = find_vma(mm, next->vm_end);
-
-       /* verify some invariant that must be enforced by the caller */
-       VM_WARN_ON(prev && addr <= prev->vm_start);
-       VM_WARN_ON(mid && end > mid->vm_end);
-       VM_WARN_ON(addr >= end);
-
        if (prev) {
+               mas_set(&mas, prev->vm_end);
                res = prev;
                vma = prev;
                vma_start = prev->vm_start;
@@ -935,6 +926,17 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
                        merge_prev = true;
                }
        }
+
+       next = mas_find(&mas, end);
+       mid = next;
+       if (mid && mid->vm_end == end)          /* cases 6, 7, 8 */
+               next = mas_find(&mas, end);
+
+       /* verify some invariant that must be enforced by the caller */
+       VM_WARN_ON(prev && addr <= prev->vm_start);
+       VM_WARN_ON(mid && end > mid->vm_end);
+       VM_WARN_ON(addr >= end);
+
        /* Can we merge the successor? */
        if (next && end == next->vm_start &&
                        mpol_equal(policy, vma_policy(next)) &&