]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
nommu: Remove uses of VMA linked list
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 29 Oct 2021 14:18:13 +0000 (10:18 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Mon, 14 Mar 2022 18:49:47 +0000 (14:49 -0400)
Use the maple tree or VMA iterator instead.  This is faster and will
allow us to shrink the VMA.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
mm/nommu.c

index 26a9056e508f0840bae4155222a8bf81e98f3c44..645d11d3a8ab613784a155db687ce037f5c7cb0a 100644 (file)
@@ -1381,6 +1381,7 @@ static int shrink_vma(struct mm_struct *mm,
  */
 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;
@@ -1392,7 +1393,7 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, struct list
        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) {
@@ -1411,7 +1412,7 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, struct list
                                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 {
@@ -1460,6 +1461,7 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
  */
 void exit_mmap(struct mm_struct *mm)
 {
+       VMA_ITERATOR(vmi, mm, 0);
        struct vm_area_struct *vma;
 
        if (!mm)
@@ -1467,12 +1469,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);
 }