Intel-XE Archive on 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 04/12] drm/xe: Assign dedicated MSI-X vectors to exec queues
Date: Fri,  5 Jun 2026 23:21:11 +0000	[thread overview]
Message-ID: <20260605232108.674580-18-stuart.summers@intel.com> (raw)
In-Reply-To: <20260605232108.674580-14-stuart.summers@intel.com>

Assign a dedicated MSI-X interrupt vector to each user exec queue at
creation time when the platform supports MSI-X. If allocation fails
for any other reason, the queue silently falls back to the shared
default MSI-X vector.

Signed-off-by: Stuart Summers <stuart.summers@intel.com>
Assisted-by: Copilot:claude-sonnet-4.6
---
 drivers/gpu/drm/xe/xe_device_types.h |  5 ++++
 drivers/gpu/drm/xe/xe_exec_queue.c   | 34 +++++++++++++++++++++++++++-
 drivers/gpu/drm/xe/xe_irq.c          | 27 ++++++++++++++++++++--
 drivers/gpu/drm/xe/xe_irq.h          |  2 ++
 4 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 32dd2ffbc796..ff15de34fd17 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -255,6 +255,11 @@ struct xe_device {
 			u16 nvec;
 			/** @irq.msix.indexes: used to allocate MSI-X indexes */
 			struct xarray indexes;
+			/**
+			 * @irq.msix.vec_count: total number of MSI-X vectors
+			 * currently allocated (static + dynamic)
+			 */
+			atomic_t vec_count;
 		} msix;
 	} irq;
 
diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c
index 1b5ca3ce578a..6c101b4f6488 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue.c
+++ b/drivers/gpu/drm/xe/xe_exec_queue.c
@@ -16,6 +16,7 @@
 #include "xe_bo.h"
 #include "xe_dep_scheduler.h"
 #include "xe_device.h"
+#include "xe_drv.h"
 #include "xe_gt.h"
 #include "xe_gt_sriov_pf.h"
 #include "xe_gt_sriov_vf.h"
@@ -138,6 +139,34 @@ static void xe_exec_queue_group_cleanup(struct xe_exec_queue *q)
 	kfree(group);
 }
 
+static void exec_queue_msix_init(struct xe_device *xe, struct xe_exec_queue *q)
+{
+	int err;
+	u16 msix;
+
+	if (!xe_device_has_msix(xe) || q->flags & EXEC_QUEUE_FLAG_KERNEL)
+		goto use_default;
+
+	err = xe_irq_msix_request_irq(xe, xe_irq_msix_hwe_handler, q,
+				      DRIVER_NAME "-exec-queue", true, &msix);
+	if (err)
+		goto use_default;
+
+	q->msix_vec = msix;
+	return;
+
+use_default:
+	q->msix_vec = XE_IRQ_DEFAULT_MSIX;
+}
+
+static void exec_queue_msix_fini(struct xe_exec_queue *q)
+{
+	struct xe_device *xe = gt_to_xe(q->gt);
+
+	if (q->msix_vec != XE_IRQ_DEFAULT_MSIX)
+		xe_irq_msix_free_irq(xe, q->msix_vec);
+}
+
 static void __xe_exec_queue_free(struct xe_exec_queue *q)
 {
 	int i;
@@ -152,6 +181,8 @@ static void __xe_exec_queue_free(struct xe_exec_queue *q)
 	if (xe_exec_queue_is_multi_queue(q))
 		xe_exec_queue_group_cleanup(q);
 
+	exec_queue_msix_fini(q);
+
 	if (q->vm) {
 		xe_vm_remove_exec_queue(q->vm, q);
 		xe_vm_put(q->vm);
@@ -220,7 +251,6 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,
 	q->gt = gt;
 	q->class = hwe->class;
 	q->width = width;
-	q->msix_vec = XE_IRQ_DEFAULT_MSIX;
 	q->logical_mask = logical_mask;
 	q->fence_irq = &gt->fence_irq[hwe->class];
 	q->ring_ops = gt->ring_ops[hwe->class];
@@ -436,6 +466,8 @@ struct xe_exec_queue *xe_exec_queue_create(struct xe_device *xe, struct xe_vm *v
 	if (IS_ERR(q))
 		return q;
 
+	exec_queue_msix_init(xe, q);
+
 	err = __xe_exec_queue_init(q, flags);
 	if (err)
 		goto err_post_alloc;
diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c
index 3429bb305293..c84d2283dd6a 100644
--- a/drivers/gpu/drm/xe/xe_irq.c
+++ b/drivers/gpu/drm/xe/xe_irq.c
@@ -13,6 +13,7 @@
 #include "regs/xe_irq_regs.h"
 #include "xe_device.h"
 #include "xe_drv.h"
+#include "xe_exec_queue.h"
 #include "xe_gsc_proxy.h"
 #include "xe_gt.h"
 #include "xe_guc.h"
@@ -930,6 +931,19 @@ static irqreturn_t xe_irq_msix_default_hwe_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
+irqreturn_t xe_irq_msix_hwe_handler(int irq, void *arg)
+{
+	struct xe_exec_queue *q = arg;
+	struct xe_tile *tile = gt_to_tile(q->hwe->gt);
+
+	if (!atomic_read(&tile->xe->irq.enabled))
+		return IRQ_NONE;
+
+	xe_memirq_hwe_handler(&tile->memirq, q->hwe);
+
+	return IRQ_HANDLED;
+}
+
 static int xe_irq_msix_alloc_vector(struct xe_device *xe, void *irq_buf,
 				    bool dynamic_msix, u16 *msix)
 {
@@ -976,18 +990,26 @@ int xe_irq_msix_request_irq(struct xe_device *xe, irq_handler_t handler, void *i
 {
 	int ret;
 
+	if (!atomic_add_unless(&xe->irq.msix.vec_count, 1,
+			       xe->irq.msix.nvec))
+		return -ENOSPC;
+
 	ret = xe_irq_msix_alloc_vector(xe, irq_buf, dynamic_msix, msix);
 	if (ret)
-		return ret;
+		goto err_dec;
 
 	ret = xe_irq_msix_request_irq_internal(xe, handler, irq_buf, name, *msix);
 	if (ret) {
 		drm_err(&xe->drm, "Failed to request IRQ for MSI-X %u\n", *msix);
 		xe_irq_msix_release_vector(xe, *msix);
-		return ret;
+		goto err_dec;
 	}
 
 	return 0;
+
+err_dec:
+	atomic_dec(&xe->irq.msix.vec_count);
+	return ret;
 }
 
 void xe_irq_msix_free_irq(struct xe_device *xe, u16 msix)
@@ -1008,6 +1030,7 @@ void xe_irq_msix_free_irq(struct xe_device *xe, u16 msix)
 
 	free_irq(irq, irq_buf);
 	xe_irq_msix_release_vector(xe, msix);
+	atomic_dec(&xe->irq.msix.vec_count);
 }
 
 int xe_irq_msix_request_irqs(struct xe_device *xe)
diff --git a/drivers/gpu/drm/xe/xe_irq.h b/drivers/gpu/drm/xe/xe_irq.h
index 5f48249dae8a..6c76004d6442 100644
--- a/drivers/gpu/drm/xe/xe_irq.h
+++ b/drivers/gpu/drm/xe/xe_irq.h
@@ -18,6 +18,7 @@
 #define XE_MSIX_MAX_VECS 1024
 
 struct xe_device;
+struct xe_exec_queue;
 struct xe_tile;
 struct xe_gt;
 
@@ -29,5 +30,6 @@ void xe_irq_enable_hwe(struct xe_gt *gt);
 int xe_irq_msix_request_irq(struct xe_device *xe, irq_handler_t handler, void *irq_buf,
 			    const char *name, bool dynamic_msix, u16 *msix);
 void xe_irq_msix_free_irq(struct xe_device *xe, u16 msix);
+irqreturn_t xe_irq_msix_hwe_handler(int irq, void *arg);
 
 #endif
-- 
2.43.0


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

Thread overview: 24+ 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 ` Stuart Summers [this message]
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-09 19:54       ` 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-09 19:38     ` Summers, Stuart
2026-06-09 21:29       ` Michal Wajdeczko
2026-06-09 22:12         ` Summers, Stuart
2026-06-05 23:21 ` [PATCH 08/12] drm/xe: Add per-exec-queue user fence wait queue Stuart Summers
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-18-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox