[PATCH v2 2/8] drm/xe/irq: add msix allocator

Niranjana Vishwanathapura niranjana.vishwanathapura at intel.com
Wed Jul 10 16:36:25 UTC 2024


On Thu, Jun 27, 2024 at 03:40:37PM +0300, Dani Liberman wrote:
>MSIX interrupts are considered as a system resource. There are
>several interrupts that will be assigned statically, and the rest
>will be allocated and released dynamically.
>
>Add MSIX allocator to manage all interrupts allocations.
>
>Signed-off-by: Dani Liberman <dliberman at habana.ai>
>---
> drivers/gpu/drm/xe/xe_device_types.h |  4 ++
> drivers/gpu/drm/xe/xe_irq.c          | 78 ++++++++++++++++++++++++++++
> drivers/gpu/drm/xe/xe_irq.h          |  5 ++
> 3 files changed, 87 insertions(+)
>
>diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
>index 09ce7ba1b4ed..0d772f8d4b40 100644
>--- a/drivers/gpu/drm/xe/xe_device_types.h
>+++ b/drivers/gpu/drm/xe/xe_device_types.h
>@@ -308,6 +308,10 @@ struct xe_device {
> 		bool enabled;
> 		/** @irq.msix_enabled: msix interrupts enabled on this device */
> 		bool msix_enabled;
>+		/** @irq.num_of_interrupts: number of msix interrupts */
>+		u32 num_of_interrupts;
>+		/** @irq.msix_indexes: used to allocate msix indexes */
>+		struct xarray msix_indexes;
> 	} irq;
>
> 	/** @ttm: ttm device */
>diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c
>index c0fc75592022..b552af53db2f 100644
>--- a/drivers/gpu/drm/xe/xe_irq.c
>+++ b/drivers/gpu/drm/xe/xe_irq.c
>@@ -30,6 +30,10 @@
> #define IIR(offset)				XE_REG(offset + 0x8)
> #define IER(offset)				XE_REG(offset + 0xc)
>
>+enum static_msix_allocations {
>+	NUM_OF_STATIC_MSIX,
>+};
>+
> static void assert_iir_is_zero(struct xe_gt *mmio, struct xe_reg reg)
> {
> 	u32 val = xe_mmio_read32(mmio, reg);
>@@ -816,3 +820,77 @@ void xe_irq_resume(struct xe_device *xe)
> 	for_each_gt(gt, xe, id)
> 		xe_irq_enable_hwe(gt);
> }
>+
>+static int xe_irq_alloc_msix(struct xe_device *xe, void *irq_buf, bool dynamic_msix, u32 *msix)
>+{
>+	struct xa_limit limit;
>+	int ret = 0;
>+	u32 id;
>+
>+	limit = (dynamic_msix) ? XA_LIMIT(NUM_OF_STATIC_MSIX, xe->irq.num_of_interrupts) :
>+				 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_release_msix(struct xe_device *xe, u32 msix)
>+{
>+	xa_erase(&xe->irq.msix_indexes, msix);
>+}
>+
>+int xe_request_irq(struct xe_device *xe, irq_handler_t handler, void *irq_buf, const char *name,
>+		   bool dynamic_msix, u32 *msix)
>+{
>+	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
>+	int ret, irq;
>+
>+	ret = xe_irq_alloc_msix(xe, irq_buf, dynamic_msix, msix);
>+	if (ret < 0)
>+		return ret;
>+
>+	irq = pci_irq_vector(pdev, *msix);
>+	if (irq < 0) {
>+		ret = irq;
>+		goto release_msix;
>+	}
>+
>+	ret = request_irq(irq, handler, IRQF_SHARED, name, irq_buf);
>+	if (ret < 0)
>+		goto release_msix;
>+
>+	return 0;
>+
>+release_msix:
>+	drm_err(&xe->drm, "Failed to request irq for MSIX %u\n", *msix);
>+	xe_irq_release_msix(xe, *msix);
>+	return ret;
>+}
>+
>+void xe_free_irq(struct xe_device *xe, u32 msix)
>+{
>+	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
>+	void *irq_buf;
>+	int irq;
>+
>+	irq_buf = xa_load(&xe->irq.msix_indexes, msix);
>+	if (!irq_buf) {
>+		drm_err(&xe->drm, "MSIX %u can't be released since it wasn't allocated\n", msix);
>+		return;
>+	}
>+
>+	irq = pci_irq_vector(pdev, msix);
>+	if (irq < 0) {
>+		drm_err(&xe->drm, "MSIX %u can't be released, there is no matching IRQ\n", msix);
>+		return;
>+	}
>+
>+	free_irq(irq, irq_buf);
>+	xe_irq_release_msix(xe, msix);
>+}
>diff --git a/drivers/gpu/drm/xe/xe_irq.h b/drivers/gpu/drm/xe/xe_irq.h
>index 067514e13675..6529dff90f76 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>
>+
> struct xe_device;
> struct xe_tile;
> struct xe_gt;
>@@ -14,5 +16,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_request_irq(struct xe_device *xe, irq_handler_t handler, void *irq_buf, const char *name,
>+		   bool dynamic_msix, u32 *msix);
>+void xe_free_irq(struct xe_device *xe, u32 msix);

Hmm...probably rename to keep xe_irq prefix here (xe_irq_request/free())?

Niranjana

>
> #endif
>-- 
>2.34.1
>


More information about the Intel-xe mailing list