From: Liam R. Howlett Date: Tue, 15 Apr 2025 18:23:00 +0000 (-0400) Subject: rcu hell X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=09cccac641e5c871854007cbe371ad65a8e77ccc;p=users%2Fjedix%2Flinux-maple.git rcu hell Signed-off-by: Liam R. Howlett --- diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c index 5f8d010516f0..39688a512ab4 100644 --- a/drivers/dma-buf/dma-resv.c +++ b/drivers/dma-buf/dma-resv.c @@ -791,8 +791,8 @@ static int __init dma_resv_lockdep(void) dma_resv_lock_slow(&obj, &ctx); fs_reclaim_acquire(GFP_KERNEL); /* for unmap_mapping_range on trylocked buffer objects in shrinkers */ - i_mmap_lock_write(&mapping); - i_mmap_unlock_write(&mapping); +// i_mmap_lock_write(&mapping); +// i_mmap_unlock_write(&mapping); #ifdef CONFIG_MMU_NOTIFIER lock_map_acquire(&__mmu_notifier_invalidate_range_start_map); __dma_fence_might_wait(); diff --git a/include/linux/mm.h b/include/linux/mm.h index 99fc2813b0cc..7a8974ad2301 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -993,16 +993,25 @@ static inline bool vma_is_shared_maywrite(struct vm_area_struct *vma) static inline struct vm_area_struct *vma_find(struct vma_iterator *vmi, unsigned long max) { - return mas_find(&vmi->mas, max - 1); + struct vm_area_struct *vma; + + rcu_read_lock(); + vma = mas_find(&vmi->mas, max - 1); + rcu_read_unlock(); + return vma; } static inline struct vm_area_struct *vma_next(struct vma_iterator *vmi) { + struct vm_area_struct *vma; /* * Uses mas_find() to get the first VMA when the iterator starts. * Calling mas_next() could skip the first entry. */ - return mas_find(&vmi->mas, ULONG_MAX); + rcu_read_lock(); + vma = mas_find(&vmi->mas, ULONG_MAX); + rcu_read_unlock(); + return vma; } static inline @@ -1014,14 +1023,21 @@ struct vm_area_struct *vma_iter_next_range(struct vma_iterator *vmi) static inline struct vm_area_struct *vma_prev(struct vma_iterator *vmi) { - return mas_prev(&vmi->mas, 0); + struct vm_area_struct *vma; + + rcu_read_lock(); + vma = mas_prev(&vmi->mas, 0); + rcu_read_unlock(); + return vma; } static inline int vma_iter_clear_gfp(struct vma_iterator *vmi, unsigned long start, unsigned long end, gfp_t gfp) { + mas_lock(&vmi->mas); __mas_set_range(&vmi->mas, start, end - 1); mas_store_gfp(&vmi->mas, NULL, gfp); + mas_unlock(&vmi->mas); if (unlikely(mas_is_err(&vmi->mas))) return -ENOMEM; diff --git a/lib/maple_tree.c b/lib/maple_tree.c index cb2b0b06a27e..9e96b99d0323 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -3403,8 +3403,7 @@ static bool mas_wr_walk(struct ma_wr_state *wr_mas) if (unlikely(mas_is_span_wr(wr_mas))) return false; - wr_mas->content = mas_slot_locked(mas, wr_mas->slots, - mas->offset); + wr_mas->content = mas_slot(mas, wr_mas->slots, mas->offset); if (ma_is_leaf(wr_mas->type)) return true; @@ -5381,9 +5380,11 @@ int mas_preallocate(struct ma_state *mas, void *entry, gfp_t gfp) { MA_WR_STATE(wr_mas, mas, entry); + rcu_read_lock(); mas_wr_prealloc_setup(&wr_mas); mas->store_type = mas_wr_store_type(&wr_mas); mas_prealloc_calc(&wr_mas, entry); + rcu_read_unlock(); if (!mas->node_request) return 0; diff --git a/mm/mmap.c b/mm/mmap.c index c1ba9bdadef7..81cb9ad69f97 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1269,7 +1269,9 @@ void exit_mmap(struct mm_struct *mm) mmap_read_lock(mm); arch_exit_mmap(mm); + rcu_read_lock(); vma = vma_next(&vmi); + rcu_read_unlock(); if (!vma || unlikely(xa_is_zero(vma))) { /* Can happen if dup_mmap() received an OOM */ mmap_read_unlock(mm); diff --git a/mm/vma.c b/mm/vma.c index c84122a0637e..9b6ee05397dc 100644 --- a/mm/vma.c +++ b/mm/vma.c @@ -1294,8 +1294,10 @@ static int vms_gather_munmap_vmas(struct vma_munmap_struct *vms, goto end_split_failed; } vma_start_write(next); + mas_lock(mas_detach); mas_set(mas_detach, vms->vma_count++); error = mas_store_gfp(mas_detach, next, GFP_KERNEL); + mas_unlock(mas_detach); if (error) goto munmap_gather_failed; @@ -1428,10 +1430,11 @@ int do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma, struct mm_struct *mm, unsigned long start, unsigned long end, struct list_head *uf, bool unlock) { - struct maple_tree mt_detach; + struct maple_tree mt_detach = + MTREE_INIT(mt_detach, vmi->mas.tree->ma_flags); MA_STATE(mas_detach, &mt_detach, 0, 0); - mt_init_flags(&mt_detach, vmi->mas.tree->ma_flags & MT_FLAGS_LOCK_MASK); - mt_on_stack(mt_detach); +// mt_init_flags(&mt_detach, vmi->mas.tree->ma_flags & MT_FLAGS_LOCK_MASK); +// mt_on_stack(mt_detach); struct vma_munmap_struct vms; int error; diff --git a/mm/vma.h b/mm/vma.h index 1b14bbb9afa2..f229a8754556 100644 --- a/mm/vma.h +++ b/mm/vma.h @@ -354,9 +354,7 @@ static inline int vma_iter_prealloc(struct vma_iterator *vmi, { int ret; - mas_lock(&vmi->mas); ret = mas_preallocate(&vmi->mas, vma, GFP_KERNEL | GFP_NOWAIT); - mas_unlock(&vmi->mas); return ret; } @@ -369,7 +367,12 @@ static inline void vma_iter_clear(struct vma_iterator *vmi) static inline struct vm_area_struct *vma_iter_load(struct vma_iterator *vmi) { - return mas_walk(&vmi->mas); + struct vm_area_struct *vma; + + rcu_read_lock(); + vma = mas_walk(&vmi->mas); + rcu_read_unlock(); + return vma; } /* Store a VMA with preallocated memory */ @@ -421,7 +424,12 @@ static inline int vma_iter_bulk_alloc(struct vma_iterator *vmi, static inline struct vm_area_struct *vma_iter_prev_range(struct vma_iterator *vmi) { - return mas_prev_range(&vmi->mas, 0); + struct vm_area_struct *vma; + + rcu_read_lock(); + vma = mas_prev_range(&vmi->mas, 0); + rcu_read_unlock(); + return vma; } /*