From: Liam R. Howlett Date: Tue, 10 May 2022 02:41:23 +0000 (-0400) Subject: fs/exec: Remove vma_adjust() call and use mmap and maple tree calls. X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=05cd9537c49abf0bd3a51721d46b373d0378ac2d;p=users%2Fjedix%2Flinux-maple.git fs/exec: Remove vma_adjust() call and use mmap and maple tree calls. Remove yet another user of vma_adjust(). Signed-off-by: Liam R. Howlett --- diff --git a/fs/exec.c b/fs/exec.c index b5e3bfd52b53..be67f089a5f6 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -687,8 +688,9 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) unsigned long new_start = old_start - shift; unsigned long new_end = old_end - shift; VMA_ITERATOR(vmi, mm, new_start); - struct vm_area_struct *next; + struct vm_area_struct *next, *new_vma; struct mmu_gather tlb; + MA_STATE(mas, &mm->mm_mt, new_start, new_start); BUG_ON(new_start > new_end); @@ -699,10 +701,12 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) if (vma != vma_next(&vmi)) return -EFAULT; + if (mas_preallocate(&mas, vma, GFP_KERNEL)) + return -ENOMEM; /* * cover the whole range: [new_start, old_end) */ - if (vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL)) + if (vma_expand(&mas, vma, new_start, old_end, vma->vm_pgoff, vma)) return -ENOMEM; /* @@ -711,7 +715,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) */ if (length != move_page_tables(vma, old_start, vma, new_start, length, false)) - return -ENOMEM; + goto pt_move_failed; lru_add_drain(); tlb_gather_mmu(&tlb, mm); @@ -734,12 +738,22 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) } tlb_finish_mmu(&tlb); + if (sub_vma(mm, vma, &new_vma, new_start, new_end)) + goto sub_vma_failed; + /* * Shrink the vma to just the new range. Always succeeds. */ - vma_adjust(vma, new_start, new_end, vma->vm_pgoff, NULL); + vma_mas_store(new_vma, &mas); + vma_mas_szero(&mas, new_end, old_end); return 0; + +sub_vma_failed: +pt_move_failed: + mas_destroy(&mas); + + return -ENOMEM; } /* diff --git a/include/linux/mm.h b/include/linux/mm.h index d0422f62b876..c12afba3e5f9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2645,6 +2645,15 @@ void anon_vma_interval_tree_verify(struct anon_vma_chain *node); extern int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin); extern int vma_adjust(struct vm_area_struct *vma, unsigned long start, unsigned long end, pgoff_t pgoff, struct vm_area_struct *expand); +inline int vma_expand(struct ma_state *mas, struct vm_area_struct *vma, + unsigned long start, unsigned long end, pgoff_t pgoff, + struct vm_area_struct *next); +inline void vma_mas_szero(struct ma_state *mas, unsigned long start, + unsigned long end); +inline void vma_mas_store(struct vm_area_struct *vma, struct ma_state *mas); +int sub_vma(struct mm_struct *mm, struct vm_area_struct *vma, + struct vm_area_struct **new_vma, unsigned long start, unsigned long end); + extern struct vm_area_struct *vma_merge(struct mm_struct *, struct vm_area_struct *prev, unsigned long addr, unsigned long end, unsigned long vm_flags, struct anon_vma *, struct file *, pgoff_t, diff --git a/mm/mmap.c b/mm/mmap.c index d4a0716b926d..a01eec04d4c1 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -507,7 +507,7 @@ void vma_mas_remove(struct vm_area_struct *vma, struct ma_state *mas) * @start: The start address to zero * @end: The end address to zero. */ -static inline void vma_mas_szero(struct ma_state *mas, unsigned long start, +inline void vma_mas_szero(struct ma_state *mas, unsigned long start, unsigned long end) { trace_vma_mas_szero(mas->tree, start, end - 1);