From: "Liam R. Howlett" <Liam.Howlett@xxxxxxxxxx> 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@xxxxxxxxxx> --- ipc/shm.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ipc/shm.c b/ipc/shm.c index ab749be6d8b7..ed6628679679 100644 --- 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; } -- 2.30.2