]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm/mmap: Call __do_munmap() on slow path of do_brk_munmap()
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Mon, 9 Nov 2020 18:41:05 +0000 (13:41 -0500)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Tue, 5 Jan 2021 17:30:41 +0000 (12:30 -0500)
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 <Liam.Howlett@Oracle.com>
mm/mmap.c

index 7be88f923bc31d470dee4facf125324d229eab2c..25ac50c669d4a394f9fae4c800d96a9f91eeedcd 100644 (file)
--- 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,