[PATCH] drm/xe/guc: Silently discard stale G2H reply during overlap

Nishit Sharma <[email protected]>
Newsgroups org.freedesktop.lists.intel-xe
Message-ID <[email protected]>
When xe_force_gt_reset_async() fires a second reset before the first
reset's post-recovery drain has completed, GuC may still be processing
H2G requests (SCHED_CONTEXT_MODE_SET / DEREGISTER_CONTEXT) that were
issued by the first reset. The G2H replies SCHED_DONE and DEREGISTER_DONE
can then arrive after the KMD has already marked those exec queues as
banned, killed, or wedged in response to the second reset.
At that point the state flags that the reply handlers assert on
have already been cleared, and the handlers treat this as a protocol
violation, emitting an *ERROR* and returning -EPROTO.

This is not a real error. The reset path tears down exec queues
independently of any in-flight G2H traffic, so a stale reply for a dead
queue is harmless. The proper response is to discard it silently and let
the reset-driven teardown proceed undisturbed.

Detect this condition by checking whether the queue is already in a
terminal state (banned, killed, or wedged) before treating an unexpected
G2H as a protocol error. If so, log at debug level and return success.

Signed-off-by: Nishit Sharma <[email protected]>
---
 drivers/gpu/drm/xe/xe_guc_submit.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
index 8aaed4fd13ea..988c236c6a03 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -3149,6 +3149,19 @@ int xe_guc_sched_done_handler(struct xe_guc *guc, u32 *msg, u32 len)
 
 	if (unlikely(!exec_queue_pending_enable(q) &&
 		     !exec_queue_pending_disable(q))) {
+		/*
+		 * Stale SCHED_DONE from a prior reset cycle: the reset marked
+		 * the queue banned/killed (clearing the pending flags) before
+		 * GuC's reply landed. Discard silently
+		 */
+		if (exec_queue_banned(q) || exec_queue_killed(q) ||
+		    exec_queue_wedged(q)) {
+			xe_gt_dbg(guc_to_gt(guc),
+				  "SCHED_DONE: Stale G2H guc_id=%d, state=0x%04x\n",
+				  q->guc->id, atomic_read(&q->guc->state));
+			return 0;
+		}
+
 		xe_gt_err(guc_to_gt(guc),
 			  "SCHED_DONE: Unexpected engine state 0x%04x, guc_id=%d, runnable_state=%u",
 			  atomic_read(&q->guc->state), q->guc->id,
@@ -3185,6 +3198,18 @@ int xe_guc_deregister_done_handler(struct xe_guc *guc, u32 *msg, u32 len)
 
 	if (!exec_queue_destroyed(q) || exec_queue_pending_disable(q) ||
 	    exec_queue_pending_enable(q) || exec_queue_enabled(q)) {
+		 /*
+		  * DEREGISTER_DONE from a prior reset cycle
+		  * Discard silently
+		  */
+		if (exec_queue_banned(q) || exec_queue_killed(q) ||
+		    exec_queue_wedged(q)) {
+			xe_gt_dbg(guc_to_gt(guc),
+				  "DEREGISTER_DONE: Stale G2H guc_id=%d, state=0x%04x\n",
+				  q->guc->id, atomic_read(&q->guc->state));
+			return 0;
+		}
+
 		xe_gt_err(guc_to_gt(guc),
 			  "DEREGISTER_DONE: Unexpected engine state 0x%04x, guc_id=%d",
 			  atomic_read(&q->guc->state), q->guc->id);
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.