From: "Matthew Wilcox (Oracle)" Subject: nommu: remove uses of VMA linked list Use the maple tree or VMA iterator instead. This is faster and will allow us to shrink the VMA. Link: https://lkml.kernel.org/r/20220426150616.3937571-67-Liam.Howlett@oracle.com Signed-off-by: Matthew Wilcox (Oracle) Signed-off-by: Liam R. Howlett Acked-by: Vlastimil Babka Cc: Catalin Marinas Cc: David Howells Cc: Will Deacon Cc: Yu Zhao Signed-off-by: Andrew Morton --- mm/nommu.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) --- a/mm/nommu.c~nommu-remove-uses-of-vma-linked-list +++ a/mm/nommu.c @@ -1383,6 +1383,7 @@ static int shrink_vma(struct mm_struct * */ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, struct list_head *uf) { + MA_STATE(mas, &mm->mm_mt, start, start); struct vm_area_struct *vma; unsigned long end; int ret; @@ -1394,7 +1395,7 @@ int do_munmap(struct mm_struct *mm, unsi end = start + len; /* find the first potentially overlapping VMA */ - vma = find_vma(mm, start); + vma = mas_find(&mas, end - 1); if (!vma) { static int limit; if (limit < 5) { @@ -1413,7 +1414,7 @@ int do_munmap(struct mm_struct *mm, unsi return -EINVAL; if (end == vma->vm_end) goto erase_whole_vma; - vma = vma->vm_next; + vma = mas_next(&mas, end - 1); } while (vma); return -EINVAL; } else { @@ -1462,6 +1463,7 @@ SYSCALL_DEFINE2(munmap, unsigned long, a */ void exit_mmap(struct mm_struct *mm) { + VMA_ITERATOR(vmi, mm, 0); struct vm_area_struct *vma; if (!mm) @@ -1469,12 +1471,17 @@ void exit_mmap(struct mm_struct *mm) mm->total_vm = 0; - while ((vma = mm->mmap)) { - mm->mmap = vma->vm_next; + /* + * Lock the mm to avoid assert complaining even though this is the only + * user of the mm + */ + mmap_write_lock(mm); + for_each_vma(vmi, vma) { delete_vma_from_mm(vma); delete_vma(mm, vma); cond_resched(); } + mmap_write_unlock(mm); __mt_destroy(&mm->mm_mt); } _