Skip to content

Commit f0d3a3c

Browse files
illevirodrigovivi
authored andcommitted
drm/xe/irq: Manage MSI-X interrupts allocation
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> Reviewed-by: Piotr Piórkowski <piotr.piorkowski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241213072538.6823-4-ilia.levi@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent 21d07f5 commit f0d3a3c

3 files changed

Lines changed: 83 additions & 20 deletions

File tree

drivers/gpu/drm/xe/xe_device_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,8 @@ struct xe_device {
353353
struct {
354354
/** @irq.msix.nvec: number of MSI-X interrupts */
355355
u16 nvec;
356+
/** @irq.msix.indexes: used to allocate MSI-X indexes */
357+
struct xarray indexes;
356358
} msix;
357359
} irq;
358360

drivers/gpu/drm/xe/xe_irq.c

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ static int xe_irq_msix_init(struct xe_device *xe)
830830
}
831831

832832
xe->irq.msix.nvec = nvec;
833+
xa_init_flags(&xe->irq.msix.indexes, XA_FLAGS_ALLOC);
833834
return 0;
834835
}
835836

@@ -879,8 +880,32 @@ static irqreturn_t xe_irq_msix_default_hwe_handler(int irq, void *arg)
879880
return IRQ_HANDLED;
880881
}
881882

882-
static int xe_irq_msix_request_irq(struct xe_device *xe, irq_handler_t handler,
883-
const char *name, u16 msix)
883+
static int xe_irq_msix_alloc_vector(struct xe_device *xe, void *irq_buf,
884+
bool dynamic_msix, u16 *msix)
885+
{
886+
struct xa_limit limit;
887+
int ret;
888+
u32 id;
889+
890+
limit = (dynamic_msix) ? XA_LIMIT(NUM_OF_STATIC_MSIX, xe->irq.msix.nvec - 1) :
891+
XA_LIMIT(*msix, *msix);
892+
ret = xa_alloc(&xe->irq.msix.indexes, &id, irq_buf, limit, GFP_KERNEL);
893+
if (ret)
894+
return ret;
895+
896+
if (dynamic_msix)
897+
*msix = id;
898+
899+
return 0;
900+
}
901+
902+
static void xe_irq_msix_release_vector(struct xe_device *xe, u16 msix)
903+
{
904+
xa_erase(&xe->irq.msix.indexes, msix);
905+
}
906+
907+
static int xe_irq_msix_request_irq_internal(struct xe_device *xe, irq_handler_t handler,
908+
void *irq_buf, const char *name, u16 msix)
884909
{
885910
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
886911
int ret, irq;
@@ -889,59 +914,90 @@ static int xe_irq_msix_request_irq(struct xe_device *xe, irq_handler_t handler,
889914
if (irq < 0)
890915
return irq;
891916

892-
ret = request_irq(irq, handler, IRQF_SHARED, name, xe);
917+
ret = request_irq(irq, handler, IRQF_SHARED, name, irq_buf);
893918
if (ret < 0)
894919
return ret;
895920

896921
return 0;
897922
}
898923

899-
static void xe_irq_msix_free_irq(struct xe_device *xe, u16 msix)
924+
int xe_irq_msix_request_irq(struct xe_device *xe, irq_handler_t handler, void *irq_buf,
925+
const char *name, bool dynamic_msix, u16 *msix)
926+
{
927+
int ret;
928+
929+
ret = xe_irq_msix_alloc_vector(xe, irq_buf, dynamic_msix, msix);
930+
if (ret)
931+
return ret;
932+
933+
ret = xe_irq_msix_request_irq_internal(xe, handler, irq_buf, name, *msix);
934+
if (ret) {
935+
drm_err(&xe->drm, "Failed to request IRQ for MSI-X %u\n", *msix);
936+
xe_irq_msix_release_vector(xe, *msix);
937+
return ret;
938+
}
939+
940+
return 0;
941+
}
942+
943+
void xe_irq_msix_free_irq(struct xe_device *xe, u16 msix)
900944
{
901945
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
902946
int irq;
947+
void *irq_buf;
948+
949+
irq_buf = xa_load(&xe->irq.msix.indexes, msix);
950+
if (!irq_buf)
951+
return;
903952

904953
irq = pci_irq_vector(pdev, msix);
905954
if (irq < 0) {
906955
drm_err(&xe->drm, "MSI-X %u can't be released, there is no matching IRQ\n", msix);
907956
return;
908957
}
909958

910-
free_irq(irq, xe);
959+
free_irq(irq, irq_buf);
960+
xe_irq_msix_release_vector(xe, msix);
911961
}
912962

913-
static int xe_irq_msix_request_irqs(struct xe_device *xe)
963+
int xe_irq_msix_request_irqs(struct xe_device *xe)
914964
{
915965
int err;
966+
u16 msix;
916967

917-
err = xe_irq_msix_request_irq(xe, guc2host_irq_handler,
918-
DRIVER_NAME "-guc2host", GUC2HOST_MSIX);
919-
if (err) {
920-
drm_err(&xe->drm, "Failed to request MSI-X IRQ %d: %d\n", GUC2HOST_MSIX, err);
968+
msix = GUC2HOST_MSIX;
969+
err = xe_irq_msix_request_irq(xe, guc2host_irq_handler, xe,
970+
DRIVER_NAME "-guc2host", false, &msix);
971+
if (err)
921972
return err;
922-
}
923973

924-
err = xe_irq_msix_request_irq(xe, xe_irq_msix_default_hwe_handler,
925-
DRIVER_NAME "-default-msix", DEFAULT_MSIX);
974+
msix = DEFAULT_MSIX;
975+
err = xe_irq_msix_request_irq(xe, xe_irq_msix_default_hwe_handler, xe,
976+
DRIVER_NAME "-default-msix", false, &msix);
926977
if (err) {
927-
drm_err(&xe->drm, "Failed to request MSI-X IRQ %d: %d\n", DEFAULT_MSIX, err);
928978
xe_irq_msix_free_irq(xe, GUC2HOST_MSIX);
929979
return err;
930980
}
931981

932982
return 0;
933983
}
934984

935-
static void xe_irq_msix_free(struct xe_device *xe)
985+
void xe_irq_msix_free(struct xe_device *xe)
936986
{
937-
xe_irq_msix_free_irq(xe, GUC2HOST_MSIX);
938-
xe_irq_msix_free_irq(xe, DEFAULT_MSIX);
987+
unsigned long msix;
988+
u32 *dummy;
989+
990+
xa_for_each(&xe->irq.msix.indexes, msix, dummy)
991+
xe_irq_msix_free_irq(xe, msix);
992+
xa_destroy(&xe->irq.msix.indexes);
939993
}
940994

941-
static void xe_irq_msix_synchronize_irq(struct xe_device *xe)
995+
void xe_irq_msix_synchronize_irq(struct xe_device *xe)
942996
{
943997
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
998+
unsigned long msix;
999+
u32 *dummy;
9441000

945-
synchronize_irq(pci_irq_vector(pdev, GUC2HOST_MSIX));
946-
synchronize_irq(pci_irq_vector(pdev, DEFAULT_MSIX));
1001+
xa_for_each(&xe->irq.msix.indexes, msix, dummy)
1002+
synchronize_irq(pci_irq_vector(pdev, msix));
9471003
}

drivers/gpu/drm/xe/xe_irq.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#ifndef _XE_IRQ_H_
77
#define _XE_IRQ_H_
88

9+
#include <linux/interrupt.h>
10+
911
#define XE_IRQ_DEFAULT_MSIX 1
1012

1113
struct xe_device;
@@ -17,5 +19,8 @@ int xe_irq_install(struct xe_device *xe);
1719
void xe_irq_suspend(struct xe_device *xe);
1820
void xe_irq_resume(struct xe_device *xe);
1921
void xe_irq_enable_hwe(struct xe_gt *gt);
22+
int xe_irq_msix_request_irq(struct xe_device *xe, irq_handler_t handler, void *irq_buf,
23+
const char *name, bool dynamic_msix, u16 *msix);
24+
void xe_irq_msix_free_irq(struct xe_device *xe, u16 msix);
2025

2126
#endif

0 commit comments

Comments
 (0)