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. Signed-off-by: Liam R. Howlett <Liam.Howlett@xxxxxxxxxx> --- mm/internal.h | 8 ++++++++ mm/mmap.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mm/internal.h b/mm/internal.h index 24437f11d3c2..cdf06f680d6e 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -1034,6 +1034,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 */ diff --git a/mm/mmap.c b/mm/mmap.c index fd3f505b40cc..8b3e58d6ac40 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2659,7 +2659,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, 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); @@ -2686,7 +2686,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, 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. -- 2.39.2