From: Ilia Levi <ilia.levi@intel.com>
To: intel-xe@lists.freedesktop.org
Cc: ilia.levi@intel.com, piotr.piorkowski@intel.com,
niranjana.vishwanathapura@intel.com, koby.elbaz@intel.com,
yaron.avizrat@intel.com
Subject: [PATCH v5 4/5] drm/xe/irq: Manage MSI-X interrupts allocation
Date: Thu, 28 Nov 2024 14:53:44 +0200 [thread overview]
Message-ID: <20241128125345.1115-5-ilia.levi@intel.com> (raw)
In-Reply-To: <20241128125345.1115-1-ilia.levi@intel.com>
Expose functions to request and free MSI-X interrupts.
The request has two flavors:
- Static MSI-X allocation, for known MSI-X interrupts (e.g. GuC-to-host)
- Dynamic MSI-X allocation, which uses the next available MSI-X interrupt
Signed-off-by: Ilia Levi <ilia.levi@intel.com>
---
drivers/gpu/drm/xe/xe_device_types.h | 2 +
drivers/gpu/drm/xe/xe_irq.c | 96 ++++++++++++++++++++++------
drivers/gpu/drm/xe/xe_irq.h | 5 ++
3 files changed, 83 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index ed638067aa26..1a3ded5a97c1 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -353,6 +353,8 @@ struct xe_device {
struct {
/** @irq.msix.nvec: number of MSI-X interrupts */
u16 nvec;
+ /** @irq.msix.indexes: used to allocate MSI-X indexes */
+ struct xarray indexes;
} msix;
} irq;
diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c
index b8a0b9bbf24c..32f5a67a917b 100644
--- a/drivers/gpu/drm/xe/xe_irq.c
+++ b/drivers/gpu/drm/xe/xe_irq.c
@@ -830,6 +830,7 @@ static int xe_irq_msix_init(struct xe_device *xe)
}
xe->irq.msix.nvec = nvec;
+ xa_init_flags(&xe->irq.msix.indexes, XA_FLAGS_ALLOC);
return 0;
}
@@ -879,8 +880,32 @@ static irqreturn_t xe_irq_msix_default_hwe_handler(int irq, void *arg)
return IRQ_HANDLED;
}
-static int xe_irq_msix_request_irq(struct xe_device *xe, irq_handler_t handler,
- const char *name, u16 msix)
+static int xe_irq_msix_alloc_vector(struct xe_device *xe, void *irq_buf,
+ bool dynamic_msix, u16 *msix)
+{
+ struct xa_limit limit;
+ int ret;
+ u32 id;
+
+ limit = (dynamic_msix) ? XA_LIMIT(NUM_OF_STATIC_MSIX, xe->irq.msix.nvec - 1) :
+ XA_LIMIT(*msix, *msix);
+ ret = xa_alloc(&xe->irq.msix.indexes, &id, irq_buf, limit, GFP_KERNEL);
+ if (ret)
+ return ret;
+
+ if (dynamic_msix)
+ *msix = id;
+
+ return 0;
+}
+
+static void xe_irq_msix_release_vector(struct xe_device *xe, u16 msix)
+{
+ xa_erase(&xe->irq.msix.indexes, msix);
+}
+
+static int xe_irq_msix_request_irq_internal(struct xe_device *xe, irq_handler_t handler,
+ void *irq_buf, const char *name, u16 msix)
{
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
int ret, irq;
@@ -889,17 +914,41 @@ static int xe_irq_msix_request_irq(struct xe_device *xe, irq_handler_t handler,
if (irq < 0)
return irq;
- ret = request_irq(irq, handler, IRQF_SHARED, name, xe);
+ ret = request_irq(irq, handler, IRQF_SHARED, name, irq_buf);
if (ret < 0)
return ret;
return 0;
}
-static void xe_irq_msix_free_irq(struct xe_device *xe, u16 msix)
+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)
+{
+ int ret;
+
+ ret = xe_irq_msix_alloc_vector(xe, irq_buf, dynamic_msix, msix);
+ if (ret)
+ return ret;
+
+ 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;
+ }
+
+ return 0;
+}
+
+void xe_irq_msix_free_irq(struct xe_device *xe, u16 msix)
{
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
int irq;
+ void *irq_buf;
+
+ irq_buf = xa_load(&xe->irq.msix.indexes, msix);
+ if (!irq_buf)
+ return;
irq = pci_irq_vector(pdev, msix);
if (irq < 0) {
@@ -907,24 +956,25 @@ static void xe_irq_msix_free_irq(struct xe_device *xe, u16 msix)
return;
}
- free_irq(irq, xe);
+ free_irq(irq, irq_buf);
+ xe_irq_msix_release_vector(xe, msix);
}
-static int xe_irq_msix_request_irqs(struct xe_device *xe)
+int xe_irq_msix_request_irqs(struct xe_device *xe)
{
int err;
+ u16 msix;
- err = xe_irq_msix_request_irq(xe, guc2host_irq_handler,
- DRIVER_NAME "-guc2host", GUC2HOST_MSIX);
- if (err) {
- drm_err(&xe->drm, "Failed to request MSI-X IRQ %d: %d\n", GUC2HOST_MSIX, err);
+ msix = GUC2HOST_MSIX;
+ err = xe_irq_msix_request_irq(xe, guc2host_irq_handler, xe,
+ DRIVER_NAME "-guc2host", false, &msix);
+ if (err)
return err;
- }
- err = xe_irq_msix_request_irq(xe, xe_irq_msix_default_hwe_handler,
- DRIVER_NAME "-default-msix", DEFAULT_MSIX);
+ msix = DEFAULT_MSIX;
+ err = xe_irq_msix_request_irq(xe, xe_irq_msix_default_hwe_handler, xe,
+ DRIVER_NAME "-default-msix", false, &msix);
if (err) {
- drm_err(&xe->drm, "Failed to request MSI-X IRQ %d: %d\n", DEFAULT_MSIX, err);
xe_irq_msix_free_irq(xe, GUC2HOST_MSIX);
return err;
}
@@ -932,16 +982,22 @@ static int xe_irq_msix_request_irqs(struct xe_device *xe)
return 0;
}
-static void xe_irq_msix_free(struct xe_device *xe)
+void xe_irq_msix_free(struct xe_device *xe)
{
- xe_irq_msix_free_irq(xe, GUC2HOST_MSIX);
- xe_irq_msix_free_irq(xe, DEFAULT_MSIX);
+ unsigned long msix;
+ u32 *dummy;
+
+ xa_for_each(&xe->irq.msix.indexes, msix, dummy)
+ xe_irq_msix_free_irq(xe, msix);
+ xa_destroy(&xe->irq.msix.indexes);
}
-static void xe_irq_msix_synchronize_irq(struct xe_device *xe)
+void xe_irq_msix_synchronize_irq(struct xe_device *xe)
{
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
+ unsigned long msix;
+ u32 *dummy;
- synchronize_irq(pci_irq_vector(pdev, GUC2HOST_MSIX));
- synchronize_irq(pci_irq_vector(pdev, DEFAULT_MSIX));
+ xa_for_each(&xe->irq.msix.indexes, msix, dummy)
+ synchronize_irq(pci_irq_vector(pdev, msix));
}
diff --git a/drivers/gpu/drm/xe/xe_irq.h b/drivers/gpu/drm/xe/xe_irq.h
index 24ff16111b96..a28bd577ba52 100644
--- a/drivers/gpu/drm/xe/xe_irq.h
+++ b/drivers/gpu/drm/xe/xe_irq.h
@@ -6,6 +6,8 @@
#ifndef _XE_IRQ_H_
#define _XE_IRQ_H_
+#include <linux/interrupt.h>
+
#define XE_IRQ_DEFAULT_MSIX 1
struct xe_device;
@@ -17,5 +19,8 @@ int xe_irq_install(struct xe_device *xe);
void xe_irq_suspend(struct xe_device *xe);
void xe_irq_resume(struct xe_device *xe);
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);
#endif
--
2.43.2
next prev parent reply other threads:[~2024-11-28 12:54 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-28 12:53 [PATCH v5 0/5] MSI-X support Ilia Levi
2024-11-28 12:53 ` [PATCH v5 1/5] drm/xe: Make irq enabled flag atomic Ilia Levi
2024-12-02 18:32 ` Piotr Piórkowski
2024-12-03 11:47 ` Levi, Ilia
2024-12-05 17:24 ` Rodrigo Vivi
2024-11-28 12:53 ` [PATCH v5 2/5] drm/xe/irq: Separate MSI and MSI-X flows Ilia Levi
2024-12-02 18:59 ` Piotr Piórkowski
2024-12-03 9:04 ` Levi, Ilia
2024-12-05 8:35 ` Piotr Piórkowski
2024-11-28 12:53 ` [PATCH v5 3/5] drm/xe: Initial MSI-X support for HW engines Ilia Levi
2024-12-02 19:15 ` Piotr Piórkowski
2024-11-28 12:53 ` Ilia Levi [this message]
2024-12-05 9:07 ` [PATCH v5 4/5] drm/xe/irq: Manage MSI-X interrupts allocation Piotr Piórkowski
2024-11-28 12:53 ` [PATCH v5 5/5] drm/xe/uapi: Support requesting unique MSI-X for exec queue Ilia Levi
2024-12-05 9:00 ` Piotr Piórkowski
2024-11-28 13:01 ` ✓ CI.Patch_applied: success for MSI-X support Patchwork
2024-11-28 13:01 ` ✓ CI.checkpatch: " Patchwork
2024-11-28 13:03 ` ✓ CI.KUnit: " Patchwork
2024-11-28 13:20 ` ✓ CI.Build: " Patchwork
2024-11-28 13:23 ` ✓ CI.Hooks: " Patchwork
2024-11-28 13:24 ` ✓ CI.checksparse: " Patchwork
2024-11-28 13:42 ` ✓ Xe.CI.BAT: " Patchwork
2024-11-28 15:39 ` ✗ Xe.CI.Full: failure " Patchwork
2024-12-13 7:25 ` [PATCH v6 0/4] " Ilia Levi
2024-12-13 7:25 ` [PATCH v6 1/4] drm/xe/irq: Separate MSI and MSI-X flows Ilia Levi
2024-12-13 7:25 ` [PATCH v6 2/4] drm/xe: Initial MSI-X support for HW engines Ilia Levi
2024-12-13 7:25 ` [PATCH v6 3/4] drm/xe/irq: Manage MSI-X interrupts allocation Ilia Levi
2024-12-13 7:25 ` [PATCH v6 4/4] drm/xe/uapi: Support requesting unique MSI-X for exec queue Ilia Levi
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=20241128125345.1115-5-ilia.levi@intel.com \
--to=ilia.levi@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=koby.elbaz@intel.com \
--cc=niranjana.vishwanathapura@intel.com \
--cc=piotr.piorkowski@intel.com \
--cc=yaron.avizrat@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.