Skip to content

Commit 09fcf8e

Browse files
committed
net:mana: Introduce new gic context and refcount for interrupt context
To allow Ethernet EQs share or use MSIx and RDMA EQs on the same MSIx, introduce gic context and allow driver to create an interrupt context on an assigned/unassigned MSIx.
1 parent 837f860 commit 09fcf8e

2 files changed

Lines changed: 132 additions & 0 deletions

File tree

drivers/net/ethernet/microsoft/mana/gdma_main.c

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,129 @@ static irqreturn_t mana_gd_intr(int irq, void *arg)
13841384
return IRQ_HANDLED;
13851385
}
13861386

1387+
void gdma_put_gic(struct gdma_context *gc, bool use_bitmap, int msi)
1388+
{
1389+
struct pci_dev *dev = to_pci_dev(gc->dev);
1390+
struct msi_map irq_map;
1391+
struct gdma_irq_context *gic;
1392+
int irq;
1393+
1394+
mutex_lock(&gc->gic_mutex);
1395+
1396+
gic = xa_load(&gc->irq_contexts, msi);
1397+
if (WARN_ON(!gic)) {
1398+
mutex_unlock(&gc->gic_mutex);
1399+
return;
1400+
}
1401+
1402+
if (!refcount_dec_and_test(&gic->refcount))
1403+
goto clear_bitmap;
1404+
1405+
irq = pci_irq_vector(dev, msi);
1406+
1407+
irq_update_affinity_hint(irq, NULL);
1408+
free_irq(irq, gic);
1409+
1410+
irq_map.virq = irq;
1411+
irq_map.index = msi;
1412+
pci_msix_free_irq(dev, irq_map);
1413+
1414+
xa_erase(&gc->irq_contexts, msi);
1415+
kfree(gic);
1416+
1417+
clear_bitmap:
1418+
if (use_bitmap)
1419+
clear_bit(msi, gc->msi_bitmap);
1420+
1421+
mutex_unlock(&gc->gic_mutex);
1422+
}
1423+
EXPORT_SYMBOL_NS(gdma_put_gic, "NET_MANA");
1424+
1425+
struct gdma_irq_context *gdma_get_gic(struct gdma_context *gc, bool use_bitmap,
1426+
u16 port_index, int queue_index,
1427+
int *msi_requested)
1428+
{
1429+
struct gdma_irq_context *gic;
1430+
struct pci_dev *dev = to_pci_dev(gc->dev);
1431+
struct msi_map irq_map;
1432+
int irq;
1433+
int msi;
1434+
int err;
1435+
1436+
mutex_lock(&gc->gic_mutex);
1437+
1438+
if (use_bitmap) {
1439+
msi = find_first_zero_bit(gc->msi_bitmap, gc->num_msix_usable);
1440+
*msi_requested = msi;
1441+
} else {
1442+
msi = *msi_requested;
1443+
}
1444+
1445+
gic = xa_load(&gc->irq_contexts, msi);
1446+
if (gic) {
1447+
refcount_inc(&gic->refcount);
1448+
if (use_bitmap)
1449+
set_bit(msi, gc->msi_bitmap);
1450+
goto out;
1451+
}
1452+
1453+
irq = pci_irq_vector(dev, msi);
1454+
if (irq == -EINVAL) {
1455+
irq_map = pci_msix_alloc_irq_at(dev, msi, NULL);
1456+
if (!irq_map.virq) {
1457+
err = irq_map.index;
1458+
dev_err(gc->dev,
1459+
"Failed to alloc irq_map msi %d err %d\n",
1460+
msi, err);
1461+
gic = NULL;
1462+
goto out;
1463+
}
1464+
irq = irq_map.virq;
1465+
msi = irq_map.index;
1466+
}
1467+
1468+
gic = kzalloc(sizeof(*gic), GFP_KERNEL);
1469+
if (!gic) {
1470+
dev_err(gc->dev, "Failed to allocate gic\n");
1471+
goto out;
1472+
}
1473+
gic->handler = mana_gd_process_eq_events;
1474+
gic->msi = msi;
1475+
gic->irq = irq;
1476+
INIT_LIST_HEAD(&gic->eq_list);
1477+
spin_lock_init(&gic->lock);
1478+
1479+
if (!gic->msi)
1480+
snprintf(gic->name, MANA_IRQ_NAME_SZ, "mana_hwc@pci:%s",
1481+
pci_name(dev));
1482+
else if (use_bitmap)
1483+
snprintf(gic->name, MANA_IRQ_NAME_SZ, "mana_p%dq%d@pci:%s",
1484+
port_index, queue_index, pci_name(dev));
1485+
else
1486+
snprintf(gic->name, MANA_IRQ_NAME_SZ, "mana_q%d@pci:%s",
1487+
queue_index, pci_name(dev));
1488+
1489+
err = request_irq(irq, mana_gd_intr, 0, gic->name, gic);
1490+
if (err) {
1491+
dev_err(gc->dev, "Failed to request irq %d %s\n",
1492+
irq, gic->name);
1493+
kfree(gic);
1494+
gic = NULL;
1495+
goto out;
1496+
}
1497+
1498+
refcount_set(&gic->refcount, 1);
1499+
xa_store(&gc->irq_contexts, msi, gic, GFP_KERNEL);
1500+
1501+
if (use_bitmap)
1502+
set_bit(msi, gc->msi_bitmap);
1503+
1504+
out:
1505+
mutex_unlock(&gc->gic_mutex);
1506+
return gic;
1507+
}
1508+
EXPORT_SYMBOL_NS(gdma_get_gic, "NET_MANA");
1509+
13871510
int mana_gd_alloc_res_map(u32 res_avail, struct gdma_resource *r)
13881511
{
13891512
r->map = bitmap_zalloc(res_avail, GFP_KERNEL);
@@ -1856,6 +1979,7 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18561979
goto release_region;
18571980

18581981
mutex_init(&gc->eq_test_event_mutex);
1982+
mutex_init(&gc->gic_mutex);
18591983
pci_set_drvdata(pdev, gc);
18601984
gc->bar0_pa = pci_resource_start(pdev, 0);
18611985

include/net/mana/gdma.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,9 @@ struct gdma_irq_context {
363363
spinlock_t lock;
364364
struct list_head eq_list;
365365
char name[MANA_IRQ_NAME_SZ];
366+
unsigned int msi;
367+
unsigned int irq;
368+
refcount_t refcount;
366369
};
367370

368371
struct gdma_context {
@@ -410,6 +413,7 @@ struct gdma_context {
410413
/* Azure RDMA adapter */
411414
struct gdma_dev mana_ib;
412415

416+
struct mutex gic_mutex;
413417
bool msi_sharing;
414418
unsigned long *msi_bitmap;
415419
};
@@ -905,6 +909,10 @@ int mana_gd_destroy_dma_region(struct gdma_context *gc, u64 dma_region_handle);
905909
void mana_register_debugfs(void);
906910
void mana_unregister_debugfs(void);
907911

912+
struct gdma_irq_context *gdma_get_gic(struct gdma_context *gc, bool use_bitmap,
913+
u16 port_index, int queue_index,
914+
int *msi_requested);
915+
void gdma_put_gic(struct gdma_context *gc, bool use_bitmap, int msi);
908916
int mana_gd_query_device_cfg(struct gdma_context *gc, u32 proto_major_ver,
909917
u32 proto_minor_ver, u32 proto_micro_ver,
910918
u16 *max_num_vports);

0 commit comments

Comments
 (0)