Skip to content

Commit c56b593

Browse files
selvintxavierjgunthorpe
authored andcommitted
RDMA/bnxt_re: Honor vlan_id in GID entry comparison
A GID entry consists of GID, vlan, netdev and smac. Extend GID duplicate check comparisons to consider vlan_id as well to support IPv6 VLAN based link local addresses. Introduce a new structure (bnxt_qplib_gid_info) to hold gid and vlan_id information. The issue is discussed in the following thread https://lore.kernel.org/r/AM0PR05MB4866CFEDCDF3CDA1D7D18AA5D1F20@AM0PR05MB4866.eurprd05.prod.outlook.com Fixes: 823b23d ("IB/core: Allow vlan link local address based RoCE GIDs") Cc: <[email protected]> # v5.2+ Link: https://lore.kernel.org/r/[email protected] Reported-by: Yi Zhang <[email protected]> Co-developed-by: Parav Pandit <[email protected]> Signed-off-by: Parav Pandit <[email protected]> Signed-off-by: Selvin Xavier <[email protected]> Tested-by: Yi Zhang <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent f4d4611 commit c56b593

File tree

5 files changed

+30
-13
lines changed

5 files changed

+30
-13
lines changed

drivers/infiniband/hw/bnxt_re/ib_verbs.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context)
308308
struct bnxt_re_dev *rdev = to_bnxt_re_dev(attr->device, ibdev);
309309
struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl;
310310
struct bnxt_qplib_gid *gid_to_del;
311+
u16 vlan_id = 0xFFFF;
311312

312313
/* Delete the entry from the hardware */
313314
ctx = *context;
@@ -317,7 +318,8 @@ int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context)
317318
if (sgid_tbl && sgid_tbl->active) {
318319
if (ctx->idx >= sgid_tbl->max)
319320
return -EINVAL;
320-
gid_to_del = &sgid_tbl->tbl[ctx->idx];
321+
gid_to_del = &sgid_tbl->tbl[ctx->idx].gid;
322+
vlan_id = sgid_tbl->tbl[ctx->idx].vlan_id;
321323
/* DEL_GID is called in WQ context(netdevice_event_work_handler)
322324
* or via the ib_unregister_device path. In the former case QP1
323325
* may not be destroyed yet, in which case just return as FW
@@ -335,7 +337,8 @@ int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context)
335337
}
336338
ctx->refcnt--;
337339
if (!ctx->refcnt) {
338-
rc = bnxt_qplib_del_sgid(sgid_tbl, gid_to_del, true);
340+
rc = bnxt_qplib_del_sgid(sgid_tbl, gid_to_del,
341+
vlan_id, true);
339342
if (rc) {
340343
dev_err(rdev_to_dev(rdev),
341344
"Failed to remove GID: %#x", rc);

drivers/infiniband/hw/bnxt_re/qplib_res.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ static int bnxt_qplib_alloc_sgid_tbl(struct bnxt_qplib_res *res,
488488
struct bnxt_qplib_sgid_tbl *sgid_tbl,
489489
u16 max)
490490
{
491-
sgid_tbl->tbl = kcalloc(max, sizeof(struct bnxt_qplib_gid), GFP_KERNEL);
491+
sgid_tbl->tbl = kcalloc(max, sizeof(*sgid_tbl->tbl), GFP_KERNEL);
492492
if (!sgid_tbl->tbl)
493493
return -ENOMEM;
494494

@@ -526,9 +526,10 @@ static void bnxt_qplib_cleanup_sgid_tbl(struct bnxt_qplib_res *res,
526526
for (i = 0; i < sgid_tbl->max; i++) {
527527
if (memcmp(&sgid_tbl->tbl[i], &bnxt_qplib_gid_zero,
528528
sizeof(bnxt_qplib_gid_zero)))
529-
bnxt_qplib_del_sgid(sgid_tbl, &sgid_tbl->tbl[i], true);
529+
bnxt_qplib_del_sgid(sgid_tbl, &sgid_tbl->tbl[i].gid,
530+
sgid_tbl->tbl[i].vlan_id, true);
530531
}
531-
memset(sgid_tbl->tbl, 0, sizeof(struct bnxt_qplib_gid) * sgid_tbl->max);
532+
memset(sgid_tbl->tbl, 0, sizeof(*sgid_tbl->tbl) * sgid_tbl->max);
532533
memset(sgid_tbl->hw_id, -1, sizeof(u16) * sgid_tbl->max);
533534
memset(sgid_tbl->vlan, 0, sizeof(u8) * sgid_tbl->max);
534535
sgid_tbl->active = 0;
@@ -537,7 +538,11 @@ static void bnxt_qplib_cleanup_sgid_tbl(struct bnxt_qplib_res *res,
537538
static void bnxt_qplib_init_sgid_tbl(struct bnxt_qplib_sgid_tbl *sgid_tbl,
538539
struct net_device *netdev)
539540
{
540-
memset(sgid_tbl->tbl, 0, sizeof(struct bnxt_qplib_gid) * sgid_tbl->max);
541+
u32 i;
542+
543+
for (i = 0; i < sgid_tbl->max; i++)
544+
sgid_tbl->tbl[i].vlan_id = 0xffff;
545+
541546
memset(sgid_tbl->hw_id, -1, sizeof(u16) * sgid_tbl->max);
542547
}
543548

drivers/infiniband/hw/bnxt_re/qplib_res.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ struct bnxt_qplib_pd_tbl {
111111
};
112112

113113
struct bnxt_qplib_sgid_tbl {
114-
struct bnxt_qplib_gid *tbl;
114+
struct bnxt_qplib_gid_info *tbl;
115115
u16 *hw_id;
116116
u16 max;
117117
u16 active;

drivers/infiniband/hw/bnxt_re/qplib_sp.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,12 @@ int bnxt_qplib_get_sgid(struct bnxt_qplib_res *res,
213213
index, sgid_tbl->max);
214214
return -EINVAL;
215215
}
216-
memcpy(gid, &sgid_tbl->tbl[index], sizeof(*gid));
216+
memcpy(gid, &sgid_tbl->tbl[index].gid, sizeof(*gid));
217217
return 0;
218218
}
219219

220220
int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
221-
struct bnxt_qplib_gid *gid, bool update)
221+
struct bnxt_qplib_gid *gid, u16 vlan_id, bool update)
222222
{
223223
struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
224224
struct bnxt_qplib_res,
@@ -236,7 +236,8 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
236236
return -ENOMEM;
237237
}
238238
for (index = 0; index < sgid_tbl->max; index++) {
239-
if (!memcmp(&sgid_tbl->tbl[index], gid, sizeof(*gid)))
239+
if (!memcmp(&sgid_tbl->tbl[index].gid, gid, sizeof(*gid)) &&
240+
vlan_id == sgid_tbl->tbl[index].vlan_id)
240241
break;
241242
}
242243
if (index == sgid_tbl->max) {
@@ -262,8 +263,9 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
262263
if (rc)
263264
return rc;
264265
}
265-
memcpy(&sgid_tbl->tbl[index], &bnxt_qplib_gid_zero,
266+
memcpy(&sgid_tbl->tbl[index].gid, &bnxt_qplib_gid_zero,
266267
sizeof(bnxt_qplib_gid_zero));
268+
sgid_tbl->tbl[index].vlan_id = 0xFFFF;
267269
sgid_tbl->vlan[index] = 0;
268270
sgid_tbl->active--;
269271
dev_dbg(&res->pdev->dev,
@@ -296,7 +298,8 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
296298
}
297299
free_idx = sgid_tbl->max;
298300
for (i = 0; i < sgid_tbl->max; i++) {
299-
if (!memcmp(&sgid_tbl->tbl[i], gid, sizeof(*gid))) {
301+
if (!memcmp(&sgid_tbl->tbl[i], gid, sizeof(*gid)) &&
302+
sgid_tbl->tbl[i].vlan_id == vlan_id) {
300303
dev_dbg(&res->pdev->dev,
301304
"SGID entry already exist in entry %d!\n", i);
302305
*index = i;
@@ -351,6 +354,7 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
351354
}
352355
/* Add GID to the sgid_tbl */
353356
memcpy(&sgid_tbl->tbl[free_idx], gid, sizeof(*gid));
357+
sgid_tbl->tbl[free_idx].vlan_id = vlan_id;
354358
sgid_tbl->active++;
355359
if (vlan_id != 0xFFFF)
356360
sgid_tbl->vlan[free_idx] = 1;

drivers/infiniband/hw/bnxt_re/qplib_sp.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ struct bnxt_qplib_gid {
8484
u8 data[16];
8585
};
8686

87+
struct bnxt_qplib_gid_info {
88+
struct bnxt_qplib_gid gid;
89+
u16 vlan_id;
90+
};
91+
8792
struct bnxt_qplib_ah {
8893
struct bnxt_qplib_gid dgid;
8994
struct bnxt_qplib_pd *pd;
@@ -221,7 +226,7 @@ int bnxt_qplib_get_sgid(struct bnxt_qplib_res *res,
221226
struct bnxt_qplib_sgid_tbl *sgid_tbl, int index,
222227
struct bnxt_qplib_gid *gid);
223228
int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
224-
struct bnxt_qplib_gid *gid, bool update);
229+
struct bnxt_qplib_gid *gid, u16 vlan_id, bool update);
225230
int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
226231
struct bnxt_qplib_gid *gid, u8 *mac, u16 vlan_id,
227232
bool update, u32 *index);

0 commit comments

Comments
 (0)