mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
net: mana: Allocate interrupt context for each EQ when creating vPort
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>
This commit is contained in:
parent
346c277d1d
commit
487af6f539
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -342,6 +342,7 @@ struct gdma_queue {
|
|||
void *context;
|
||||
|
||||
unsigned int msix_index;
|
||||
unsigned int irq;
|
||||
|
||||
u32 log2_throttle_limit;
|
||||
} eq;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user