]> www.infradead.org Git - users/willy/linux.git/commitdiff
ipc/shm: Stop using the vma linked list
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Mon, 4 Jan 2021 19:51:19 +0000 (14:51 -0500)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Wed, 20 Oct 2021 20:00:33 +0000 (16:00 -0400)
When searching for a VMA, a maple state can be used instead of the linked list in
the mm_struct

Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
ipc/shm.c

index ab749be6d8b71ffc351a0a6fa92b5027593966b6..ed662867967914042bf7febc2ff20b5a48f1bbda 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1631,6 +1631,7 @@ long ksys_shmdt(char __user *shmaddr)
        loff_t size = 0;
        struct file *file;
        struct vm_area_struct *next;
+       MA_STATE(mas, &mm->mm_mt, addr, addr);
 #endif
 
        if (addr & ~PAGE_MASK)
@@ -1660,11 +1661,11 @@ long ksys_shmdt(char __user *shmaddr)
         * match the usual checks anyway. So assume all vma's are
         * above the starting address given.
         */
-       vma = find_vma(mm, addr);
 
 #ifdef CONFIG_MMU
+       vma = mas_find(&mas, ULONG_MAX);
        while (vma) {
-               next = vma->vm_next;
+               next = mas_find(&mas, ULONG_MAX);
 
                /*
                 * Check if the starting address would match, i.e. it's
@@ -1703,21 +1704,21 @@ long ksys_shmdt(char __user *shmaddr)
         */
        size = PAGE_ALIGN(size);
        while (vma && (loff_t)(vma->vm_end - addr) <= size) {
-               next = vma->vm_next;
-
                /* finding a matching vma now does not alter retval */
                if ((vma->vm_ops == &shm_vm_ops) &&
                    ((vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) &&
                    (vma->vm_file == file))
                        do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start, NULL);
-               vma = next;
+
+               vma = mas_find(&mas, addr + size - 1);
        }
 
 #else  /* CONFIG_MMU */
+       vma = mas_walk(&mas);
        /* under NOMMU conditions, the exact address to be destroyed must be
         * given
         */
-       if (vma && vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) {
+       if (vma && vma->vm_ops == &shm_vm_ops) {
                do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start, NULL);
                retval = 0;
        }