A GT reset can stop a context after the LRC head has advanced past the
start of the oldest pending job.

The replay path rewinds the software ring tail to the job's recorded
start so the pending jobs are written again. However, it leaves the LRC
head at its saved later position and initializes the LRC tail from that
position.

The hardware and software ring positions can therefore use different
replay starting points.

Before resubmitting the queue, set the software tail and both LRC ring
pointers to the start of the oldest pending job. Update the pointers
while the context is unregistered, before resubmitting pending jobs.

Cc: Matthew Brost <[email protected]>
Cc: Thomas Hellström <[email protected]>
Cc: Himal Prasad Ghimiray <[email protected]>
Cc: Rodrigo Vivi <[email protected]>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Arvind Yadav <[email protected]>
---
 drivers/gpu/drm/xe/xe_guc_submit.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c 
b/drivers/gpu/drm/xe/xe_guc_submit.c
index ca24a77dfb26..878ba94d22e0 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -2984,17 +2984,17 @@ static void guc_exec_queue_start(struct xe_exec_queue 
*q)
                trace_xe_exec_queue_resubmit(q);
                if (job) {
                        for (i = 0; i < q->width; ++i) {
+                               u32 replay_head = job->ptrs[i].head;
+
                                /*
-                                * The GuC context is unregistered at this point
-                                * time, adjusting software ring tail ensures
-                                * jobs are rewritten in original placement,
-                                * adjusting LRC tail ensures the newly loaded
-                                * GuC / contexts only view the LRC tail
-                                * increasing as jobs are written out.
+                                * A started job may have advanced the saved LRC
+                                * head past its original ring position. Rewind
+                                * both head and tail before rewriting and
+                                * replaying the pending jobs.
                                 */
-                               q->lrc[i]->ring.tail = job->ptrs[i].head;
-                               xe_lrc_set_ring_tail(q->lrc[i],
-                                                    
xe_lrc_ring_head(q->lrc[i]));
+                               q->lrc[i]->ring.tail = replay_head;
+                               xe_lrc_set_ring_head(q->lrc[i], replay_head);
+                               xe_lrc_set_ring_tail(q->lrc[i], replay_head);
                        }
                }
                xe_sched_resubmit_jobs(sched);
-- 
2.43.0

Reply via email to