Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/xe: Hold a PM ref when GT TLB invalidations are inflight

Avoid GT TLB invalidation timeouts by holding a PM ref when
invalidations are inflight.

v2:
- Drop PM ref before signaling fence (CI)
v3:
- Move invalidation_fence_signal helper in tlb timeout to previous
patch (Matthew Auld)

Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Nirmoy Das <nirmoy.das@intel.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Nirmoy Das <nirmoy.das@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240719172905.1527927-4-matthew.brost@intel.com
(cherry picked from commit 0a382f9bc5dc4744a33970a5ed4df8f9c702ee9e)
Requires: 46209ce5287b ("drm/xe: Add xe_gt_tlb_invalidation_fence_init
helper")
Requires: 0e414ab036e0 ("drm/xe: Drop xe_gt_tlb_invalidation_wait")
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

authored by

Matthew Brost and committed by
Rodrigo Vivi
f0027022 58bfe667

+29 -3
+21 -2
drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
··· 13 13 #include "xe_guc.h" 14 14 #include "xe_guc_ct.h" 15 15 #include "xe_mmio.h" 16 + #include "xe_pm.h" 16 17 #include "xe_sriov.h" 17 18 #include "xe_trace.h" 18 19 #include "regs/xe_guc_regs.h" ··· 42 41 bool stack = test_bit(FENCE_STACK_BIT, &fence->base.flags); 43 42 44 43 trace_xe_gt_tlb_invalidation_fence_signal(xe, fence); 44 + xe_gt_tlb_invalidation_fence_fini(fence); 45 45 dma_fence_signal(&fence->base); 46 46 if (!stack) 47 47 dma_fence_put(&fence->base); ··· 265 263 266 264 xe_gt_tlb_invalidation_fence_init(gt, &fence, true); 267 265 ret = xe_gt_tlb_invalidation_guc(gt, &fence); 268 - if (ret < 0) 266 + if (ret < 0) { 267 + xe_gt_tlb_invalidation_fence_fini(&fence); 269 268 return ret; 269 + } 270 270 271 271 xe_gt_tlb_invalidation_fence_wait(&fence); 272 272 } else if (xe_device_uc_enabled(xe) && !xe_device_wedged(xe)) { ··· 493 489 * @fence: TLB invalidation fence to initialize 494 490 * @stack: fence is stack variable 495 491 * 496 - * Initialize TLB invalidation fence for use 492 + * Initialize TLB invalidation fence for use. xe_gt_tlb_invalidation_fence_fini 493 + * must be called if fence is not signaled. 497 494 */ 498 495 void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, 499 496 struct xe_gt_tlb_invalidation_fence *fence, 500 497 bool stack) 501 498 { 499 + xe_pm_runtime_get_noresume(gt_to_xe(gt)); 500 + 502 501 spin_lock_irq(&gt->tlb_invalidation.lock); 503 502 dma_fence_init(&fence->base, &invalidation_fence_ops, 504 503 &gt->tlb_invalidation.lock, ··· 512 505 set_bit(FENCE_STACK_BIT, &fence->base.flags); 513 506 else 514 507 dma_fence_get(&fence->base); 508 + fence->gt = gt; 509 + } 510 + 511 + /** 512 + * xe_gt_tlb_invalidation_fence_fini - Finalize TLB invalidation fence 513 + * @fence: TLB invalidation fence to finalize 514 + * 515 + * Drop PM ref which fence took durinig init. 516 + */ 517 + void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence) 518 + { 519 + xe_pm_runtime_put(gt_to_xe(fence->gt)); 515 520 }
+1
drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h
··· 28 28 void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, 29 29 struct xe_gt_tlb_invalidation_fence *fence, 30 30 bool stack); 31 + void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence); 31 32 32 33 static inline void 33 34 xe_gt_tlb_invalidation_fence_wait(struct xe_gt_tlb_invalidation_fence *fence)
+4
drivers/gpu/drm/xe/xe_gt_tlb_invalidation_types.h
··· 8 8 9 9 #include <linux/dma-fence.h> 10 10 11 + struct xe_gt; 12 + 11 13 /** 12 14 * struct xe_gt_tlb_invalidation_fence - XE GT TLB invalidation fence 13 15 * ··· 19 17 struct xe_gt_tlb_invalidation_fence { 20 18 /** @base: dma fence base */ 21 19 struct dma_fence base; 20 + /** @gt: GT which fence belong to */ 21 + struct xe_gt *gt; 22 22 /** @link: link into list of pending tlb fences */ 23 23 struct list_head link; 24 24 /** @seqno: seqno of TLB invalidation to signal fence one */
+3 -1
drivers/gpu/drm/xe/xe_vm.c
··· 3379 3379 */ 3380 3380 ret = xe_gt_tlb_invalidation_vma(tile->primary_gt, 3381 3381 &fence[id], vma); 3382 - if (ret < 0) 3382 + if (ret < 0) { 3383 + xe_gt_tlb_invalidation_fence_fini(&fence[id]); 3383 3384 goto wait; 3385 + } 3384 3386 3385 3387 tile_needs_invalidate |= BIT(id); 3386 3388 }