[PATCH v4 3/3] drm/xe/guc/tlb: Flush g2h worker in case of tlb timeout

Matthew Auld matthew.auld at intel.com
Tue Oct 29 10:59:08 UTC 2024


On 29/10/2024 09:54, Nirmoy Das wrote:
> Flush the g2h worker explicitly if TLB timeout happens which is
> observed on LNL and that points to the recent scheduling issue with
> E-cores on LNL.
> 
> This is similar to the recent fix:
> commit e51527233804 ("drm/xe/guc/ct: Flush g2h worker in case of g2h
> response timeout") and should be removed once there is E core
> scheduling fix.
> 
> v2: Add platform check(Himal)
> v3: Remove gfx platform check as the issue related to cpu
>      platform(John)
>      Use the common WA macro(John) and print when the flush
>      resolves timeout(Matt B)
> 
> Cc: Badal Nilawar <badal.nilawar at intel.com>
> Cc: Matthew Brost <matthew.brost at intel.com>
> Cc: Matthew Auld <matthew.auld at intel.com>
> Cc: John Harrison <John.C.Harrison at Intel.com>
> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray at intel.com>
> Cc: Lucas De Marchi <lucas.demarchi at intel.com>
> Cc: <stable at vger.kernel.org> # v6.11+
> Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2687
> Signed-off-by: Nirmoy Das <nirmoy.das at intel.com>
> ---
>   drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
> index 773de1f08db9..0bdb3ba5220a 100644
> --- a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
> +++ b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
> @@ -81,6 +81,15 @@ static void xe_gt_tlb_fence_timeout(struct work_struct *work)
>   		if (msecs_to_jiffies(since_inval_ms) < tlb_timeout_jiffies(gt))
>   			break;
>   
> +		LNL_FLUSH_WORK(&gt->uc.guc.ct.g2h_worker);

I think here we are holding the pending lock, and g2h worker also wants 
to grab that same lock so this smells like potential deadlock. Also 
flush_work can sleep so I don't think is allowed under spinlock.

> +		since_inval_ms = ktime_ms_delta(ktime_get(),
> +						fence->invalidation_time);

I think invalidation_time is rather when we sent off the invalidation 
req, and we already check that above so if we get here then we know the 
timeout has expired for this fence, so checking again after the flush 
doesn't really help AFAICT.

I think we can just move the flush to before the loop and outside the 
lock, and then if the fence(s) gets signalled they will be removed from 
the list and then also won't be considered for timeout?

> +		if (msecs_to_jiffies(since_inval_ms) < tlb_timeout_jiffies(gt)) {
> +			xe_gt_dbg(gt, "LNL_FLUSH_WORK resolved TLB invalidation fence timeout, seqno=%d recv=%d",
> +				  fence->seqno, gt->tlb_invalidation.seqno_recv);
> +			break;
> +		}
> +
>   		trace_xe_gt_tlb_invalidation_fence_timeout(xe, fence);
>   		xe_gt_err(gt, "TLB invalidation fence timeout, seqno=%d recv=%d",
>   			  fence->seqno, gt->tlb_invalidation.seqno_recv);


More information about the Intel-xe mailing list