@@ -71,7 +71,6 @@ exec_queue_to_guc(struct xe_exec_queue *q)
7171#define EXEC_QUEUE_STATE_WEDGED (1 << 8)
7272#define EXEC_QUEUE_STATE_BANNED (1 << 9)
7373#define EXEC_QUEUE_STATE_PENDING_RESUME (1 << 10)
74- #define EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND (1 << 11)
7574
7675static bool exec_queue_registered (struct xe_exec_queue * q )
7776{
@@ -158,6 +157,11 @@ static void set_exec_queue_banned(struct xe_exec_queue *q)
158157 atomic_or (EXEC_QUEUE_STATE_BANNED , & q -> guc -> state );
159158}
160159
160+ static void clear_exec_queue_banned (struct xe_exec_queue * q )
161+ {
162+ atomic_andnot (EXEC_QUEUE_STATE_BANNED , & q -> guc -> state );
163+ }
164+
161165static bool exec_queue_suspended (struct xe_exec_queue * q )
162166{
163167 return atomic_read (& q -> guc -> state ) & EXEC_QUEUE_STATE_SUSPENDED ;
@@ -218,21 +222,6 @@ static void clear_exec_queue_pending_resume(struct xe_exec_queue *q)
218222 atomic_and (~EXEC_QUEUE_STATE_PENDING_RESUME , & q -> guc -> state );
219223}
220224
221- static bool exec_queue_idle_skip_suspend (struct xe_exec_queue * q )
222- {
223- return atomic_read (& q -> guc -> state ) & EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND ;
224- }
225-
226- static void set_exec_queue_idle_skip_suspend (struct xe_exec_queue * q )
227- {
228- atomic_or (EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND , & q -> guc -> state );
229- }
230-
231- static void clear_exec_queue_idle_skip_suspend (struct xe_exec_queue * q )
232- {
233- atomic_and (~EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND , & q -> guc -> state );
234- }
235-
236225static bool exec_queue_killed_or_banned_or_wedged (struct xe_exec_queue * q )
237226{
238227 return (atomic_read (& q -> guc -> state ) &
@@ -1157,7 +1146,7 @@ static void submit_exec_queue(struct xe_exec_queue *q, struct xe_sched_job *job)
11571146 if (!job -> restore_replay || job -> last_replay ) {
11581147 if (xe_exec_queue_is_parallel (q ))
11591148 wq_item_append (q );
1160- else if (! exec_queue_idle_skip_suspend ( q ))
1149+ else
11611150 xe_lrc_set_ring_tail (lrc , lrc -> ring .tail );
11621151 job -> last_replay = false;
11631152 }
@@ -1167,9 +1156,12 @@ static void submit_exec_queue(struct xe_exec_queue *q, struct xe_sched_job *job)
11671156
11681157 /*
11691158 * All queues in a multi-queue group will use the primary queue
1170- * of the group to interface with GuC.
1159+ * of the group to interface with GuC. If primay is suspended,
1160+ * just return. Jobs will get scheduled once primary is resumed.
11711161 */
11721162 q = xe_exec_queue_multi_queue_primary (q );
1163+ if (exec_queue_suspended (q ))
1164+ return ;
11731165
11741166 if (!exec_queue_enabled (q ) && !exec_queue_suspended (q )) {
11751167 action [len ++ ] = XE_GUC_ACTION_SCHED_CONTEXT_MODE_SET ;
@@ -1376,7 +1368,8 @@ static bool check_timeout(struct xe_exec_queue *q, struct xe_sched_job *job)
13761368 xe_sched_job_seqno (job ), xe_sched_job_lrc_seqno (job ),
13771369 q -> guc -> id );
13781370
1379- return xe_sched_invalidate_job (job , 2 );
1371+ /* GuC never scheduled this job - let the caller trigger a GT reset. */
1372+ return true;
13801373 }
13811374
13821375 ctx_timestamp = lower_32_bits (xe_lrc_timestamp (q -> lrc [0 ]));
@@ -1473,6 +1466,21 @@ static void disable_scheduling(struct xe_exec_queue *q, bool immediate)
14731466 G2H_LEN_DW_SCHED_CONTEXT_MODE_SET , 1 );
14741467}
14751468
1469+ /*
1470+ * Recover via GT reset for a kernel queue, or for a GuC scheduling failure (job
1471+ * never started) on a queue that was not already killed or banned. An already
1472+ * banned queue must stay banned, so its unstarted jobs do not clear the ban or
1473+ * trigger a reset.
1474+ */
1475+ static bool timeout_needs_gt_reset (struct xe_exec_queue * q , struct xe_sched_job * job ,
1476+ bool skip_timeout_check )
1477+ {
1478+ if (q -> flags & EXEC_QUEUE_FLAG_KERNEL )
1479+ return true;
1480+
1481+ return !skip_timeout_check && !xe_sched_job_started (job );
1482+ }
1483+
14761484static enum drm_gpu_sched_stat
14771485guc_exec_queue_timedout_job (struct drm_sched_job * drm_job )
14781486{
@@ -1621,19 +1629,19 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
16211629 xe_sched_job_seqno (job ), xe_sched_job_lrc_seqno (job ),
16221630 q -> guc -> id , q -> flags );
16231631
1624- /*
1625- * Kernel jobs should never fail, nor should VM jobs if they do
1626- * somethings has gone wrong and the GT needs a reset
1627- */
1628- xe_gt_WARN (q -> gt , q -> flags & EXEC_QUEUE_FLAG_KERNEL ,
1629- "Kernel-submitted job timed out\n" ) ;
1630- xe_gt_WARN ( q -> gt , q -> flags & EXEC_QUEUE_FLAG_VM && ! exec_queue_killed ( q ),
1631- "VM job timed out on non-killed execqueue\n" );
1632- if (! wedged && ( q -> flags & EXEC_QUEUE_FLAG_KERNEL ||
1633- ( q -> flags & EXEC_QUEUE_FLAG_VM && ! exec_queue_killed ( q )))) {
1634- if (! xe_sched_invalidate_job ( job , 2 )) {
1635- xe_gt_reset_async (q -> gt );
1636- goto rearm ;
1632+ if (! wedged ) {
1633+ if ( timeout_needs_gt_reset ( q , job , skip_timeout_check )) {
1634+ if (! xe_sched_invalidate_job ( job , 2 )) {
1635+ clear_exec_queue_banned ( q );
1636+ xe_gt_reset_async (q -> gt );
1637+ goto rearm ;
1638+ }
1639+ if ( q -> flags & EXEC_QUEUE_FLAG_KERNEL ) {
1640+ xe_gt_WARN ( q -> gt , true, "Kernel-submitted job timed out\n" );
1641+ xe_device_declare_wedged ( gt_to_xe ( q -> gt ));
1642+ }
1643+ } else if (q -> flags & EXEC_QUEUE_FLAG_VM && ! exec_queue_killed ( q )) {
1644+ xe_gt_WARN ( q -> gt , true, "VM job timed out on non-killed execqueue\n" ) ;
16371645 }
16381646 }
16391647
@@ -1812,10 +1820,9 @@ static void __guc_exec_queue_process_msg_suspend(struct xe_sched_msg *msg)
18121820{
18131821 struct xe_exec_queue * q = msg -> private_data ;
18141822 struct xe_guc * guc = exec_queue_to_guc (q );
1815- bool idle_skip_suspend = xe_exec_queue_idle_skip_suspend (q );
18161823
1817- if (! idle_skip_suspend && guc_exec_queue_allowed_to_change_state (q ) &&
1818- ! exec_queue_suspended ( q ) && exec_queue_enabled (q )) {
1824+ if (guc_exec_queue_allowed_to_change_state ( q ) && ! exec_queue_suspended (q ) &&
1825+ exec_queue_enabled (q )) {
18191826 wait_event (guc -> ct .wq , vf_recovery (guc ) ||
18201827 ((q -> guc -> resume_time != RESUME_PENDING ||
18211828 xe_guc_read_stopped (guc )) && !exec_queue_pending_disable (q )));
@@ -1834,56 +1841,24 @@ static void __guc_exec_queue_process_msg_suspend(struct xe_sched_msg *msg)
18341841 disable_scheduling (q , false);
18351842 }
18361843 } else if (q -> guc -> suspend_pending ) {
1837- if (idle_skip_suspend )
1838- set_exec_queue_idle_skip_suspend (q );
18391844 set_exec_queue_suspended (q );
18401845 suspend_fence_signal (q );
18411846 }
18421847}
18431848
1844- static void sched_context (struct xe_exec_queue * q )
1845- {
1846- struct xe_guc * guc = exec_queue_to_guc (q );
1847- struct xe_lrc * lrc = q -> lrc [0 ];
1848- u32 action [] = {
1849- XE_GUC_ACTION_SCHED_CONTEXT ,
1850- q -> guc -> id ,
1851- };
1852-
1853- xe_gt_assert (guc_to_gt (guc ), !xe_exec_queue_is_parallel (q ));
1854- xe_gt_assert (guc_to_gt (guc ), !exec_queue_destroyed (q ));
1855- xe_gt_assert (guc_to_gt (guc ), exec_queue_registered (q ));
1856- xe_gt_assert (guc_to_gt (guc ), !exec_queue_pending_disable (q ));
1857-
1858- trace_xe_exec_queue_submit (q );
1859-
1860- xe_lrc_set_ring_tail (lrc , lrc -> ring .tail );
1861- xe_guc_ct_send (& guc -> ct , action , ARRAY_SIZE (action ), 0 , 0 );
1862- }
1863-
18641849static void __guc_exec_queue_process_msg_resume (struct xe_sched_msg * msg )
18651850{
18661851 struct xe_exec_queue * q = msg -> private_data ;
18671852
18681853 if (guc_exec_queue_allowed_to_change_state (q )) {
18691854 clear_exec_queue_suspended (q );
18701855 if (!exec_queue_enabled (q )) {
1871- if (exec_queue_idle_skip_suspend (q )) {
1872- struct xe_lrc * lrc = q -> lrc [0 ];
1873-
1874- clear_exec_queue_idle_skip_suspend (q );
1875- xe_lrc_set_ring_tail (lrc , lrc -> ring .tail );
1876- }
18771856 q -> guc -> resume_time = RESUME_PENDING ;
18781857 set_exec_queue_pending_resume (q );
18791858 enable_scheduling (q );
1880- } else if (exec_queue_idle_skip_suspend (q )) {
1881- clear_exec_queue_idle_skip_suspend (q );
1882- sched_context (q );
18831859 }
18841860 } else {
18851861 clear_exec_queue_suspended (q );
1886- clear_exec_queue_idle_skip_suspend (q );
18871862 }
18881863}
18891864
@@ -2840,8 +2815,8 @@ static void handle_sched_done(struct xe_guc *guc, struct xe_exec_queue *q,
28402815 xe_gt_assert (guc_to_gt (guc ), exec_queue_pending_disable (q ));
28412816
28422817 if (q -> guc -> suspend_pending ) {
2843- suspend_fence_signal (q );
28442818 clear_exec_queue_pending_disable (q );
2819+ suspend_fence_signal (q );
28452820 } else {
28462821 if (exec_queue_banned (q )) {
28472822 smp_wmb ();
0 commit comments