]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: mana: Allocate interrupt context for each EQ when creating vPort
authorLong Li <longli@microsoft.com>
Fri, 5 Jun 2026 00:57:14 +0000 (17:57 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 10 Jun 2026 00:22:27 +0000 (17:22 -0700)
Use GIC functions to create a dedicated interrupt context or acquire a
shared interrupt context for each EQ when setting up a vPort.

The caller now owns the GIC reference across the EQ create/destroy
lifecycle: mana_create_eq() calls mana_gd_get_gic() before creating
each EQ and mana_destroy_eq() calls mana_gd_put_gic() after destroying
it. The msix_index invalidation is moved from mana_gd_deregister_irq()
to the mana_gd_create_eq() error path so that mana_destroy_eq() can
read the index before teardown.

Signed-off-by: Long Li <longli@microsoft.com>
Link: https://patch.msgid.link/20260605005717.2059954-6-longli@microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/microsoft/mana/gdma_main.c
drivers/net/ethernet/microsoft/mana/mana_en.c
include/net/mana/gdma.h

index 653c091ad2969aad45dbe2af0102e348435e0db0..6feedbbdebc360d49d3eeaaea13494da28c9c636 100644 (file)
@@ -919,7 +919,6 @@ static void mana_gd_deregister_irq(struct gdma_queue *queue)
        }
        spin_unlock_irqrestore(&gic->lock, flags);
 
-       queue->eq.msix_index = INVALID_PCI_MSIX_INDEX;
        synchronize_rcu();
 }
 
@@ -1034,6 +1033,7 @@ static int mana_gd_create_eq(struct gdma_dev *gd,
 out:
        dev_err(dev, "Failed to create EQ: %d\n", err);
        mana_gd_destroy_eq(gc, false, queue);
+       queue->eq.msix_index = INVALID_PCI_MSIX_INDEX;
        return err;
 }
 
index 3ec8e94e7c17e94b1cbcc25076bd90f3e06518fb..beada8660258a092d1dc6eda0090e19c32daf546 100644 (file)
@@ -1645,6 +1645,7 @@ void mana_destroy_eq(struct mana_port_context *apc)
        struct mana_context *ac = apc->ac;
        struct gdma_context *gc = ac->gdma_dev->gdma_context;
        struct gdma_queue *eq;
+       unsigned int msi;
        int i;
 
        if (!apc->eqs)
@@ -1658,7 +1659,9 @@ void mana_destroy_eq(struct mana_port_context *apc)
                if (!eq)
                        continue;
 
+               msi = eq->eq.msix_index;
                mana_gd_destroy_queue(gc, eq);
+               mana_gd_put_gic(gc, !gc->msi_sharing, msi);
        }
 
        kfree(apc->eqs);
@@ -1675,6 +1678,7 @@ static void mana_create_eq_debugfs(struct mana_port_context *apc, int i)
        eq.mana_eq_debugfs = debugfs_create_dir(eqnum, apc->mana_eqs_debugfs);
        debugfs_create_u32("head", 0400, eq.mana_eq_debugfs, &eq.eq->head);
        debugfs_create_u32("tail", 0400, eq.mana_eq_debugfs, &eq.eq->tail);
+       debugfs_create_u32("irq", 0400, eq.mana_eq_debugfs, &eq.eq->eq.irq);
        debugfs_create_file("eq_dump", 0400, eq.mana_eq_debugfs, eq.eq, &mana_dbg_q_fops);
 }
 
@@ -1683,7 +1687,9 @@ int mana_create_eq(struct mana_port_context *apc)
        struct gdma_dev *gd = apc->ac->gdma_dev;
        struct gdma_context *gc = gd->gdma_context;
        struct gdma_queue_spec spec = {};
+       struct gdma_irq_context *gic;
        int err;
+       int msi;
        int i;
 
        if (WARN_ON(apc->eqs))
@@ -1703,12 +1709,22 @@ int mana_create_eq(struct mana_port_context *apc)
                debugfs_create_dir("EQs", apc->mana_port_debugfs);
 
        for (i = 0; i < apc->num_queues; i++) {
-               spec.eq.msix_index = (i + 1) % gc->num_msix_usable;
+               msi = (i + 1) % gc->num_msix_usable;
+
+               gic = mana_gd_get_gic(gc, !gc->msi_sharing, &msi);
+               if (IS_ERR(gic)) {
+                       err = PTR_ERR(gic);
+                       goto out;
+               }
+               spec.eq.msix_index = msi;
+
                err = mana_gd_create_mana_eq(gd, &spec, &apc->eqs[i].eq);
                if (err) {
                        dev_err(gc->dev, "Failed to create EQ %d : %d\n", i, err);
+                       mana_gd_put_gic(gc, !gc->msi_sharing, msi);
                        goto out;
                }
+               apc->eqs[i].eq->eq.irq = gic->irq;
                mana_create_eq_debugfs(apc, i);
        }
 
index e3ee85c614ec2ef161e90dc188f135fb6c350700..6a65fedae38f29af0326a56daa5c02fc1782f4d9 100644 (file)
@@ -342,6 +342,7 @@ struct gdma_queue {
                        void *context;
 
                        unsigned int msix_index;
+                       unsigned int irq;
 
                        u32 log2_throttle_limit;
                } eq;