1010#include <linux/circ_buf.h>
1111#include <linux/dma-fence-array.h>
1212
13+ #include <drm/drm_drv.h>
1314#include <drm/drm_managed.h>
1415
1516#include "abi/guc_actions_abi.h"
3738#include "xe_macros.h"
3839#include "xe_map.h"
3940#include "xe_mocs.h"
41+ #include "xe_module.h"
4042#include "xe_pm.h"
4143#include "xe_ring_ops_types.h"
4244#include "xe_sched_job.h"
@@ -232,17 +234,9 @@ static bool exec_queue_killed_or_banned_or_wedged(struct xe_exec_queue *q)
232234static void guc_submit_sw_fini (struct drm_device * drm , void * arg )
233235{
234236 struct xe_guc * guc = arg ;
235- struct xe_device * xe = guc_to_xe (guc );
236237 struct xe_gt * gt = guc_to_gt (guc );
237- int ret ;
238-
239- ret = wait_event_timeout (guc -> submission_state .fini_wq ,
240- xa_empty (& guc -> submission_state .exec_queue_lookup ),
241- HZ * 5 );
242238
243- drain_workqueue (xe -> destroy_wq );
244-
245- xe_gt_assert (gt , ret );
239+ xe_gt_assert (gt , xa_empty (& guc -> submission_state .exec_queue_lookup ));
246240
247241 xa_destroy (& guc -> submission_state .exec_queue_lookup );
248242}
@@ -319,8 +313,6 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids)
319313
320314 xa_init (& guc -> submission_state .exec_queue_lookup );
321315
322- init_waitqueue_head (& guc -> submission_state .fini_wq );
323-
324316 primelockdep (guc );
325317
326318 guc -> submission_state .initialized = true;
@@ -411,9 +403,6 @@ static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q,
411403 xe_guc_id_mgr_release_locked (& guc -> submission_state .idm ,
412404 q -> guc -> id , q -> width );
413405
414- if (xa_empty (& guc -> submission_state .exec_queue_lookup ))
415- wake_up (& guc -> submission_state .fini_wq );
416-
417406 mutex_unlock (& guc -> submission_state .lock );
418407}
419408
@@ -1685,6 +1674,7 @@ static void guc_exec_queue_fini(struct xe_exec_queue *q)
16851674{
16861675 struct xe_guc_exec_queue * ge = q -> guc ;
16871676 struct xe_guc * guc = exec_queue_to_guc (q );
1677+ struct drm_device * drm = & guc_to_xe (guc )-> drm ;
16881678
16891679 if (xe_exec_queue_is_multi_queue_secondary (q )) {
16901680 struct xe_exec_queue_group * group = q -> multi_queue .group ;
@@ -1703,36 +1693,52 @@ static void guc_exec_queue_fini(struct xe_exec_queue *q)
17031693 * (timeline name).
17041694 */
17051695 kfree_rcu (ge , rcu );
1696+
1697+ drm_dev_put (drm );
17061698}
17071699
1708- static void __guc_exec_queue_destroy_async (struct work_struct * w )
1700+ static void guc_exec_queue_do_destroy (struct xe_exec_queue * q )
17091701{
1710- struct xe_guc_exec_queue * ge =
1711- container_of (w , struct xe_guc_exec_queue , destroy_async );
1712- struct xe_exec_queue * q = ge -> q ;
1702+ struct xe_guc_exec_queue * ge = q -> guc ;
17131703 struct xe_guc * guc = exec_queue_to_guc (q );
1704+ struct xe_device * xe = guc_to_xe (guc );
1705+ struct drm_device * drm = & xe -> drm ;
1706+
1707+ /*
1708+ * guc_exec_queue_fini() drops the queue's drm_device ref.
1709+ * Keep the device alive until the PM-runtime guard unwinds.
1710+ */
1711+ drm_dev_get (drm );
1712+
1713+ scoped_guard (xe_pm_runtime , xe ) {
1714+ trace_xe_exec_queue_destroy (q );
17141715
1715- guard ( xe_pm_runtime )( guc_to_xe ( guc ));
1716- trace_xe_exec_queue_destroy ( q );
1716+ /* Confirm no work left behind accessing device structures */
1717+ cancel_delayed_work_sync ( & ge -> sched . base . work_tdr );
17171718
1718- /* Confirm no work left behind accessing device structures */
1719- cancel_delayed_work_sync ( & ge -> sched . base . work_tdr );
1719+ xe_exec_queue_fini ( q );
1720+ }
17201721
1721- xe_exec_queue_fini ( q );
1722+ drm_dev_put ( drm );
17221723}
17231724
1724- static void guc_exec_queue_destroy_async (struct xe_exec_queue * q )
1725+ static void __guc_exec_queue_destroy_async (struct work_struct * w )
17251726{
1726- struct xe_guc * guc = exec_queue_to_guc (q );
1727- struct xe_device * xe = guc_to_xe (guc );
1727+ struct xe_guc_exec_queue * ge =
1728+ container_of (w , struct xe_guc_exec_queue , destroy_async );
1729+
1730+ guc_exec_queue_do_destroy (ge -> q );
1731+ }
17281732
1733+ static void guc_exec_queue_destroy_async (struct xe_exec_queue * q )
1734+ {
17291735 INIT_WORK (& q -> guc -> destroy_async , __guc_exec_queue_destroy_async );
17301736
17311737 /* We must block on kernel engines so slabs are empty on driver unload */
17321738 if (q -> flags & EXEC_QUEUE_FLAG_PERMANENT || exec_queue_wedged (q ))
1733- __guc_exec_queue_destroy_async ( & q -> guc -> destroy_async );
1739+ guc_exec_queue_do_destroy ( q );
17341740 else
1735- queue_work ( xe -> destroy_wq , & q -> guc -> destroy_async );
1741+ xe_destroy_wq_queue ( & q -> guc -> destroy_async );
17361742}
17371743
17381744static void __guc_exec_queue_destroy (struct xe_guc * guc , struct xe_exec_queue * q )
@@ -1927,6 +1933,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
19271933{
19281934 struct xe_gpu_scheduler * sched ;
19291935 struct xe_guc * guc = exec_queue_to_guc (q );
1936+ struct drm_device * drm = & guc_to_xe (guc )-> drm ;
19301937 struct workqueue_struct * submit_wq = NULL ;
19311938 struct xe_guc_exec_queue * ge ;
19321939 long timeout ;
@@ -1938,6 +1945,8 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
19381945 if (!ge )
19391946 return - ENOMEM ;
19401947
1948+ drm_dev_get (drm );
1949+
19411950 q -> guc = ge ;
19421951 ge -> q = q ;
19431952 init_rcu_head (& ge -> rcu );
@@ -1955,6 +1964,8 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
19551964
19561965 xe_exec_queue_assign_name (q , q -> guc -> id );
19571966
1967+ strscpy (ge -> name , q -> name , sizeof (ge -> name ));
1968+
19581969 /*
19591970 * Use primary queue's submit_wq for all secondary queues of a
19601971 * multi queue group. This serialization avoids any locking around
@@ -1969,7 +1980,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
19691980 err = xe_sched_init (& ge -> sched , & drm_sched_ops , & xe_sched_ops ,
19701981 submit_wq , xe_lrc_ring_size () / MAX_JOB_SIZE_BYTES , 64 ,
19711982 timeout , guc_to_gt (guc )-> ordered_wq , NULL ,
1972- q -> name , gt_to_xe (q -> gt )-> drm .dev );
1983+ ge -> name , gt_to_xe (q -> gt )-> drm .dev );
19731984 if (err )
19741985 goto err_release_id ;
19751986
@@ -2014,6 +2025,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
20142025 release_guc_id (guc , q );
20152026err_free :
20162027 kfree (ge );
2028+ drm_dev_put (drm );
20172029
20182030 return err ;
20192031}
0 commit comments