@@ -822,7 +822,7 @@ static void submit_exec_queue(struct xe_exec_queue *q, struct xe_sched_job *job)
822822
823823 xe_gt_assert (guc_to_gt (guc ), exec_queue_registered (q ));
824824
825- if (!job -> skip_emit || job -> last_replay ) {
825+ if (!job -> restore_replay || job -> last_replay ) {
826826 if (xe_exec_queue_is_parallel (q ))
827827 wq_item_append (q );
828828 else
@@ -881,10 +881,10 @@ guc_exec_queue_run_job(struct drm_sched_job *drm_job)
881881 if (!killed_or_banned_or_wedged && !xe_sched_job_is_error (job )) {
882882 if (!exec_queue_registered (q ))
883883 register_exec_queue (q , GUC_CONTEXT_NORMAL );
884- if (!job -> skip_emit )
884+ if (!job -> restore_replay )
885885 q -> ring_ops -> emit_job (job );
886886 submit_exec_queue (q , job );
887- job -> skip_emit = false;
887+ job -> restore_replay = false;
888888 }
889889
890890 /*
@@ -2112,6 +2112,18 @@ static void guc_exec_queue_revert_pending_state_change(struct xe_guc *guc,
21122112 q -> guc -> resume_time = 0 ;
21132113}
21142114
2115+ static void lrc_parallel_clear (struct xe_lrc * lrc )
2116+ {
2117+ struct xe_device * xe = gt_to_xe (lrc -> gt );
2118+ struct iosys_map map = xe_lrc_parallel_map (lrc );
2119+ int i ;
2120+
2121+ for (i = 0 ; i < WQ_SIZE / sizeof (u32 ); ++ i )
2122+ parallel_write (xe , map , wq [i ],
2123+ FIELD_PREP (WQ_TYPE_MASK , WQ_TYPE_NOOP ) |
2124+ FIELD_PREP (WQ_LEN_MASK , 0 ));
2125+ }
2126+
21152127/*
21162128 * This function is quite complex but only real way to ensure no state is lost
21172129 * during VF resume flows. The function scans the queue state, make adjustments
@@ -2135,23 +2147,23 @@ static void guc_exec_queue_pause(struct xe_guc *guc, struct xe_exec_queue *q)
21352147 guc_exec_queue_revert_pending_state_change (guc , q );
21362148
21372149 if (xe_exec_queue_is_parallel (q )) {
2138- struct xe_device * xe = guc_to_xe ( guc );
2139- struct iosys_map map = xe_lrc_parallel_map (q -> lrc [0 ]);
2150+ /* Pairs with WRITE_ONCE in __xe_exec_queue_init */
2151+ struct xe_lrc * lrc = READ_ONCE (q -> lrc [0 ]);
21402152
21412153 /*
21422154 * NOP existing WQ commands that may contain stale GGTT
21432155 * addresses. These will be replayed upon unpause. The hardware
21442156 * seems to get confused if the WQ head/tail pointers are
21452157 * adjusted.
21462158 */
2147- for (i = 0 ; i < WQ_SIZE / sizeof (u32 ); ++ i )
2148- parallel_write (xe , map , wq [i ],
2149- FIELD_PREP (WQ_TYPE_MASK , WQ_TYPE_NOOP ) |
2150- FIELD_PREP (WQ_LEN_MASK , 0 ));
2159+ if (lrc )
2160+ lrc_parallel_clear (lrc );
21512161 }
21522162
21532163 job = xe_sched_first_pending_job (sched );
21542164 if (job ) {
2165+ job -> restore_replay = true;
2166+
21552167 /*
21562168 * Adjust software tail so jobs submitted overwrite previous
21572169 * position in ring buffer with new GGTT addresses.
@@ -2241,17 +2253,18 @@ static void guc_exec_queue_unpause_prepare(struct xe_guc *guc,
22412253 struct xe_exec_queue * q )
22422254{
22432255 struct xe_gpu_scheduler * sched = & q -> guc -> sched ;
2244- struct drm_sched_job * s_job ;
22452256 struct xe_sched_job * job = NULL ;
2257+ bool restore_replay = false;
22462258
2247- list_for_each_entry (s_job , & sched -> base .pending_list , list ) {
2248- job = to_xe_sched_job ( s_job ) ;
2249-
2250- xe_gt_dbg (guc_to_gt (guc ), "Replay JOB - guc_id=%d, seqno=%d" ,
2251- q -> guc -> id , xe_sched_job_seqno (job ));
2259+ list_for_each_entry (job , & sched -> base .pending_list , drm . list ) {
2260+ restore_replay |= job -> restore_replay ;
2261+ if ( restore_replay ) {
2262+ xe_gt_dbg (guc_to_gt (guc ), "Replay JOB - guc_id=%d, seqno=%d" ,
2263+ q -> guc -> id , xe_sched_job_seqno (job ));
22522264
2253- q -> ring_ops -> emit_job (job );
2254- job -> skip_emit = true;
2265+ q -> ring_ops -> emit_job (job );
2266+ job -> restore_replay = true;
2267+ }
22552268 }
22562269
22572270 if (job )
0 commit comments