Skip to content

Commit 4730f4a

Browse files
grzegorz-andrejczukjgunthorpe
authored andcommitted
IB/hfi1: Activate the dummy netdev
As described in earlier patches, ipoib netdev will share receive contexts with existing VNIC netdev through a dummy netdev. The following changes are made to achieve that: - Set up netdev receive contexts after user contexts. A function is added to count the available netdev receive contexts. - Add functions to set/get receive map table free index. - Rename NUM_VNIC_MAP_ENTRIES as NUM_NETDEV_MAP_ENTRIES. - Let the dummy netdev own the receive contexts instead of VNIC. - Allocate the dummy netdev when the hfi1 device is added and free it when the device is removed. - Initialize AIP RSM rules when the IpoIb rxq is initialized and remove the rules when it is de-initialized. - Convert VNIC to use the dummy netdev. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Mike Marciniszyn <[email protected]> Reviewed-by: Dennis Dalessandro <[email protected]> Signed-off-by: Sadanand Warrier <[email protected]> Signed-off-by: Grzegorz Andrejczuk <[email protected]> Signed-off-by: Dennis Dalessandro <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 370caa5 commit 4730f4a

File tree

11 files changed

+178
-342
lines changed

11 files changed

+178
-342
lines changed

drivers/infiniband/hw/hfi1/chip.c

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13396,8 +13396,7 @@ static int set_up_interrupts(struct hfi1_devdata *dd)
1339613396
static int set_up_context_variables(struct hfi1_devdata *dd)
1339713397
{
1339813398
unsigned long num_kernel_contexts;
13399-
u16 num_netdev_contexts = HFI1_NUM_VNIC_CTXT;
13400-
int total_contexts;
13399+
u16 num_netdev_contexts;
1340113400
int ret;
1340213401
unsigned ngroups;
1340313402
int rmt_count;
@@ -13434,13 +13433,6 @@ static int set_up_context_variables(struct hfi1_devdata *dd)
1343413433
num_kernel_contexts = send_contexts - num_vls - 1;
1343513434
}
1343613435

13437-
/* Accommodate VNIC contexts if possible */
13438-
if ((num_kernel_contexts + num_netdev_contexts) > rcv_contexts) {
13439-
dd_dev_err(dd, "No receive contexts available for VNIC\n");
13440-
num_netdev_contexts = 0;
13441-
}
13442-
total_contexts = num_kernel_contexts + num_netdev_contexts;
13443-
1344413436
/*
1344513437
* User contexts:
1344613438
* - default to 1 user context per real (non-HT) CPU core if
@@ -13453,15 +13445,19 @@ static int set_up_context_variables(struct hfi1_devdata *dd)
1345313445
/*
1345413446
* Adjust the counts given a global max.
1345513447
*/
13456-
if (total_contexts + n_usr_ctxts > rcv_contexts) {
13448+
if (num_kernel_contexts + n_usr_ctxts > rcv_contexts) {
1345713449
dd_dev_err(dd,
13458-
"Reducing # user receive contexts to: %d, from %u\n",
13459-
rcv_contexts - total_contexts,
13450+
"Reducing # user receive contexts to: %u, from %u\n",
13451+
(u32)(rcv_contexts - num_kernel_contexts),
1346013452
n_usr_ctxts);
1346113453
/* recalculate */
13462-
n_usr_ctxts = rcv_contexts - total_contexts;
13454+
n_usr_ctxts = rcv_contexts - num_kernel_contexts;
1346313455
}
1346413456

13457+
num_netdev_contexts =
13458+
hfi1_num_netdev_contexts(dd, rcv_contexts -
13459+
(num_kernel_contexts + n_usr_ctxts),
13460+
&node_affinity.real_cpu_mask);
1346513461
/*
1346613462
* The RMT entries are currently allocated as shown below:
1346713463
* 1. QOS (0 to 128 entries);
@@ -13487,17 +13483,16 @@ static int set_up_context_variables(struct hfi1_devdata *dd)
1348713483
n_usr_ctxts = user_rmt_reduced;
1348813484
}
1348913485

13490-
total_contexts += n_usr_ctxts;
13491-
13492-
/* the first N are kernel contexts, the rest are user/vnic contexts */
13493-
dd->num_rcv_contexts = total_contexts;
13486+
/* the first N are kernel contexts, the rest are user/netdev contexts */
13487+
dd->num_rcv_contexts =
13488+
num_kernel_contexts + n_usr_ctxts + num_netdev_contexts;
1349413489
dd->n_krcv_queues = num_kernel_contexts;
1349513490
dd->first_dyn_alloc_ctxt = num_kernel_contexts;
1349613491
dd->num_netdev_contexts = num_netdev_contexts;
1349713492
dd->num_user_contexts = n_usr_ctxts;
1349813493
dd->freectxts = n_usr_ctxts;
1349913494
dd_dev_info(dd,
13500-
"rcv contexts: chip %d, used %d (kernel %d, vnic %u, user %u)\n",
13495+
"rcv contexts: chip %d, used %d (kernel %d, netdev %u, user %u)\n",
1350113496
rcv_contexts,
1350213497
(int)dd->num_rcv_contexts,
1350313498
(int)dd->n_krcv_queues,
@@ -14554,43 +14549,44 @@ static bool hfi1_netdev_update_rmt(struct hfi1_devdata *dd)
1455414549
u8 ctx_id = 0;
1455514550
u64 reg;
1455614551
u32 regoff;
14557-
int rmt_start = dd->vnic.rmt_start;
14552+
int rmt_start = hfi1_netdev_get_free_rmt_idx(dd);
14553+
int ctxt_count = hfi1_netdev_ctxt_count(dd);
1455814554

1455914555
/* We already have contexts mapped in RMT */
1456014556
if (has_rsm_rule(dd, RSM_INS_VNIC) || has_rsm_rule(dd, RSM_INS_AIP)) {
1456114557
dd_dev_info(dd, "Contexts are already mapped in RMT\n");
1456214558
return true;
1456314559
}
1456414560

14565-
if (hfi1_is_rmt_full(rmt_start, NUM_VNIC_MAP_ENTRIES)) {
14561+
if (hfi1_is_rmt_full(rmt_start, NUM_NETDEV_MAP_ENTRIES)) {
1456614562
dd_dev_err(dd, "Not enought RMT entries used = %d\n",
1456714563
rmt_start);
1456814564
return false;
1456914565
}
1457014566

1457114567
dev_dbg(&(dd)->pcidev->dev, "RMT start = %d, end %d\n",
1457214568
rmt_start,
14573-
rmt_start + NUM_VNIC_MAP_ENTRIES);
14569+
rmt_start + NUM_NETDEV_MAP_ENTRIES);
1457414570

1457514571
/* Update RSM mapping table, 32 regs, 256 entries - 1 ctx per byte */
1457614572
regoff = RCV_RSM_MAP_TABLE + (rmt_start / 8) * 8;
1457714573
reg = read_csr(dd, regoff);
14578-
for (i = 0; i < NUM_VNIC_MAP_ENTRIES; i++) {
14574+
for (i = 0; i < NUM_NETDEV_MAP_ENTRIES; i++) {
1457914575
/* Update map register with netdev context */
1458014576
j = (rmt_start + i) % 8;
1458114577
reg &= ~(0xffllu << (j * 8));
14582-
reg |= (u64)dd->vnic.ctxt[ctx_id++]->ctxt << (j * 8);
14578+
reg |= (u64)hfi1_netdev_get_ctxt(dd, ctx_id++)->ctxt << (j * 8);
1458314579
/* Wrap up netdev ctx index */
14584-
ctx_id %= dd->vnic.num_ctxt;
14580+
ctx_id %= ctxt_count;
1458514581
/* Write back map register */
14586-
if (j == 7 || ((i + 1) == NUM_VNIC_MAP_ENTRIES)) {
14582+
if (j == 7 || ((i + 1) == NUM_NETDEV_MAP_ENTRIES)) {
1458714583
dev_dbg(&(dd)->pcidev->dev,
1458814584
"RMT[%d] =0x%llx\n",
1458914585
regoff - RCV_RSM_MAP_TABLE, reg);
1459014586

1459114587
write_csr(dd, regoff, reg);
1459214588
regoff += 8;
14593-
if (i < (NUM_VNIC_MAP_ENTRIES - 1))
14589+
if (i < (NUM_NETDEV_MAP_ENTRIES - 1))
1459414590
reg = read_csr(dd, regoff);
1459514591
}
1459614592
}
@@ -14617,8 +14613,9 @@ void hfi1_init_aip_rsm(struct hfi1_devdata *dd)
1461714613
* exist yet
1461814614
*/
1461914615
if (atomic_fetch_inc(&dd->ipoib_rsm_usr_num) == 0) {
14616+
int rmt_start = hfi1_netdev_get_free_rmt_idx(dd);
1462014617
struct rsm_rule_data rrd = {
14621-
.offset = dd->vnic.rmt_start,
14618+
.offset = rmt_start,
1462214619
.pkt_type = IB_PACKET_TYPE,
1462314620
.field1_off = LRH_BTH_MATCH_OFFSET,
1462414621
.mask1 = LRH_BTH_MASK,
@@ -14627,10 +14624,10 @@ void hfi1_init_aip_rsm(struct hfi1_devdata *dd)
1462714624
.mask2 = BTH_DESTQP_MASK,
1462814625
.value2 = BTH_DESTQP_VALUE,
1462914626
.index1_off = DETH_AIP_SQPN_SELECT_OFFSET +
14630-
ilog2(NUM_VNIC_MAP_ENTRIES),
14631-
.index1_width = ilog2(NUM_VNIC_MAP_ENTRIES),
14627+
ilog2(NUM_NETDEV_MAP_ENTRIES),
14628+
.index1_width = ilog2(NUM_NETDEV_MAP_ENTRIES),
1463214629
.index2_off = DETH_AIP_SQPN_SELECT_OFFSET,
14633-
.index2_width = ilog2(NUM_VNIC_MAP_ENTRIES)
14630+
.index2_width = ilog2(NUM_NETDEV_MAP_ENTRIES)
1463414631
};
1463514632

1463614633
hfi1_enable_rsm_rule(dd, RSM_INS_AIP, &rrd);
@@ -14640,9 +14637,10 @@ void hfi1_init_aip_rsm(struct hfi1_devdata *dd)
1464014637
/* Initialize RSM for VNIC */
1464114638
void hfi1_init_vnic_rsm(struct hfi1_devdata *dd)
1464214639
{
14640+
int rmt_start = hfi1_netdev_get_free_rmt_idx(dd);
1464314641
struct rsm_rule_data rrd = {
1464414642
/* Add rule for vnic */
14645-
.offset = dd->vnic.rmt_start,
14643+
.offset = rmt_start,
1464614644
.pkt_type = 4,
1464714645
/* Match 16B packets */
1464814646
.field1_off = L2_TYPE_MATCH_OFFSET,
@@ -14654,9 +14652,9 @@ void hfi1_init_vnic_rsm(struct hfi1_devdata *dd)
1465414652
.value2 = L4_16B_ETH_VALUE,
1465514653
/* Calc context from veswid and entropy */
1465614654
.index1_off = L4_16B_HDR_VESWID_OFFSET,
14657-
.index1_width = ilog2(NUM_VNIC_MAP_ENTRIES),
14655+
.index1_width = ilog2(NUM_NETDEV_MAP_ENTRIES),
1465814656
.index2_off = L2_16B_ENTROPY_OFFSET,
14659-
.index2_width = ilog2(NUM_VNIC_MAP_ENTRIES)
14657+
.index2_width = ilog2(NUM_NETDEV_MAP_ENTRIES)
1466014658
};
1466114659

1466214660
hfi1_enable_rsm_rule(dd, RSM_INS_VNIC, &rrd);
@@ -14690,8 +14688,8 @@ static int init_rxe(struct hfi1_devdata *dd)
1469014688
init_qos(dd, rmt);
1469114689
init_fecn_handling(dd, rmt);
1469214690
complete_rsm_map_table(dd, rmt);
14693-
/* record number of used rsm map entries for vnic */
14694-
dd->vnic.rmt_start = rmt->used;
14691+
/* record number of used rsm map entries for netdev */
14692+
hfi1_netdev_set_free_rmt_idx(dd, rmt->used);
1469514693
kfree(rmt);
1469614694

1469714695
/*
@@ -15245,6 +15243,10 @@ int hfi1_init_dd(struct hfi1_devdata *dd)
1524515243
(dd->revision >> CCE_REVISION_SW_SHIFT)
1524615244
& CCE_REVISION_SW_MASK);
1524715245

15246+
/* alloc netdev data */
15247+
if (hfi1_netdev_alloc(dd))
15248+
goto bail_cleanup;
15249+
1524815250
ret = set_up_context_variables(dd);
1524915251
if (ret)
1525015252
goto bail_cleanup;
@@ -15345,6 +15347,7 @@ int hfi1_init_dd(struct hfi1_devdata *dd)
1534515347
hfi1_comp_vectors_clean_up(dd);
1534615348
msix_clean_up_interrupts(dd);
1534715349
bail_cleanup:
15350+
hfi1_netdev_free(dd);
1534815351
hfi1_pcie_ddcleanup(dd);
1534915352
bail_free:
1535015353
hfi1_free_devdata(dd);

drivers/infiniband/hw/hfi1/driver.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,28 +1771,10 @@ static void process_receive_ib(struct hfi1_packet *packet)
17711771
hfi1_ib_rcv(packet);
17721772
}
17731773

1774-
static inline bool hfi1_is_vnic_packet(struct hfi1_packet *packet)
1775-
{
1776-
/* Packet received in VNIC context via RSM */
1777-
if (packet->rcd->is_vnic)
1778-
return true;
1779-
1780-
if ((hfi1_16B_get_l2(packet->ebuf) == OPA_16B_L2_TYPE) &&
1781-
(hfi1_16B_get_l4(packet->ebuf) == OPA_16B_L4_ETHR))
1782-
return true;
1783-
1784-
return false;
1785-
}
1786-
17871774
static void process_receive_bypass(struct hfi1_packet *packet)
17881775
{
17891776
struct hfi1_devdata *dd = packet->rcd->dd;
17901777

1791-
if (hfi1_is_vnic_packet(packet)) {
1792-
hfi1_vnic_bypass_rcv(packet);
1793-
return;
1794-
}
1795-
17961778
if (hfi1_setup_bypass_packet(packet))
17971779
return;
17981780

drivers/infiniband/hw/hfi1/hfi.h

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,23 +1047,10 @@ struct hfi1_asic_data {
10471047
#define NUM_MAP_ENTRIES 256
10481048
#define NUM_MAP_REGS 32
10491049

1050-
/*
1051-
* Number of VNIC contexts used. Ensure it is less than or equal to
1052-
* max queues supported by VNIC (HFI1_VNIC_MAX_QUEUE).
1053-
*/
1054-
#define HFI1_NUM_VNIC_CTXT 8
1055-
1056-
/* Number of VNIC RSM entries */
1057-
#define NUM_VNIC_MAP_ENTRIES 8
1058-
10591050
/* Virtual NIC information */
10601051
struct hfi1_vnic_data {
1061-
struct hfi1_ctxtdata *ctxt[HFI1_NUM_VNIC_CTXT];
10621052
struct kmem_cache *txreq_cache;
1063-
struct xarray vesws;
10641053
u8 num_vports;
1065-
u8 rmt_start;
1066-
u8 num_ctxt;
10671054
};
10681055

10691056
struct hfi1_vnic_vport_info;
@@ -1419,6 +1406,7 @@ struct hfi1_devdata {
14191406
struct hfi1_vnic_data vnic;
14201407
/* Lock to protect IRQ SRC register access */
14211408
spinlock_t irq_src_lock;
1409+
int vnic_num_vports;
14221410
struct net_device *dummy_netdev;
14231411

14241412
/* Keeps track of IPoIB RSM rule users */

drivers/infiniband/hw/hfi1/init.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
#include "affinity.h"
7070
#include "vnic.h"
7171
#include "exp_rcv.h"
72+
#include "netdev.h"
7273

7374
#undef pr_fmt
7475
#define pr_fmt(fmt) DRIVER_NAME ": " fmt
@@ -1665,9 +1666,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
16651666
/* do the generic initialization */
16661667
initfail = hfi1_init(dd, 0);
16671668

1668-
/* setup vnic */
1669-
hfi1_vnic_setup(dd);
1670-
16711669
ret = hfi1_register_ib_device(dd);
16721670

16731671
/*
@@ -1706,7 +1704,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
17061704
hfi1_device_remove(dd);
17071705
if (!ret)
17081706
hfi1_unregister_ib_device(dd);
1709-
hfi1_vnic_cleanup(dd);
17101707
postinit_cleanup(dd);
17111708
if (initfail)
17121709
ret = initfail;
@@ -1751,8 +1748,8 @@ static void remove_one(struct pci_dev *pdev)
17511748
/* unregister from IB core */
17521749
hfi1_unregister_ib_device(dd);
17531750

1754-
/* cleanup vnic */
1755-
hfi1_vnic_cleanup(dd);
1751+
/* free netdev data */
1752+
hfi1_netdev_free(dd);
17561753

17571754
/*
17581755
* Disable the IB link, disable interrupts on the device,

drivers/infiniband/hw/hfi1/ipoib_rx.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,22 @@ int hfi1_ipoib_rxq_init(struct net_device *netdev)
7474
{
7575
struct hfi1_ipoib_dev_priv *ipoib_priv = hfi1_ipoib_priv(netdev);
7676
struct hfi1_devdata *dd = ipoib_priv->dd;
77+
int ret;
7778

78-
return hfi1_netdev_rx_init(dd);
79+
ret = hfi1_netdev_rx_init(dd);
80+
if (ret)
81+
return ret;
82+
83+
hfi1_init_aip_rsm(dd);
84+
85+
return ret;
7986
}
8087

8188
void hfi1_ipoib_rxq_deinit(struct net_device *netdev)
8289
{
8390
struct hfi1_ipoib_dev_priv *ipoib_priv = hfi1_ipoib_priv(netdev);
8491
struct hfi1_devdata *dd = ipoib_priv->dd;
8592

93+
hfi1_deinit_aip_rsm(dd);
8694
hfi1_netdev_rx_destroy(dd);
8795
}

drivers/infiniband/hw/hfi1/msix.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ static int msix_request_rcd_irq_common(struct hfi1_ctxtdata *rcd,
172172
const char *name)
173173
{
174174
int nr = msix_request_irq(rcd->dd, rcd, handler, thread,
175-
IRQ_RCVCTXT, name);
175+
rcd->is_vnic ? IRQ_NETDEVCTXT : IRQ_RCVCTXT,
176+
name);
176177
if (nr < 0)
177178
return nr;
178179

@@ -371,15 +372,16 @@ void msix_clean_up_interrupts(struct hfi1_devdata *dd)
371372
}
372373

373374
/**
374-
* msix_vnic_syncrhonize_irq() - Vnic IRQ synchronize
375+
* msix_netdev_syncrhonize_irq() - netdev IRQ synchronize
375376
* @dd: valid devdata
376377
*/
377-
void msix_vnic_synchronize_irq(struct hfi1_devdata *dd)
378+
void msix_netdev_synchronize_irq(struct hfi1_devdata *dd)
378379
{
379380
int i;
381+
int ctxt_count = hfi1_netdev_ctxt_count(dd);
380382

381-
for (i = 0; i < dd->vnic.num_ctxt; i++) {
382-
struct hfi1_ctxtdata *rcd = dd->vnic.ctxt[i];
383+
for (i = 0; i < ctxt_count; i++) {
384+
struct hfi1_ctxtdata *rcd = hfi1_netdev_get_ctxt(dd, i);
383385
struct hfi1_msix_entry *me;
384386

385387
me = &dd->msix_info.msix_entries[rcd->msix_intr];

drivers/infiniband/hw/hfi1/msix.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ int msix_request_sdma_irq(struct sdma_engine *sde);
6060
void msix_free_irq(struct hfi1_devdata *dd, u8 msix_intr);
6161

6262
/* Netdev interface */
63-
void msix_vnic_synchronize_irq(struct hfi1_devdata *dd);
63+
void msix_netdev_synchronize_irq(struct hfi1_devdata *dd);
6464
int msix_netdev_request_rcd_irq(struct hfi1_ctxtdata *rcd);
6565

6666
#endif

drivers/infiniband/hw/hfi1/netdev.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,25 @@ struct hfi1_ctxtdata *hfi1_netdev_get_ctxt(struct hfi1_devdata *dd, int ctxt)
8282
return priv->rxq[ctxt].rcd;
8383
}
8484

85+
static inline
86+
int hfi1_netdev_get_free_rmt_idx(struct hfi1_devdata *dd)
87+
{
88+
struct hfi1_netdev_priv *priv = hfi1_netdev_priv(dd->dummy_netdev);
89+
90+
return priv->rmt_start;
91+
}
92+
93+
static inline
94+
void hfi1_netdev_set_free_rmt_idx(struct hfi1_devdata *dd, int rmt_idx)
95+
{
96+
struct hfi1_netdev_priv *priv = hfi1_netdev_priv(dd->dummy_netdev);
97+
98+
priv->rmt_start = rmt_idx;
99+
}
100+
101+
u32 hfi1_num_netdev_contexts(struct hfi1_devdata *dd, u32 available_contexts,
102+
struct cpumask *cpu_mask);
103+
85104
void hfi1_netdev_enable_queues(struct hfi1_devdata *dd);
86105
void hfi1_netdev_disable_queues(struct hfi1_devdata *dd);
87106
int hfi1_netdev_rx_init(struct hfi1_devdata *dd);

0 commit comments

Comments
 (0)