]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
rcu hell ma_lock_sheaves
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Tue, 15 Apr 2025 18:23:00 +0000 (14:23 -0400)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Tue, 15 Apr 2025 18:23:00 +0000 (14:23 -0400)
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
drivers/dma-buf/dma-resv.c
include/linux/mm.h
lib/maple_tree.c
mm/mmap.c
mm/vma.c
mm/vma.h

index 5f8d010516f07f542827df329ef6042339e586cc..39688a512ab49c3529e4b5de5f26579bd3cc4d03 100644 (file)
@@ -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();
index 99fc2813b0cc32fed3342f0c8ee371f46183cf9e..7a8974ad2301d7950ac0bde2682ed5e98e605c65 100644 (file)
@@ -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;
 
index cb2b0b06a27e61732ae2ed7fd88fd738a375c804..9e96b99d03239ce4d1a4c48fa944ae55d4266264 100644 (file)
@@ -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;
 
index c1ba9bdadef7331f6dc9ea438e977e682edbb3f8..81cb9ad69f974e9be1a6c121d1c71e833629a133 100644 (file)
--- 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);
index c84122a0637e1cef79fb8c1514927c83db782331..9b6ee05397dc2e395ddb15836e16bf21be9764e1 100644 (file)
--- 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;
 
index 1b14bbb9afa21a5381dcca597842356e5ef75ea1..f229a8754556736faeef2137701bd734af3f7cdd 100644 (file)
--- 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;
 }
 
 /*