mm: remove re-walk from mmap_region()
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Mon, 24 Jul 2023 18:31:48 +0000 (14:31 -0400)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 18 Aug 2023 17:12:48 +0000 (10:12 -0700)
Using vma_iter_set() will reset the tree and cause a re-walk.  Use
vmi_iter_config() to set the write to a sub-set of the range.  Change
the file case to also use vmi_iter_config() so that the end is correctly
set.

Link: https://lkml.kernel.org/r/20230724183157.3939892-7-Liam.Howlett@oracle.com
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Peng Zhang <zhangpeng.00@bytedance.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/internal.h
mm/mmap.c

index 7d11ebe..c5ba08f 100644 (file)
@@ -1041,6 +1041,14 @@ static inline bool vma_soft_dirty_enabled(struct vm_area_struct *vma)
        return !(vma->vm_flags & VM_SOFTDIRTY);
 }
 
+static inline void vma_iter_config(struct vma_iterator *vmi,
+               unsigned long index, unsigned long last)
+{
+       MAS_BUG_ON(&vmi->mas, vmi->mas.node != MAS_START &&
+                  (vmi->mas.index > index || vmi->mas.last < index));
+       __mas_set_range(&vmi->mas, index, last - 1);
+}
+
 /*
  * VMA Iterator functions shared between nommu and mmap
  */
index 5fbc7d7..a1a5948 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2676,8 +2676,11 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
 
        next = vma_next(&vmi);
        prev = vma_prev(&vmi);
-       if (vm_flags & VM_SPECIAL)
+       if (vm_flags & VM_SPECIAL) {
+               if (prev)
+                       vma_iter_next_range(&vmi);
                goto cannot_expand;
+       }
 
        /* Attempt to expand an old mapping */
        /* Check next */
@@ -2698,6 +2701,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
                merge_start = prev->vm_start;
                vma = prev;
                vm_pgoff = prev->vm_pgoff;
+       } else if (prev) {
+               vma_iter_next_range(&vmi);
        }
 
 
@@ -2708,9 +2713,9 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
                goto expanded;
        }
 
+       if (vma == prev)
+               vma_iter_set(&vmi, addr);
 cannot_expand:
-       if (prev)
-               vma_iter_next_range(&vmi);
 
        /*
         * Determine the object being mapped and call the appropriate
@@ -2723,7 +2728,7 @@ cannot_expand:
                goto unacct_error;
        }
 
-       vma_iter_set(&vmi, addr);
+       vma_iter_config(&vmi, addr, end);
        vma->vm_start = addr;
        vma->vm_end = end;
        vm_flags_init(vma, vm_flags);
@@ -2750,7 +2755,7 @@ cannot_expand:
                if (WARN_ON((addr != vma->vm_start)))
                        goto close_and_free_vma;
 
-               vma_iter_set(&vmi, addr);
+               vma_iter_config(&vmi, addr, end);
                /*
                 * If vm_flags changed after call_mmap(), we should try merge
                 * vma again as we may succeed this time.