net: mana: Use GIC functions to allocate global EQs

Replace the GDMA global interrupt setup code with the new GIC allocation
and release functions for managing interrupt contexts.

This changes the per-queue interrupt names in /proc/interrupts from
mana_q0, mana_q1, ... to mana_msi1, mana_msi2, ... to reflect the
MSI-X index rather than a zero-based queue number. The HWC interrupt
name (mana_hwc) is unchanged.

Signed-off-by: Long Li <longli@microsoft.com>
Link: https://patch.msgid.link/20260605005717.2059954-5-longli@microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Long Li 2026-06-04 17:57:13 -07:00 committed by Jakub Kicinski
parent d478457fc1
commit 346c277d1d

View File

@ -1949,7 +1949,7 @@ static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec)
struct gdma_context *gc = pci_get_drvdata(pdev);
struct gdma_irq_context *gic;
bool skip_first_cpu = false;
int *irqs, irq, err, i;
int *irqs, err, i, msi;
irqs = kmalloc_objs(int, nvec);
if (!irqs)
@ -1962,30 +1962,14 @@ static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec)
* further used in irq_setup()
*/
for (i = 1; i <= nvec; i++) {
gic = kzalloc_obj(*gic);
if (!gic) {
err = -ENOMEM;
msi = i;
gic = mana_gd_get_gic(gc, false, &msi);
if (IS_ERR(gic)) {
err = PTR_ERR(gic);
goto free_irq;
}
gic->handler = mana_gd_process_eq_events;
INIT_LIST_HEAD(&gic->eq_list);
spin_lock_init(&gic->lock);
snprintf(gic->name, MANA_IRQ_NAME_SZ, "mana_q%d@pci:%s",
i - 1, pci_name(pdev));
/* one pci vector is already allocated for HWC */
irqs[i - 1] = pci_irq_vector(pdev, i);
if (irqs[i - 1] < 0) {
err = irqs[i - 1];
goto free_current_gic;
}
err = request_irq(irqs[i - 1], mana_gd_intr, 0, gic->name, gic);
if (err)
goto free_current_gic;
xa_store(&gc->irq_contexts, i, gic, GFP_KERNEL);
irqs[i - 1] = gic->irq;
}
/*
@ -2007,20 +1991,9 @@ static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec)
kfree(irqs);
return 0;
free_current_gic:
kfree(gic);
free_irq:
for (i -= 1; i > 0; i--) {
irq = pci_irq_vector(pdev, i);
gic = xa_load(&gc->irq_contexts, i);
if (WARN_ON(!gic))
continue;
irq_update_affinity_hint(irq, NULL);
free_irq(irq, gic);
xa_erase(&gc->irq_contexts, i);
kfree(gic);
}
for (i -= 1; i > 0; i--)
mana_gd_put_gic(gc, false, i);
kfree(irqs);
return err;
}
@ -2029,9 +2002,9 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev, int nvec)
{
struct gdma_context *gc = pci_get_drvdata(pdev);
struct gdma_irq_context *gic;
int *irqs, *start_irqs, irq;
int *irqs, *start_irqs;
unsigned int cpu;
int err, i;
int err, i, msi;
irqs = kmalloc_objs(int, nvec);
if (!irqs)
@ -2040,34 +2013,14 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev, int nvec)
start_irqs = irqs;
for (i = 0; i < nvec; i++) {
gic = kzalloc_obj(*gic);
if (!gic) {
err = -ENOMEM;
msi = i;
gic = mana_gd_get_gic(gc, false, &msi);
if (IS_ERR(gic)) {
err = PTR_ERR(gic);
goto free_irq;
}
gic->handler = mana_gd_process_eq_events;
INIT_LIST_HEAD(&gic->eq_list);
spin_lock_init(&gic->lock);
if (!i)
snprintf(gic->name, MANA_IRQ_NAME_SZ, "mana_hwc@pci:%s",
pci_name(pdev));
else
snprintf(gic->name, MANA_IRQ_NAME_SZ, "mana_q%d@pci:%s",
i - 1, pci_name(pdev));
irqs[i] = pci_irq_vector(pdev, i);
if (irqs[i] < 0) {
err = irqs[i];
goto free_current_gic;
}
err = request_irq(irqs[i], mana_gd_intr, 0, gic->name, gic);
if (err)
goto free_current_gic;
xa_store(&gc->irq_contexts, i, gic, GFP_KERNEL);
irqs[i] = gic->irq;
}
/* If number of IRQ is one extra than number of online CPUs,
@ -2096,20 +2049,9 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev, int nvec)
kfree(start_irqs);
return 0;
free_current_gic:
kfree(gic);
free_irq:
for (i -= 1; i >= 0; i--) {
irq = pci_irq_vector(pdev, i);
gic = xa_load(&gc->irq_contexts, i);
if (WARN_ON(!gic))
continue;
irq_update_affinity_hint(irq, NULL);
free_irq(irq, gic);
xa_erase(&gc->irq_contexts, i);
kfree(gic);
}
for (i -= 1; i >= 0; i--)
mana_gd_put_gic(gc, false, i);
kfree(start_irqs);
return err;
@ -2183,28 +2125,20 @@ static int mana_gd_setup_remaining_irqs(struct pci_dev *pdev)
static void mana_gd_remove_irqs(struct pci_dev *pdev)
{
struct gdma_context *gc = pci_get_drvdata(pdev);
struct gdma_irq_context *gic;
int irq, i;
int i;
if (gc->max_num_msix < 1)
return;
for (i = 0; i < gc->max_num_msix; i++) {
irq = pci_irq_vector(pdev, i);
if (irq < 0)
if (!xa_load(&gc->irq_contexts, i))
continue;
gic = xa_load(&gc->irq_contexts, i);
if (WARN_ON(!gic))
continue;
/* Need to clear the hint before free_irq */
irq_update_affinity_hint(irq, NULL);
free_irq(irq, gic);
xa_erase(&gc->irq_contexts, i);
kfree(gic);
mana_gd_put_gic(gc, false, i);
}
WARN_ON(!xa_empty(&gc->irq_contexts));
pci_free_irq_vectors(pdev);
bitmap_free(gc->msi_bitmap);