From 07461b7aef9288ababe707f26bc94e1048774b21 Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Mon, 9 Nov 2020 13:41:05 -0500 Subject: [PATCH] mm/mmap: Call __do_munmap() on slow path of do_brk_munmap() do_brk_munmap() would not handle the unmapping of multiple VMAs in the case of mprotect'ed regions of a brk() so just use the full __do_munmap() in these rare cases. Signed-off-by: Liam R. Howlett --- mm/mmap.c | 47 ++++------------------------------------------- 1 file changed, 4 insertions(+), 43 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index 7be88f923bc3..25ac50c669d4 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1850,13 +1850,10 @@ static unsigned long unmapped_area(struct vm_unmapped_area_info *info) if (length < info->length) return -ENOMEM; - rcu_read_lock(); if (mas_get_empty_area(&mas, info->low_limit, info->high_limit - 1, length)) { - rcu_read_unlock(); return -ENOMEM; } - rcu_read_unlock(); gap = mas.index; gap += (info->align_offset - gap) & info->align_mask; return gap; @@ -1881,13 +1878,10 @@ static unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info) if (length < info->length) return -ENOMEM; - rcu_read_lock(); if (mas_get_empty_area_rev(&mas, info->low_limit, info->high_limit, length)) { - rcu_read_unlock(); return -ENOMEM; } - rcu_read_unlock(); gap = (mas.index + info->align_mask) & ~info->align_mask; gap -= info->align_offset & info->align_mask; return gap; @@ -2847,6 +2841,7 @@ out: /* * bkr_munmap() - Unmap a parital vma. + * @mas: The maple tree state. * @vma: The vma to be modified * @newbrk: the start of the address to unmap * @oldbrk: The end of the address to unmap @@ -2867,42 +2862,7 @@ static int do_brk_munmap(struct ma_state *mas, struct vm_area_struct *vma, arch_unmap(mm, newbrk, oldbrk); if (vma->vm_start >= newbrk) { // remove entire mapping. - struct vm_area_struct *prev, *next; - - - ret = userfaultfd_unmap_prep(&unmap, newbrk, oldbrk, uf); - if (ret) - return ret; - - if (mm->locked_vm) - unlock_range(vma, oldbrk); - - mas->index = vma->vm_start; - mas->last = vma->vm_end - 1; - if (mas_store_gfp(mas, NULL, GFP_KERNEL)) - goto mas_store_fail; - - /* TODO: Drop linked list */ - prev = vma->vm_prev; - next = vma->vm_next; - if (prev) { - prev->vm_next = next; - if (prev->vm_flags & VM_GROWSUP) - ret = 0; - } - if (next) { - next->vm_prev = prev; - if (next->vm_flags & VM_GROWSDOWN) - ret = 0; - } - - vmacache_invalidate(mm); - if (ret) - mmap_write_downgrade(mm); - - unmap_region(mm, vma, prev, newbrk, oldbrk); - /* Fix up all other VM information */ - remove_vma_list(mm, vma); + ret = __do_munmap(mm, newbrk, oldbrk - newbrk, &uf, true); goto munmap_full_vma; } @@ -2935,7 +2895,7 @@ static int do_brk_munmap(struct ma_state *mas, struct vm_area_struct *vma, munmap_full_vma: validate_mm_mt(mm); - return 1; + return ret; mas_store_fail: vma->vm_end = oldbrk; @@ -2944,6 +2904,7 @@ mas_store_fail: /* * do_brk_flags() - Increase the brk vma if the flags match. + * @mas: The maple tree state. * @addr: The start address * @len: The length of the increase * @vma: The vma, -- 2.50.1