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 <[email protected]>
---
 .../net/ethernet/microsoft/mana/gdma_main.c   | 110 ++++--------------
 1 file changed, 22 insertions(+), 88 deletions(-)

diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c 
b/drivers/net/ethernet/microsoft/mana/gdma_main.c
index fd643300a427..653c091ad296 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -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)
-                       continue;
-
-               gic = xa_load(&gc->irq_contexts, i);
-               if (WARN_ON(!gic))
+               if (!xa_load(&gc->irq_contexts, i))
                        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);
-- 
2.43.0


Reply via email to