drm/xe: keep pulling mem_access_get further back
authorMatthew Auld <matthew.auld@intel.com>
Wed, 24 May 2023 17:56:54 +0000 (18:56 +0100)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Tue, 19 Dec 2023 23:34:10 +0000 (18:34 -0500)
Lockdep is unhappy about ggtt->lock -> runtime_pm, where it seems
to think this can somehow get inverted. The ggtt->lock looks like a
potentially sensitive driver lock, so likely a sensible move to never
call the runtime_pm routines while holding it. Actually it looks like
d3cold wants to grab this, so perhaps this can indeed deadlock.

v2:
 - Don't forget about xe_gt_tlb_invalidation_vma(), which now needs
   explicit access_get.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_ggtt.c
drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c

index 9890335..1ed22b5 100644 (file)
@@ -142,12 +142,14 @@ static void xe_ggtt_initial_clear(struct xe_ggtt *ggtt)
        u64 start, end;
 
        /* Display may have allocated inside ggtt, so be careful with clearing here */
+       xe_device_mem_access_get(ggtt->gt->xe);
        mutex_lock(&ggtt->lock);
        drm_mm_for_each_hole(hole, &ggtt->mm, start, end)
                xe_ggtt_clear(ggtt, start, end - start);
 
        xe_ggtt_invalidate(ggtt->gt);
        mutex_unlock(&ggtt->lock);
+       xe_device_mem_access_put(ggtt->gt->xe);
 }
 
 int xe_ggtt_init(struct xe_gt *gt, struct xe_ggtt *ggtt)
@@ -284,12 +286,14 @@ static int __xe_ggtt_insert_bo_at(struct xe_ggtt *ggtt, struct xe_bo *bo,
        if (err)
                return err;
 
+       xe_device_mem_access_get(ggtt->gt->xe);
        mutex_lock(&ggtt->lock);
        err = drm_mm_insert_node_in_range(&ggtt->mm, &bo->ggtt_node, bo->size,
                                          alignment, 0, start, end, 0);
        if (!err)
                xe_ggtt_map_bo(ggtt, bo);
        mutex_unlock(&ggtt->lock);
+       xe_device_mem_access_put(ggtt->gt->xe);
 
        return err;
 }
@@ -318,6 +322,7 @@ int xe_ggtt_insert_bo(struct xe_ggtt *ggtt, struct xe_bo *bo)
 
 void xe_ggtt_remove_node(struct xe_ggtt *ggtt, struct drm_mm_node *node)
 {
+       xe_device_mem_access_get(ggtt->gt->xe);
        mutex_lock(&ggtt->lock);
 
        xe_ggtt_clear(ggtt, node->start, node->size);
@@ -327,6 +332,7 @@ void xe_ggtt_remove_node(struct xe_ggtt *ggtt, struct drm_mm_node *node)
        xe_ggtt_invalidate(ggtt->gt);
 
        mutex_unlock(&ggtt->lock);
+       xe_device_mem_access_put(ggtt->gt->xe);
 }
 
 void xe_ggtt_remove_bo(struct xe_ggtt *ggtt, struct xe_bo *bo)
index 20f8f0a..44e442b 100644 (file)
@@ -114,7 +114,6 @@ static int send_tlb_invalidation(struct xe_guc *guc,
         * need to be updated.
         */
 
-       xe_device_mem_access_get(gt->xe);
        mutex_lock(&guc->ct.lock);
        seqno = gt->tlb_invalidation.seqno;
        if (fence) {
@@ -143,7 +142,6 @@ static int send_tlb_invalidation(struct xe_guc *guc,
        if (ret < 0 && fence)
                invalidation_fence_signal(fence);
        mutex_unlock(&guc->ct.lock);
-       xe_device_mem_access_put(gt->xe);
 
        return ret;
 }
@@ -196,7 +194,7 @@ int xe_gt_tlb_invalidation_vma(struct xe_gt *gt,
        struct xe_device *xe = gt_to_xe(gt);
 #define MAX_TLB_INVALIDATION_LEN       7
        u32 action[MAX_TLB_INVALIDATION_LEN];
-       int len = 0;
+       int len = 0, ret;
 
        XE_BUG_ON(!vma);
 
@@ -250,7 +248,11 @@ int xe_gt_tlb_invalidation_vma(struct xe_gt *gt,
 
        XE_BUG_ON(len > MAX_TLB_INVALIDATION_LEN);
 
-       return send_tlb_invalidation(&gt->uc.guc, fence, action, len);
+       xe_device_mem_access_get(gt->xe);
+       ret = send_tlb_invalidation(&gt->uc.guc, fence, action, len);
+       xe_device_mem_access_put(gt->xe);
+
+       return ret;
 }
 
 static bool tlb_invalidation_seqno_past(struct xe_gt *gt, int seqno)