All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stuart Summers <stuart.summers@intel.com>
Cc: michal.wajdeczko@intel.com, ilia.levi@intel.com,
	x.wang@intel.com, rodrigo.vivi@intel.com,
	intel-xe@lists.freedesktop.org,
	alan.previn.teres.alexis@intel.com,
	Stuart Summers <stuart.summers@intel.com>
Subject: [PATCH 08/12] drm/xe: Add per-exec-queue user fence wait queue
Date: Fri,  5 Jun 2026 23:21:15 +0000	[thread overview]
Message-ID: <20260605232108.674580-22-stuart.summers@intel.com> (raw)
In-Reply-To: <20260605232108.674580-14-stuart.summers@intel.com>

Add a new ufence_wq wait queue to struct xe_exec_queue and initialize it
at queue allocation time. Also introduce xe_wait_user_fence_wake() to
centralize the ufence wake call sites.

This patch just adds the infrastructure in place to do this and doesn't
actually start using it. The reason being that we need to be careful
when handling a case where a user does a VM bind without a bind queue
and mistakenly passes a non-bind queue to the wait user fence. There
are a couple of IGT cases at least that are doing this today and to
avoid regressing any user code around this, we'll add some additional
handling in a subsequent patch before connecting this to the actual
wait user fence code.

Signed-off-by: Stuart Summers <stuart.summers@intel.com>
Assisted-by: Copilot:claude-sonnet-4.6
---
 drivers/gpu/drm/xe/xe_exec_queue.c       |  1 +
 drivers/gpu/drm/xe/xe_exec_queue_types.h |  3 +++
 drivers/gpu/drm/xe/xe_guc_submit.c       |  6 ++----
 drivers/gpu/drm/xe/xe_hw_engine.c        |  6 ++++--
 drivers/gpu/drm/xe/xe_hw_engine.h        |  3 ++-
 drivers/gpu/drm/xe/xe_irq.c              |  2 +-
 drivers/gpu/drm/xe/xe_memirq.c           |  2 +-
 drivers/gpu/drm/xe/xe_sync.c             |  3 ++-
 drivers/gpu/drm/xe/xe_wait_user_fence.c  | 16 +++++++++++++++-
 drivers/gpu/drm/xe/xe_wait_user_fence.h  |  4 ++++
 10 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c
index 6c101b4f6488..aa49400b67ba 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue.c
+++ b/drivers/gpu/drm/xe/xe_exec_queue.c
@@ -260,6 +260,7 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,
 	INIT_LIST_HEAD(&q->multi_gt_link);
 	INIT_LIST_HEAD(&q->hw_engine_group_link);
 	INIT_LIST_HEAD(&q->pxp.link);
+	init_waitqueue_head(&q->ufence_wq);
 	spin_lock_init(&q->multi_queue.lock);
 	spin_lock_init(&q->lrc_lookup_lock);
 	q->multi_queue.priority = XE_MULTI_QUEUE_PRIORITY_NORMAL;
diff --git a/drivers/gpu/drm/xe/xe_exec_queue_types.h b/drivers/gpu/drm/xe/xe_exec_queue_types.h
index 2f5ccf294675..edd2ecc8a27c 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue_types.h
+++ b/drivers/gpu/drm/xe/xe_exec_queue_types.h
@@ -231,6 +231,9 @@ struct xe_exec_queue {
 		struct list_head link;
 	} pxp;
 
+	/** @ufence_wq: per-queue user fence wait queue */
+	wait_queue_head_t ufence_wq;
+
 	/** @ufence_syncobj: User fence syncobj */
 	struct drm_syncobj *ufence_syncobj;
 
diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
index 4b247a3019d2..97ab4892dc02 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -21,6 +21,7 @@
 #include "xe_device.h"
 #include "xe_exec_queue.h"
 #include "xe_force_wake.h"
+#include "xe_wait_user_fence.h"
 #include "xe_gpu_scheduler.h"
 #include "xe_gt.h"
 #include "xe_gt_clock.h"
@@ -555,11 +556,8 @@ static bool vf_recovery(struct xe_guc *guc)
 
 static void xe_guc_exec_queue_trigger_cleanup(struct xe_exec_queue *q)
 {
-	struct xe_guc *guc = exec_queue_to_guc(q);
-	struct xe_device *xe = guc_to_xe(guc);
-
 	/** to wakeup xe_wait_user_fence ioctl if exec queue is reset */
-	wake_up_all(&xe->ufence_wq);
+	xe_wait_user_fence_wake(gt_to_xe(q->gt), q);
 
 	xe_sched_tdr_queue_imm(&q->guc->sched);
 }
diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c
index 98265293f2dc..05780bd5beba 100644
--- a/drivers/gpu/drm/xe/xe_hw_engine.c
+++ b/drivers/gpu/drm/xe/xe_hw_engine.c
@@ -42,6 +42,7 @@
 #include "xe_tuning.h"
 #include "xe_uc_fw.h"
 #include "xe_wa.h"
+#include "xe_wait_user_fence.h"
 
 #define MAX_MMIO_BASES 3
 struct engine_info {
@@ -894,9 +895,10 @@ int xe_hw_engines_init(struct xe_gt *gt)
 	return 0;
 }
 
-void xe_hw_engine_handle_irq(struct xe_hw_engine *hwe, u16 intr_vec)
+void xe_hw_engine_handle_irq(struct xe_hw_engine *hwe, u16 intr_vec,
+			     struct xe_exec_queue *q)
 {
-	wake_up_all(&gt_to_xe(hwe->gt)->ufence_wq);
+	xe_wait_user_fence_wake(gt_to_xe(hwe->gt), q);
 
 	if (hwe->irq_handler)
 		hwe->irq_handler(hwe, intr_vec);
diff --git a/drivers/gpu/drm/xe/xe_hw_engine.h b/drivers/gpu/drm/xe/xe_hw_engine.h
index c3ee37f8cfc0..7501c9051a71 100644
--- a/drivers/gpu/drm/xe/xe_hw_engine.h
+++ b/drivers/gpu/drm/xe/xe_hw_engine.h
@@ -51,7 +51,8 @@ struct xe_exec_queue;
 
 int xe_hw_engines_init_early(struct xe_gt *gt);
 int xe_hw_engines_init(struct xe_gt *gt);
-void xe_hw_engine_handle_irq(struct xe_hw_engine *hwe, u16 intr_vec);
+void xe_hw_engine_handle_irq(struct xe_hw_engine *hwe, u16 intr_vec,
+			     struct xe_exec_queue *q);
 void xe_hw_engine_enable_ring(struct xe_hw_engine *hwe);
 u32 xe_hw_engine_mask_per_class(struct xe_gt *gt,
 				enum xe_engine_class engine_class);
diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c
index 871c6c5c4fac..935a90719e75 100644
--- a/drivers/gpu/drm/xe/xe_irq.c
+++ b/drivers/gpu/drm/xe/xe_irq.c
@@ -385,7 +385,7 @@ static void gt_irq_handler(struct xe_tile *tile,
 
 			hwe = xe_gt_hw_engine(engine_gt, class, instance, false);
 			if (hwe) {
-				xe_hw_engine_handle_irq(hwe, intr_vec);
+				xe_hw_engine_handle_irq(hwe, intr_vec, NULL);
 				continue;
 			}
 
diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c
index 208f44436c66..427a0e13f7aa 100644
--- a/drivers/gpu/drm/xe/xe_memirq.c
+++ b/drivers/gpu/drm/xe/xe_memirq.c
@@ -459,7 +459,7 @@ static void memirq_dispatch_engine(struct xe_memirq *memirq,
 	 * is opportunistic, unconditionally pass MI_USER_INTERRUPT to issue
 	 * that check.
 	 */
-	xe_hw_engine_handle_irq(hwe, GT_MI_USER_INTERRUPT);
+	xe_hw_engine_handle_irq(hwe, GT_MI_USER_INTERRUPT, q);
 }
 
 static void memirq_dispatch_guc(struct xe_memirq *memirq, struct iosys_map *status,
diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c
index 37866768d64c..652341f22460 100644
--- a/drivers/gpu/drm/xe/xe_sync.c
+++ b/drivers/gpu/drm/xe/xe_sync.c
@@ -18,6 +18,7 @@
 #include "xe_exec_queue.h"
 #include "xe_macros.h"
 #include "xe_sched_job_types.h"
+#include "xe_wait_user_fence.h"
 
 struct xe_user_fence {
 	struct xe_device *xe;
@@ -92,7 +93,7 @@ static void user_fence_worker(struct work_struct *w)
 	 * Wake up waiters only after updating the ufence state, allowing the UMD
 	 * to safely reuse the same ufence without encountering -EBUSY errors.
 	 */
-	wake_up_all(&ufence->xe->ufence_wq);
+	xe_wait_user_fence_wake(ufence->xe, NULL);
 	user_fence_put(ufence);
 }
 
diff --git a/drivers/gpu/drm/xe/xe_wait_user_fence.c b/drivers/gpu/drm/xe/xe_wait_user_fence.c
index 12ceb3efa8ea..7c9d52b50580 100644
--- a/drivers/gpu/drm/xe/xe_wait_user_fence.c
+++ b/drivers/gpu/drm/xe/xe_wait_user_fence.c
@@ -54,6 +54,20 @@ static int do_compare(u64 addr, u64 value, u64 mask, u16 op)
 #define VALID_FLAGS	DRM_XE_UFENCE_WAIT_FLAG_ABSTIME
 #define MAX_OP		DRM_XE_UFENCE_WAIT_OP_LTE
 
+/**
+ * xe_wait_user_fence_wake() - Wake user fence waiters
+ * @xe: the xe device
+ * @q: exec queue (reserved; per-queue wake-up is enabled in a later patch)
+ *
+ * Wakes all user fence waiters on the device-level wait queue.
+ * Per-exec-queue and ufence_list broadcast support are introduced in
+ * subsequent patches once the full infrastructure is in place.
+ */
+void xe_wait_user_fence_wake(struct xe_device *xe, struct xe_exec_queue *q)
+{
+	wake_up_all(&xe->ufence_wq);
+}
+
 static long to_jiffies_timeout(struct xe_device *xe,
 			       struct drm_xe_wait_user_fence *args)
 {
@@ -110,7 +124,7 @@ static long to_jiffies_timeout(struct xe_device *xe,
  *
  * If an exec queue ID is provided, the wait is aborted early if the
  * queue enters a reset state. The device-level wait queue is used for
- * wakeups.
+ * wakeups in all cases.
  *
  * On return, @timeout is updated to reflect the remaining time (or zero
  * on expiry), unless %DRM_XE_UFENCE_WAIT_FLAG_ABSTIME is set.
diff --git a/drivers/gpu/drm/xe/xe_wait_user_fence.h b/drivers/gpu/drm/xe/xe_wait_user_fence.h
index 0e268978f9e6..64e5000eabb4 100644
--- a/drivers/gpu/drm/xe/xe_wait_user_fence.h
+++ b/drivers/gpu/drm/xe/xe_wait_user_fence.h
@@ -8,6 +8,10 @@
 
 struct drm_device;
 struct drm_file;
+struct xe_device;
+struct xe_exec_queue;
+
+void xe_wait_user_fence_wake(struct xe_device *xe, struct xe_exec_queue *q);
 
 int xe_wait_user_fence_ioctl(struct drm_device *dev, void *data,
 			     struct drm_file *file);
-- 
2.43.0


  parent reply	other threads:[~2026-06-05 23:21 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-05 23:21 [PATCH 00/12] Enable per exec queue MSI-X vector assignment Stuart Summers
2026-06-05 23:21 ` [PATCH 01/12] drm/xe: Add kerneldoc to xe_wait_user_fence_ioctl() Stuart Summers
2026-06-05 23:21 ` [PATCH 02/12] drm/xe: Handle NULL in xe_exec_queue_get_unless_zero() Stuart Summers
2026-06-05 23:21 ` [PATCH 03/12] drm/xe: Cap MSI-X vector count to XE_MSIX_MAX_VECS Stuart Summers
2026-06-05 23:21 ` [PATCH 04/12] drm/xe: Assign dedicated MSI-X vectors to exec queues Stuart Summers
2026-06-05 23:21 ` [PATCH 05/12] drm/xe: Add configfs max_msix_vecs attribute Stuart Summers
2026-06-05 23:21 ` [PATCH 06/12] drm/xe: Change MSI-X assignment failure to drm_dbg Stuart Summers
2026-06-06 10:57   ` Michal Wajdeczko
2026-06-08 20:30     ` Summers, Stuart
2026-06-05 23:21 ` [PATCH 07/12] drm/xe: Remove memirq status and source checks for engine interrupts Stuart Summers
2026-06-06 11:18   ` Michal Wajdeczko
2026-06-05 23:21 ` Stuart Summers [this message]
2026-06-05 23:21 ` [PATCH 09/12] drm/xe: Track all exec queues in a device-level ufence list Stuart Summers
2026-06-05 23:21 ` [PATCH 10/12] drm/xe: Hook up per queue thread wake to the unique MSI-X vector allocation Stuart Summers
2026-06-05 23:21 ` [PATCH 11/12] drm/xe: Enable per-queue ufence wake in ioctl and wake function Stuart Summers
2026-06-05 23:21 ` [PATCH 12/12] drm/xe/memirq: Enable compute walker post-sync interrupt Stuart Summers
2026-06-05 23:47 ` ✗ CI.checkpatch: warning for Enable per exec queue MSI-X vector assignment Patchwork
2026-06-05 23:49 ` ✓ CI.KUnit: success " Patchwork
2026-06-06  0:43 ` ✓ Xe.CI.BAT: " Patchwork
2026-06-06 13:27 ` ✓ Xe.CI.FULL: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260605232108.674580-22-stuart.summers@intel.com \
    --to=stuart.summers@intel.com \
    --cc=alan.previn.teres.alexis@intel.com \
    --cc=ilia.levi@intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=michal.wajdeczko@intel.com \
    --cc=rodrigo.vivi@intel.com \
    --cc=x.wang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.