From 61b337f6508fb566553f204a69e743524730e860 Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Mon, 1 May 2023 20:27:52 -0400 Subject: [PATCH] mm: Fix __vma_adjust() writes for the maple tree Only write when necessary to the maple tree. This should only occur when the VMA changes. In the __vma_adjust() case, it is either the vma when it is expanded, the next vma when the boundary expands into 'vma', writing the 'insert', or when vma expands/shrinks for shift_arg_pages(). The mas_preallocate() setup should track the intended write to ensure the correct number of nodes are preallocated for the pending write. Signed-off-by: Liam R. Howlett --- mm/mmap.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index 5ea97c037ab2..c374ff80eb69 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -628,7 +628,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, bool vma_changed = false; long adjust_next = 0; int remove_next = 0; - MA_STATE(mas, &mm->mm_mt, 0, 0); + MA_STATE(mas, &mm->mm_mt, start, end - 1); struct vm_area_struct *exporter = NULL, *importer = NULL; if (next && !insert) { @@ -713,6 +713,13 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, } } + if (adjust_next < 0) + mas_set_range(&mas, next->vm_start + adjust_next, + next->vm_end - 1); + else if (insert) + mas_set_range(&mas, insert->vm_start, insert->vm_end - 1); + + if (mas_preallocate(&mas, vma, GFP_KERNEL)) return -ENOMEM; @@ -757,24 +764,23 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, } if (start != vma->vm_start) { - if ((vma->vm_start < start) && - (!insert || (insert->vm_end != start))) { + if ((vma->vm_start < start) && !insert) { vma_mas_szero(&mas, vma->vm_start, start); VM_WARN_ON(insert && insert->vm_start > vma->vm_start); - } else { + } else if (!insert) { vma_changed = true; } vma->vm_start = start; } if (end != vma->vm_end) { if (vma->vm_end > end) { - if (!insert || (insert->vm_start != end)) { + if (adjust_next >= 0 && !insert) { vma_mas_szero(&mas, end, vma->vm_end); mas_reset(&mas); VM_WARN_ON(insert && insert->vm_end < vma->vm_end); } - } else { + } else if (!insert) { vma_changed = true; } vma->vm_end = end; -- 2.50.1