Skip to content

Commit 94de94d

Browse files
committed
drm/xe/guc: Cancel ongoing H2G requests when stopping CT
Once we have started a GT reset sequence, which includes stopping GuC CTB communication, we should also cancel all ongoing H2G send- recv requests, as either GuC is already dead, or due to imminent reset GuC will not be able to reply, or due to internal cleanup we will lose pending fences. With this we will report dedicated -ECANCELED error instead of misleading -ETIME. Signed-off-by: Michal Wajdeczko <[email protected]> Cc: Matthew Brost <[email protected]> Reviewed-by: Jonathan Cavitt <[email protected]> Acked-by: Matthew Brost <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 4ecdcf9 commit 94de94d

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

drivers/gpu/drm/xe/xe_guc_ct.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct g2h_fence {
8585
u16 error;
8686
u16 hint;
8787
u16 reason;
88+
bool cancel;
8889
bool retry;
8990
bool fail;
9091
bool done;
@@ -103,6 +104,13 @@ static void g2h_fence_init(struct g2h_fence *g2h_fence, u32 *response_buffer)
103104
g2h_fence->seqno = ~0x0;
104105
}
105106

107+
static void g2h_fence_cancel(struct g2h_fence *g2h_fence)
108+
{
109+
g2h_fence->cancel = true;
110+
g2h_fence->fail = true;
111+
g2h_fence->done = true;
112+
}
113+
106114
static bool g2h_fence_needs_alloc(struct g2h_fence *g2h_fence)
107115
{
108116
return g2h_fence->seqno == ~0x0;
@@ -388,6 +396,8 @@ static void guc_ct_change_state(struct xe_guc_ct *ct,
388396
enum xe_guc_ct_state state)
389397
{
390398
struct xe_gt *gt = ct_to_gt(ct);
399+
struct g2h_fence *g2h_fence;
400+
unsigned long idx;
391401

392402
mutex_lock(&ct->lock); /* Serialise dequeue_one_g2h() */
393403
spin_lock_irq(&ct->fast_lock); /* Serialise CT fast-path */
@@ -406,6 +416,14 @@ static void guc_ct_change_state(struct xe_guc_ct *ct,
406416

407417
spin_unlock_irq(&ct->fast_lock);
408418

419+
/* cancel all in-flight send-recv requests */
420+
xa_for_each(&ct->fence_lookup, idx, g2h_fence)
421+
g2h_fence_cancel(g2h_fence);
422+
423+
/* make sure guc_ct_send_recv() will see g2h_fence changes */
424+
smp_mb();
425+
wake_up_all(&ct->g2h_fence_wq);
426+
409427
/*
410428
* Lockdep doesn't like this under the fast lock and he destroy only
411429
* needs to be serialized with the send path which ct lock provides.
@@ -1098,6 +1116,11 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len,
10981116
goto retry;
10991117
}
11001118
if (g2h_fence.fail) {
1119+
if (g2h_fence.cancel) {
1120+
xe_gt_dbg(gt, "H2G request %#x canceled!\n", action[0]);
1121+
ret = -ECANCELED;
1122+
goto unlock;
1123+
}
11011124
xe_gt_err(gt, "H2G request %#x failed: error %#x hint %#x\n",
11021125
action[0], g2h_fence.error, g2h_fence.hint);
11031126
ret = -EIO;
@@ -1106,6 +1129,7 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len,
11061129
if (ret > 0)
11071130
ret = response_buffer ? g2h_fence.response_len : g2h_fence.response_data;
11081131

1132+
unlock:
11091133
mutex_unlock(&ct->lock);
11101134

11111135
return ret;

0 commit comments

Comments
 (0)