From: Liam R. Howlett Date: Sat, 20 Feb 2021 17:56:07 +0000 (-0500) Subject: mm/mmap: Lock maple tree when using mas_store_gfp() X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=75dceeed30dab6cc660a5da78d0cf302669f1738;p=users%2Fjedix%2Flinux-maple.git mm/mmap: Lock maple tree when using mas_store_gfp() When storing to the maple tree, take the write lock to avoid entering/exiting the use of RCU during a write operation. Signed-off-by: Liam R. Howlett --- diff --git a/mm/mmap.c b/mm/mmap.c index 8a915579e61b..c0852a0275cd 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -454,9 +454,14 @@ static void __vma_link_file(struct vm_area_struct *vma) */ static inline int vma_mas_store(struct vm_area_struct *vma, struct ma_state *mas) { + int ret; + mas->index = vma->vm_start; mas->last = vma->vm_end - 1; - return mas_store_gfp(mas, vma, GFP_KERNEL); + mas_lock(mas); + ret = mas_store_gfp(mas, vma, GFP_KERNEL); + mas_unlock(mas); + return ret; } /* @@ -470,9 +475,14 @@ static inline int vma_mas_store(struct vm_area_struct *vma, struct ma_state *mas */ static inline int vma_mas_remove(struct vm_area_struct *vma, struct ma_state *mas) { + int ret; + mas->index = vma->vm_start; mas->last = vma->vm_end - 1; - return mas_store_gfp(mas, NULL, GFP_KERNEL); + mas_lock(mas); + ret = mas_store_gfp(mas, NULL, GFP_KERNEL); + mas_unlock(mas); + return ret; } /* @@ -2335,7 +2345,9 @@ static inline unsigned long detach_range(struct mm_struct *mm, mas_set(&mas, src->last + 1); /* Drop removed area from the tree */ *vma = mas_find(&mas, ULONG_MAX); + mas_lock(src); mas_store_gfp(src, NULL, GFP_KERNEL); + mas_unlock(src); /* Decrement map_count */ mm->map_count -= count; /* Set the upper limit */ @@ -3054,8 +3066,12 @@ static int do_brk_flags(struct ma_state *mas, struct ma_state *ma_prev, } vma->vm_end = addr + len; vma->vm_flags |= VM_SOFTDIRTY; - if (mas_store_gfp(ma_prev, vma, GFP_KERNEL)) + mas_lock(ma_prev); + if (mas_store_gfp(ma_prev, vma, GFP_KERNEL)) { + mas_unlock(ma_prev); goto mas_mod_fail; + } + mas_unlock(ma_prev); if (vma->anon_vma) { anon_vma_interval_tree_post_update_vma(vma); anon_vma_unlock_write(vma->anon_vma);