git: 6a75471dbcf0 - main - OFED: Various changes from Linux 4.19
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 24 Jun 2026 19:51:19 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=6a75471dbcf0fb187cf7918ee1a918fd7c9d002d
commit 6a75471dbcf0fb187cf7918ee1a918fd7c9d002d
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2026-06-24 19:30:56 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2026-06-24 19:30:56 +0000
OFED: Various changes from Linux 4.19
Many of these changes deal with shifting from fetcing SGID attributes
via an index in drivers to including references to SGID attributes in
other structures passed to driver callbacks which can be used directly
avoiding the need for fetching attributes via lookup functions. I had
to fixup the ROCE GID management code directly as the version in
FreeBSD is very different from Linux.
I also tweaked the change from commit
475c8de7bf2dc86d9806709a04e9c8f524d4ec32 to use a goto to reduce diffs
with upstream to minimize conflicts when merging upstream changes.
This contains changes from the following Linux commits:
a1a4caeebac9 IB/core: Do not set the gid type when reserving default entries
1c36cf912ad1 IB/core: Store default GID property per-table instead of per-entry
1dfce2945771 IB: Replace ib_query_gid/ib_get_cached_gid with rdma_query_gid
83f6f8d29dd3 IB/core: Make rdma_find_gid_by_filter support all protocols
c3d71b69a75c IB/core: Provide rdma_ versions of the gid cache API
77e786fcbe2e IB/core: Replace ib_query_gid with rdma_get_gid_attr
bf399c2cadfa IB/core: Introduce GID attribute get, put and hold APIs
f4df9a7c34d8 RDMA: Use GID from the ib_gid_attr during the add_gid() callback
b150c3862d21 IB/core: Introduce GID entry reference counts
47ec38666210 RDMA: Convert drivers to use sgid_attr instead of sgid_index
d97099fe53ed IB{cm, core}: Introduce and use ah_attr copy, move, replace APIs
947c99ecfcb4 IB/core: Tidy ib_resolve_eth_dmac
8d9ec9addd6c IB/core: Add a sgid_attr pointer to struct rdma_ah_attr
89af969a6653 RDMA: Convert drivers to use the AH's sgid_attr in post_wr paths
1a1f460ff151 RDMA: Hold the sgid_attr inside the struct ib_ah/qp
7492052a186b IB/mlx4: Use GID attribute from ah attribute
59d40813328f IB/core: Free GID table entry during GID deletion
881456789248 RDMA/cma: Consider net namespace while leaving multicast group
4ed13a5f2d60 IB/cm: Keep track of the sgid_attr that created the cm id
aa74f4878d61 IB: Make init_ah_attr_grh_fields set sgid_attr
f685c19529f0 IB: Make ib_init_ah_from_mcmember set sgid_attr
b7403217656d IB: Make ib_init_ah_attr_from_wc set sgid_attr
ea8c2d8f6014 RDMA/core: Remove unused ib cache functions
a8872d53e9b7 IB/cm: Use sgid_attr from the AV
398391071f25 IB/cm: Replace members of sa_path_rec with 'struct sgid_attr *'
815d456ef21a IB/cm: Pass the sgid_attr through various events
4eefd62c17a9 include/rdma/opa_addr.h: Fix an endianness issue
f8c2d2280cf6 RDMA/core: Remove set-but-not-used variables
28e39894ed4f RDMA/core: Remove ib_find_cached_gid() and ib_find_cached_gid_by_port()
07e7056aff6c IB/core: Simplify check for RoCE route resolve
40ddacf2dda9 RDMA/umem: Don't hold mmap_sem for too long
1215cb7c88ec RDMA/umem: Refactor exit paths in ib_umem_get
c012691508f5 IB/cm: Remove cma_multicast->igmp_joined
4b4671a0f269 IB/IPoIB: Simplify ib_post_(send|recv|srq_recv)() calls
1fec77bf8fcd RDMA/core: Simplify ib_post_(send|recv|srq_recv)() calls
bb039a870c05 IB/core: Allow ULPs to specify NULL as the third ib_post_(send|recv|srq_recv)() argument
643d213a9a03 RDMA/cma: Do not ignore net namespace for unbound cm_id
d274e45ce1ed RDMA/cma: Consider netdevice for RoCE ports
cee104334c98 IB/core: Introduce and use sgid_attr in CM requests
7150c3d5544b RDMA/core: Remove {create,destroy}_ah from mandatory verbs
854633165164 RDMA/core: Prefix _ib to IB/RoCE specific functions
7582df826734 RDMA/core: Avoid holding lock while initializing fields on stack
79d684f02647 RDMA/core: Simplify gid type check in cma_acquire_dev()
ca3a8ace2b12 RDMA/core: Return bool instead of int
05e0b86c413d RDMA/cma: Get rid of 1 bit boolean
e7ff98aefc9e RDMA/cma: Constify path record, ib_cm_event, listen_id pointers
2df7dba855e1 RDMA/core: Constify dst_addr argument
219d2e9dfda9 RDMA/cma: Simplify rdma_resolve_addr() error flow
26e551c5aec5 RDMA: Fix return code check in rdma_set_cq_moderation
58796e67d5d5 IB/ucm: Initialize sgid request GID attribute pointer
dd81b2c8a333 IB/core: Change filter function return type from int to bool
93065ac753e4 mm, oom: distinguish blockable mode for mmu notifiers
0d23ba6034b9 RDMA/ucma: check fd type in ucma_migrate_id()
Part of cee104334c98 was previously merged into FreeBSD. Namely, SGID
index fields had been added to the two param structures instead and
roce_get_net_dev_by_cm_event was implemented using SGID indices.
Tested by: Wafa Hamzah <wafah@nvidia.com> (mlx5_ib)
Tested by: John Baldwin <jhb@FreeBSD.org> (iw_cxgbe)
Sponsored by: Chelsio Communications
---
sys/dev/bnxt/bnxt_re/ib_verbs.c | 61 +-
sys/dev/bnxt/bnxt_re/ib_verbs.h | 3 +-
sys/dev/irdma/fbsd_kcompat.h | 3 +-
sys/dev/irdma/irdma_kcompat.c | 53 +-
sys/dev/mlx4/mlx4_ib/mlx4_ib.h | 2 +-
sys/dev/mlx4/mlx4_ib/mlx4_ib_ah.c | 19 +-
sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c | 30 +-
sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c | 32 +-
sys/dev/mlx5/mlx5_ib/mlx5_ib.h | 6 +-
sys/dev/mlx5/mlx5_ib/mlx5_ib_ah.c | 4 +-
sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c | 2 +-
sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c | 45 +-
sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c | 10 +-
sys/dev/mthca/mthca_av.c | 5 +-
sys/dev/qlnx/qlnxr/qlnxr_cm.c | 10 +-
sys/dev/qlnx/qlnxr/qlnxr_verbs.c | 5 +-
sys/ofed/drivers/infiniband/core/core_priv.h | 4 +-
sys/ofed/drivers/infiniband/core/ib_addr.c | 4 +-
sys/ofed/drivers/infiniband/core/ib_cache.c | 731 +++++++++++++--------
sys/ofed/drivers/infiniband/core/ib_cm.c | 138 ++--
sys/ofed/drivers/infiniband/core/ib_cma.c | 385 ++++++-----
sys/ofed/drivers/infiniband/core/ib_device.c | 23 +-
sys/ofed/drivers/infiniband/core/ib_mad.c | 17 +-
sys/ofed/drivers/infiniband/core/ib_multicast.c | 40 +-
.../drivers/infiniband/core/ib_roce_gid_mgmt.c | 30 +-
sys/ofed/drivers/infiniband/core/ib_sa_query.c | 106 ++-
sys/ofed/drivers/infiniband/core/ib_sysfs.c | 68 +-
sys/ofed/drivers/infiniband/core/ib_ucm.c | 15 +-
sys/ofed/drivers/infiniband/core/ib_ucma.c | 6 +
sys/ofed/drivers/infiniband/core/ib_umem.c | 58 +-
sys/ofed/drivers/infiniband/core/ib_umem_odp.c | 33 +-
sys/ofed/drivers/infiniband/core/ib_user_mad.c | 1 +
.../drivers/infiniband/core/ib_uverbs_marshall.c | 2 -
sys/ofed/drivers/infiniband/core/ib_verbs.c | 415 +++++++++---
sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_cm.c | 27 +-
.../drivers/infiniband/ulp/ipoib/ipoib_ethtool.c | 2 +-
sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c | 6 +-
sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 +-
.../drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 5 +-
sys/ofed/include/rdma/ib.h | 4 +-
sys/ofed/include/rdma/ib_addr.h | 6 +-
sys/ofed/include/rdma/ib_cache.h | 58 +-
sys/ofed/include/rdma/ib_cm.h | 14 +-
sys/ofed/include/rdma/ib_sa.h | 49 +-
sys/ofed/include/rdma/ib_umem_odp.h | 3 +-
sys/ofed/include/rdma/ib_verbs.h | 51 +-
sys/ofed/include/rdma/opa_addr.h | 2 +-
sys/ofed/include/rdma/rdma_cm.h | 2 +-
48 files changed, 1434 insertions(+), 1169 deletions(-)
diff --git a/sys/dev/bnxt/bnxt_re/ib_verbs.c b/sys/dev/bnxt/bnxt_re/ib_verbs.c
index 516d0bb8cddf..0162c130d23e 100644
--- a/sys/dev/bnxt/bnxt_re/ib_verbs.c
+++ b/sys/dev/bnxt/bnxt_re/ib_verbs.c
@@ -509,8 +509,7 @@ int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context)
return rc;
}
-int bnxt_re_add_gid(const union ib_gid *gid,
- const struct ib_gid_attr *attr, void **context)
+int bnxt_re_add_gid(const struct ib_gid_attr *attr, void **context)
{
int rc;
u32 tbl_idx = 0;
@@ -521,11 +520,12 @@ int bnxt_re_add_gid(const union ib_gid *gid,
if ((attr->ndev) && is_vlan_dev(attr->ndev))
vlan_id = vlan_dev_vlan_id(attr->ndev);
- rc = bnxt_qplib_add_sgid(sgid_tbl, gid,
+ rc = bnxt_qplib_add_sgid(sgid_tbl, &attr->gid,
rdev->dev_addr,
vlan_id, true, &tbl_idx);
if (rc == -EALREADY) {
- dev_dbg(rdev_to_dev(rdev), "GID %pI6 is already present\n", gid);
+ dev_dbg(rdev_to_dev(rdev), "GID %pI6 is already present\n",
+ &attr->gid);
ctx_tbl = sgid_tbl->ctx;
if (!ctx_tbl[tbl_idx]) {
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
@@ -921,53 +921,29 @@ static u8 _to_bnxt_re_nw_type(enum rdma_network_type ntype)
return nw_type;
}
-static inline int
-bnxt_re_get_cached_gid(struct ib_device *dev, u8 port_num, int index,
- union ib_gid *sgid, struct ib_gid_attr **sgid_attr,
- const struct ib_global_route *grh, struct ib_ah *ah)
-{
- int ret = 0;
-
- ret = ib_get_cached_gid(dev, port_num, index, sgid, *sgid_attr);
- return ret;
-}
-
-static inline enum rdma_network_type
-bnxt_re_gid_to_network_type(struct ib_gid_attr *sgid_attr,
- union ib_gid *sgid)
-{
- return ib_gid_to_network_type(sgid_attr->gid_type, sgid);
-}
-
static int bnxt_re_get_ah_info(struct bnxt_re_dev *rdev,
struct rdma_ah_attr *ah_attr,
struct bnxt_re_ah_info *ah_info)
{
- struct ib_gid_attr *gattr;
+ const struct ib_gid_attr *gattr;
enum rdma_network_type ib_ntype;
u8 ntype;
- union ib_gid *gid;
const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
int rc = 0;
- gid = &ah_info->sgid;
- gattr = &ah_info->sgid_attr;
-
- rc = bnxt_re_get_cached_gid(&rdev->ibdev, 1, grh->sgid_index,
- gid, &gattr, grh, NULL);
- if (rc)
- return rc;
+ gattr = grh->sgid_attr;
+ ah_info->sgid_attr = *gattr;
+ ah_info->sgid = gattr->gid;
/* Get vlan tag */
if (gattr->ndev) {
if (is_vlan_dev(gattr->ndev))
ah_info->vlan_tag = vlan_dev_vlan_id(gattr->ndev);
- if_rele(gattr->ndev);
}
/* Get network header type for this GID */
- ib_ntype = bnxt_re_gid_to_network_type(gattr, gid);
+ ib_ntype = rdma_gid_attr_network_type(gattr);
ntype = _to_bnxt_re_nw_type(ib_ntype);
ah_info->nw_type = ntype;
@@ -2584,11 +2560,10 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
struct bnxt_qplib_ppp *ppp = NULL;
struct bnxt_re_dev *rdev;
struct bnxt_re_qp *qp;
- struct ib_gid_attr *sgid_attr;
- struct ib_gid_attr gid_attr;
- union ib_gid sgid, *gid_ptr = NULL;
+ const struct ib_gid_attr *sgid_attr;
+ const union ib_gid *gid_ptr = NULL;
u8 nw_type;
- int rc, entries, status;
+ int rc, entries;
bool is_copy_to_udata = false;
bool is_qpmtu_high = false;
@@ -2671,18 +2646,12 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
qp->qplib_qp.ah.traffic_class = grh->traffic_class;
qp->qplib_qp.ah.sl = rdma_ah_get_sl(&qp_attr->ah_attr);
ether_addr_copy(qp->qplib_qp.ah.dmac, ROCE_DMAC(&qp_attr->ah_attr));
- sgid_attr = &gid_attr;
- status = bnxt_re_get_cached_gid(&rdev->ibdev, 1,
- grh->sgid_index,
- &sgid, &sgid_attr,
- grh, NULL);
- if (!status)
- if_rele(sgid_attr->ndev);
- gid_ptr = &sgid;
+ sgid_attr = grh->sgid_attr;
+ gid_ptr = &sgid_attr->gid;
if (sgid_attr->ndev) {
memcpy(qp->qplib_qp.smac, rdev->dev_addr,
ETH_ALEN);
- nw_type = bnxt_re_gid_to_network_type(sgid_attr, &sgid);
+ nw_type = rdma_gid_attr_network_type(sgid_attr);
dev_dbg(rdev_to_dev(rdev),
"Connection using the nw_type %d\n", nw_type);
switch (nw_type) {
diff --git a/sys/dev/bnxt/bnxt_re/ib_verbs.h b/sys/dev/bnxt/bnxt_re/ib_verbs.h
index 4158aabb8fef..1ca8610b6332 100644
--- a/sys/dev/bnxt/bnxt_re/ib_verbs.h
+++ b/sys/dev/bnxt/bnxt_re/ib_verbs.h
@@ -296,8 +296,7 @@ void bnxt_re_compat_qfwstr(void);
int bnxt_re_query_pkey(struct ib_device *ibdev, u8 port_num,
u16 index, u16 *pkey);
int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context);
-int bnxt_re_add_gid(const union ib_gid *gid,
- const struct ib_gid_attr *attr, void **context);
+int bnxt_re_add_gid(const struct ib_gid_attr *attr, void **context);
int bnxt_re_query_gid(struct ib_device *ibdev, u8 port_num,
int index, union ib_gid *gid);
enum rdma_link_layer bnxt_re_get_link_layer(struct ib_device *ibdev,
diff --git a/sys/dev/irdma/fbsd_kcompat.h b/sys/dev/irdma/fbsd_kcompat.h
index 8f9d7f86e481..8050d528a9c0 100644
--- a/sys/dev/irdma/fbsd_kcompat.h
+++ b/sys/dev/irdma/fbsd_kcompat.h
@@ -253,8 +253,7 @@ int irdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata);
void irdma_dealloc_ucontext(struct ib_ucontext *context);
int irdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
void irdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
-int irdma_add_gid(const union ib_gid *,
- const struct ib_gid_attr *, void **);
+int irdma_add_gid(const struct ib_gid_attr *, void **);
int irdma_del_gid(const struct ib_gid_attr *, void **);
struct ib_device *ib_device_get_by_netdev(struct ifnet *ndev, int driver_id);
void ib_device_put(struct ib_device *device);
diff --git a/sys/dev/irdma/irdma_kcompat.c b/sys/dev/irdma/irdma_kcompat.c
index 4472c61dd0e0..03ddae317d58 100644
--- a/sys/dev/irdma/irdma_kcompat.c
+++ b/sys/dev/irdma/irdma_kcompat.c
@@ -77,8 +77,7 @@ irdma_get_dev_fw_str(struct ib_device *dev,
}
int
-irdma_add_gid(const union ib_gid *gid,
- const struct ib_gid_attr *attr,
+irdma_add_gid(const struct ib_gid_attr *attr,
void **context)
{
return 0;
@@ -528,8 +527,8 @@ irdma_create_sleepable_ah(struct ib_ah *ib_ah,
struct irdma_pd *pd = to_iwpd(ib_ah->pd);
struct irdma_ah *ah = container_of(ib_ah, struct irdma_ah, ibah);
struct irdma_device *iwdev = to_iwdev(ib_ah->pd->device);
- union ib_gid sgid;
- struct ib_gid_attr sgid_attr;
+ const union ib_gid *sgid;
+ const struct ib_gid_attr *sgid_attr;
struct irdma_pci_f *rf = iwdev->rf;
struct irdma_sc_ah *sc_ah;
u32 ah_id = 0;
@@ -556,24 +555,12 @@ irdma_create_sleepable_ah(struct ib_ah *ib_ah,
irdma_sc_init_ah(&rf->sc_dev, sc_ah);
ah->sgid_index = attr->grh.sgid_index;
memcpy(&ah->dgid, &attr->grh.dgid, sizeof(ah->dgid));
- rcu_read_lock();
- err = ib_get_cached_gid(&iwdev->ibdev, attr->port_num,
- attr->grh.sgid_index, &sgid, &sgid_attr);
- rcu_read_unlock();
- if (err) {
- irdma_debug(&iwdev->rf->sc_dev, IRDMA_DEBUG_VERBS,
- "GID lookup at idx=%d with port=%d failed\n",
- attr->grh.sgid_index, attr->port_num);
- err = -EINVAL;
- goto err_gid_l2;
- }
- rdma_gid2ip((struct sockaddr *)&sgid_addr, &sgid);
+ sgid_attr = attr->grh.sgid_attr;
+ sgid = &sgid_attr->gid;
+ rdma_gid2ip((struct sockaddr *)&sgid_addr, sgid);
rdma_gid2ip((struct sockaddr *)&dgid_addr, &attr->grh.dgid);
ah->av.attrs = *attr;
- ah->av.net_type = ib_gid_to_network_type(sgid_attr.gid_type, &sgid);
-
- if (sgid_attr.ndev)
- dev_put(sgid_attr.ndev);
+ ah->av.net_type = rdma_gid_attr_network_type(sgid_attr);
ah_info = &sc_ah->ah_info;
ah_info->ah_idx = ah_id;
@@ -588,10 +575,10 @@ irdma_create_sleepable_ah(struct ib_ah *ib_ah,
ether_addr_copy(dmac, attr->roce.dmac);
- irdma_fill_ah_info(if_getvnet(iwdev->netdev), ah_info, &sgid_attr, &sgid_addr, &dgid_addr,
+ irdma_fill_ah_info(if_getvnet(iwdev->netdev), ah_info, sgid_attr, &sgid_addr, &dgid_addr,
dmac, ah->av.net_type);
- err = irdma_create_ah_vlan_tag(iwdev, pd, ah_info, &sgid_attr, dmac);
+ err = irdma_create_ah_vlan_tag(iwdev, pd, ah_info, sgid_attr, dmac);
if (err)
goto err_gid_l2;
@@ -1393,27 +1380,19 @@ int
kc_irdma_set_roce_cm_info(struct irdma_qp *iwqp, struct ib_qp_attr *attr,
u16 *vlan_id)
{
- int ret;
- union ib_gid sgid;
- struct ib_gid_attr sgid_attr;
+ const struct ib_gid_attr *sgid_attr;
struct irdma_av *av = &iwqp->roce_ah.av;
const struct ib_global_route *grh = rdma_ah_read_grh(&attr->ah_attr);
- ret = ib_get_cached_gid(iwqp->ibqp.device,
- rdma_ah_get_port_num(&attr->ah_attr),
- grh->sgid_index, &sgid,
- &sgid_attr);
- if (ret)
- return ret;
+ sgid_attr = grh->sgid_attr;
- if (sgid_attr.ndev) {
- *vlan_id = rdma_vlan_dev_vlan_id(sgid_attr.ndev);
- ether_addr_copy(iwqp->ctx_info.roce_info->mac_addr, if_getlladdr(sgid_attr.ndev));
+ if (sgid_attr->ndev) {
+ *vlan_id = rdma_vlan_dev_vlan_id(sgid_attr->ndev);
+ ether_addr_copy(iwqp->ctx_info.roce_info->mac_addr, if_getlladdr(sgid_attr->ndev));
}
- av->net_type = ib_gid_to_network_type(sgid_attr.gid_type, &sgid);
- rdma_gid2ip((struct sockaddr *)&av->sgid_addr, &sgid);
- dev_put(sgid_attr.ndev);
+ av->net_type = rdma_gid_attr_network_type(sgid_attr);
+ rdma_gid2ip((struct sockaddr *)&av->sgid_addr, &sgid_attr->gid);
iwqp->sc_qp.user_pri = iwqp->ctx_info.user_pri;
return 0;
diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib.h b/sys/dev/mlx4/mlx4_ib/mlx4_ib.h
index 9a5306ca1a30..86ac63f7c78e 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib.h
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib.h
@@ -882,7 +882,7 @@ int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags,
int mr_access_flags, struct ib_pd *pd,
struct ib_udata *udata);
int mlx4_ib_gid_index_to_real_index(struct mlx4_ib_dev *ibdev,
- u8 port_num, int index);
+ const struct ib_gid_attr *attr);
void mlx4_sched_ib_sl2vl_update_work(struct mlx4_ib_dev *ibdev,
int port);
diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_ah.c b/sys/dev/mlx4/mlx4_ib/mlx4_ib_ah.c
index e31c223c27e6..babdd234e45b 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_ah.c
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_ah.c
@@ -79,14 +79,13 @@ static int create_iboe_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr)
{
struct ib_pd *pd = ib_ah->pd;
struct mlx4_ib_dev *ibdev = to_mdev(ib_ah->device);
+ const struct ib_gid_attr *gid_attr;
struct mlx4_ib_ah *ah = to_mah(ib_ah);
struct mlx4_dev *dev = ibdev->dev;
const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
int is_mcast = 0;
struct in6_addr in6;
u16 vlan_tag = 0xffff;
- union ib_gid sgid;
- struct ib_gid_attr gid_attr;
int ret;
memcpy(&in6, grh->dgid.raw, sizeof(in6));
@@ -94,22 +93,16 @@ static int create_iboe_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr)
is_mcast = 1;
memcpy(ah->av.eth.mac, ah_attr->roce.dmac, ETH_ALEN);
- ret = ib_get_cached_gid(pd->device, rdma_ah_get_port_num(ah_attr),
- grh->sgid_index, &sgid, &gid_attr);
- if (ret)
- return ret;
eth_zero_addr(ah->av.eth.s_mac);
- if (gid_attr.ndev) {
- vlan_tag = rdma_vlan_dev_vlan_id(gid_attr.ndev);
- memcpy(ah->av.eth.s_mac, if_getlladdr(gid_attr.ndev), ETH_ALEN);
- if_rele(gid_attr.ndev);
- }
+ gid_attr = ah_attr->grh.sgid_attr;
+ vlan_tag = rdma_vlan_dev_vlan_id(gid_attr->ndev);
+ memcpy(ah->av.eth.s_mac, if_getlladdr(gid_attr->ndev), ETH_ALEN);
+
if (vlan_tag < 0x1000)
vlan_tag |= (rdma_ah_get_sl(ah_attr) & 7) << 13;
ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn |
(rdma_ah_get_port_num(ah_attr) << 24));
- ret = mlx4_ib_gid_index_to_real_index(ibdev,
- rdma_ah_get_port_num(ah_attr), grh->sgid_index);
+ ret = mlx4_ib_gid_index_to_real_index(ibdev, gid_attr);
if (ret < 0)
return ret;
ah->av.eth.gid_index = ret;
diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c b/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
index 83b2f9da6bee..129fdd2eabb9 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
@@ -252,9 +252,7 @@ static int mlx4_ib_update_gids(struct gid_entry *gids,
return mlx4_ib_update_gids_v1(gids, ibdev, port_num);
}
-static int mlx4_ib_add_gid(const union ib_gid *gid,
- const struct ib_gid_attr *attr,
- void **context)
+static int mlx4_ib_add_gid(const struct ib_gid_attr *attr, void **context)
{
struct mlx4_ib_dev *ibdev = to_mdev(attr->device);
struct mlx4_ib_iboe *iboe = &ibdev->iboe;
@@ -277,7 +275,8 @@ static int mlx4_ib_add_gid(const union ib_gid *gid,
port_gid_table = &iboe->gids[attr->port_num - 1];
spin_lock_bh(&iboe->lock);
for (i = 0; i < MLX4_MAX_PORT_GIDS; ++i) {
- if (!memcmp(&port_gid_table->gids[i].gid, gid, sizeof(*gid)) &&
+ if (!memcmp(&port_gid_table->gids[i].gid,
+ &attr->gid, sizeof(attr->gid)) &&
(port_gid_table->gids[i].gid_type == attr->gid_type)) {
found = i;
break;
@@ -295,7 +294,8 @@ static int mlx4_ib_add_gid(const union ib_gid *gid,
ret = -ENOMEM;
} else {
*context = port_gid_table->gids[free].ctx;
- memcpy(&port_gid_table->gids[free].gid, gid, sizeof(*gid));
+ memcpy(&port_gid_table->gids[free].gid,
+ &attr->gid, sizeof(attr->gid));
port_gid_table->gids[free].gid_type = attr->gid_type;
port_gid_table->gids[free].ctx->real_index = free;
port_gid_table->gids[free].ctx->refcount = 1;
@@ -386,17 +386,15 @@ static int mlx4_ib_del_gid(const struct ib_gid_attr *attr, void **context)
}
int mlx4_ib_gid_index_to_real_index(struct mlx4_ib_dev *ibdev,
- u8 port_num, int index)
+ const struct ib_gid_attr *attr)
{
struct mlx4_ib_iboe *iboe = &ibdev->iboe;
struct gid_cache_context *ctx = NULL;
- union ib_gid gid;
struct mlx4_port_gid_table *port_gid_table;
int real_index = -EINVAL;
int i;
- int ret;
unsigned long flags;
- struct ib_gid_attr attr;
+ u8 port_num = attr->port_num;
if (port_num > MLX4_MAX_PORTS)
return -EINVAL;
@@ -405,21 +403,15 @@ int mlx4_ib_gid_index_to_real_index(struct mlx4_ib_dev *ibdev,
port_num = 1;
if (!rdma_cap_roce_gid_table(&ibdev->ib_dev, port_num))
- return index;
-
- ret = ib_get_cached_gid(&ibdev->ib_dev, port_num, index, &gid, &attr);
- if (ret)
- return ret;
-
- if (attr.ndev)
- if_rele(attr.ndev);
+ return attr->index;
spin_lock_irqsave(&iboe->lock, flags);
port_gid_table = &iboe->gids[port_num - 1];
for (i = 0; i < MLX4_MAX_PORT_GIDS; ++i)
- if (!memcmp(&port_gid_table->gids[i].gid, &gid, sizeof(gid)) &&
- attr.gid_type == port_gid_table->gids[i].gid_type) {
+ if (!memcmp(&port_gid_table->gids[i].gid,
+ &attr->gid, sizeof(attr->gid)) &&
+ attr->gid_type == port_gid_table->gids[i].gid_type) {
ctx = port_gid_table->gids[i].ctx;
break;
}
diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c b/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c
index beb954c93dca..fb98bdcd48f9 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c
@@ -1412,9 +1412,8 @@ static int _mlx4_set_path(struct mlx4_ib_dev *dev, const struct rdma_ah_attr *ah
if (rdma_ah_get_ah_flags(ah) & IB_AH_GRH) {
const struct ib_global_route *grh = rdma_ah_read_grh(ah);
- int real_sgid_index = mlx4_ib_gid_index_to_real_index(dev,
- port,
- grh->sgid_index);
+ int real_sgid_index =
+ mlx4_ib_gid_index_to_real_index(dev, grh->sgid_attr);
if (real_sgid_index < 0)
return real_sgid_index;
@@ -1627,6 +1626,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
enum ib_qp_state new_state,
struct ib_udata *udata)
{
+ const struct ib_gid_attr *gid_attr = NULL;
struct mlx4_ib_dev *dev = to_mdev(ibqp->device);
struct mlx4_ib_qp *qp = to_mqp(ibqp);
struct mlx4_ib_pd *pd;
@@ -1773,28 +1773,16 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
if (attr_mask & IB_QP_AV) {
u8 port_num = mlx4_is_bonded(to_mdev(ibqp->device)->dev) ? 1 :
attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
- union ib_gid gid;
- struct ib_gid_attr gid_attr;
u16 vlan = 0xffff;
u8 smac[ETH_ALEN];
- int status = 0;
int is_eth = rdma_cap_eth_ah(&dev->ib_dev, port_num) &&
rdma_ah_get_ah_flags(&attr->ah_attr) & IB_AH_GRH;
if (is_eth) {
- int index =
- rdma_ah_read_grh(&attr->ah_attr)->sgid_index;
-
- status = ib_get_cached_gid(ibqp->device, port_num,
- index, &gid, &gid_attr);
- if (!status && gid_attr.ndev) {
- vlan = rdma_vlan_dev_vlan_id(gid_attr.ndev);
- memcpy(smac, if_getlladdr(gid_attr.ndev), ETH_ALEN);
- if_rele(gid_attr.ndev);
- }
+ gid_attr = attr->ah_attr.grh.sgid_attr;
+ vlan = rdma_vlan_dev_vlan_id(gid_attr->ndev);
+ memcpy(smac, if_getlladdr(gid_attr->ndev), ETH_ALEN);
}
- if (status)
- goto out;
if (mlx4_set_path(dev, attr, attr_mask, qp, &context->pri_path,
port_num, vlan, smac))
@@ -1805,7 +1793,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
if (is_eth &&
(cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR)) {
- u8 qpc_roce_mode = gid_type_to_qpc(gid_attr.gid_type);
+ u8 qpc_roce_mode = gid_type_to_qpc(gid_attr->gid_type);
if (qpc_roce_mode == MLX4_QPC_ROCE_MODE_UNDEFINED) {
err = -EINVAL;
@@ -2538,10 +2526,8 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, const struct ib_ud_wr *wr,
to_mdev(ib_dev)->sriov.demux[sqp->qp.port - 1].
guid_cache[ah->av.ib.gid_index];
} else {
- ib_get_cached_gid(ib_dev,
- be32_to_cpu(ah->av.ib.port_pd) >> 24,
- ah->av.ib.gid_index,
- &sqp->ud_header.grh.source_gid, NULL);
+ sqp->ud_header.grh.source_gid =
+ ah->ibah.sgid_attr->gid;
}
}
memcpy(sqp->ud_header.grh.destination_gid.raw,
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib.h b/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
index 1cb6cb9d3b48..a97d74864292 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
@@ -1050,10 +1050,8 @@ int mlx5_ib_get_vf_stats(struct ib_device *device, int vf,
int mlx5_ib_set_vf_guid(struct ib_device *device, int vf, u8 port,
u64 guid, int type);
-__be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num,
- int index);
-int mlx5_get_roce_gid_type(struct mlx5_ib_dev *dev, u8 port_num,
- int index, enum ib_gid_type *gid_type);
+__be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev,
+ const struct ib_gid_attr *attr);
/* GSI QP helper functions */
struct ib_qp *mlx5_ib_gsi_create_qp(struct ib_pd *pd,
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_ah.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_ah.c
index 7439ec3fa4ea..046d99c894b9 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_ah.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_ah.c
@@ -49,9 +49,7 @@ static void create_ib_ah(struct mlx5_ib_dev *dev,
memcpy(ah->av.rmac, ah_attr->roce.dmac,
sizeof(ah_attr->roce.dmac));
ah->av.udp_sport =
- mlx5_get_roce_udp_sport(dev,
- rdma_ah_get_port_num(ah_attr),
- rdma_ah_read_grh(ah_attr)->sgid_index);
+ mlx5_get_roce_udp_sport(dev, ah_attr->grh.sgid_attr);
ah->av.stat_rate_sl |= (rdma_ah_get_sl(ah_attr) & 0x7) << 1;
} else {
ah->av.rlid = cpu_to_be16(rdma_ah_get_dlid(ah_attr));
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c
index 81beadd263f7..28fcc7b648e5 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c
@@ -1099,7 +1099,7 @@ int mlx5_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
int err;
if (!MLX5_CAP_GEN(dev->mdev, cq_moderation))
- return -ENOSYS;
+ return -EOPNOTSUPP;
err = mlx5_core_modify_cq_moderation(dev->mdev, &mcq->mcq,
cq_period, cq_count);
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
index a1159f91829d..90b886d635f1 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
@@ -428,12 +428,11 @@ static int set_roce_addr(struct ib_device *device, u8 port_num,
return mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
}
-static int mlx5_ib_add_gid(const union ib_gid *gid,
- const struct ib_gid_attr *attr,
+static int mlx5_ib_add_gid(const struct ib_gid_attr *attr,
__always_unused void **context)
{
- return set_roce_addr(attr->device, attr->port_num, attr->index, gid,
- attr);
+ return set_roce_addr(attr->device, attr->port_num, attr->index,
+ &attr->gid, attr);
}
static int mlx5_ib_del_gid(const struct ib_gid_attr *attr,
@@ -443,47 +442,15 @@ static int mlx5_ib_del_gid(const struct ib_gid_attr *attr,
NULL);
}
-__be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num,
- int index)
+__be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev,
+ const struct ib_gid_attr *attr)
{
- struct ib_gid_attr attr;
- union ib_gid gid;
-
- if (ib_get_cached_gid(&dev->ib_dev, port_num, index, &gid, &attr))
- return 0;
-
- if (!attr.ndev)
- return 0;
-
- if_rele(attr.ndev);
-
- if (attr.gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
+ if (attr->gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
return 0;
return cpu_to_be16(MLX5_CAP_ROCE(dev->mdev, r_roce_min_src_udp_port));
}
-int mlx5_get_roce_gid_type(struct mlx5_ib_dev *dev, u8 port_num,
- int index, enum ib_gid_type *gid_type)
-{
- struct ib_gid_attr attr;
- union ib_gid gid;
- int ret;
-
- ret = ib_get_cached_gid(&dev->ib_dev, port_num, index, &gid, &attr);
- if (ret)
- return ret;
-
- if (!attr.ndev)
- return -ENODEV;
-
- if_rele(attr.ndev);
-
- *gid_type = attr.gid_type;
-
- return 0;
-}
-
static int mlx5_use_mad_ifc(struct mlx5_ib_dev *dev)
{
if (MLX5_CAP_GEN(dev->mdev, port_type) == MLX5_CAP_PORT_TYPE_IB)
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c
index 0c891ed4a012..c2a7f42237ad 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c
@@ -2350,14 +2350,12 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
if (ah->type == RDMA_AH_ATTR_TYPE_ROCE) {
if (!(ah_flags & IB_AH_GRH))
return -EINVAL;
- err = mlx5_get_roce_gid_type(dev, port, grh->sgid_index,
- &gid_type);
- if (err)
- return err;
+
memcpy(path->rmac, ah->roce.dmac, sizeof(ah->roce.dmac));
- path->udp_sport = mlx5_get_roce_udp_sport(dev, port,
- grh->sgid_index);
+ path->udp_sport =
+ mlx5_get_roce_udp_sport(dev, ah->grh.sgid_attr);
path->dci_cfi_prio_sl = (sl & 0x7) << 4;
+ gid_type = ah->grh.sgid_attr->gid_type;
if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
path->ecn_dscp = (grh->traffic_class >> 2) & 0x3f;
} else {
diff --git a/sys/dev/mthca/mthca_av.c b/sys/dev/mthca/mthca_av.c
index e22bdac288b3..0c0c976415ef 100644
--- a/sys/dev/mthca/mthca_av.c
+++ b/sys/dev/mthca/mthca_av.c
@@ -283,10 +283,7 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
header->grh.flow_label =
ah->av->sl_tclass_flowlabel & cpu_to_be32(0xfffff);
header->grh.hop_limit = ah->av->hop_limit;
- ib_get_cached_gid(&dev->ib_dev,
- be32_to_cpu(ah->av->port_pd) >> 24,
- ah->av->gid_index % dev->limits.gid_table_len,
- &header->grh.source_gid, NULL);
+ header->grh.source_gid = ah->ibah.sgid_attr->gid;
memcpy(header->grh.destination_gid.raw,
ah->av->dgid, 16);
}
diff --git a/sys/dev/qlnx/qlnxr/qlnxr_cm.c b/sys/dev/qlnx/qlnxr/qlnxr_cm.c
index a00d51cb6451..ab586d5e6200 100644
--- a/sys/dev/qlnx/qlnxr/qlnxr_cm.c
+++ b/sys/dev/qlnx/qlnxr/qlnxr_cm.c
@@ -487,7 +487,7 @@ qlnxr_gsi_build_header(struct qlnxr_dev *dev,
bool has_vlan = false, has_grh_ipv6 = true;
struct rdma_ah_attr *ah_attr = &get_qlnxr_ah((ud_wr(swr)->ah))->attr;
const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
- union ib_gid sgid;
+ const struct ib_gid_attr *sgid_attr = grh->sgid_attr;
int send_size = 0;
u16 vlan_id = 0;
u16 ether_type;
@@ -505,10 +505,6 @@ qlnxr_gsi_build_header(struct qlnxr_dev *dev,
has_vlan = qlnxr_get_vlan_id_gsi(ah_attr, &vlan_id);
ether_type = ETH_P_ROCE;
*roce_mode = ROCE_V1;
- if (grh->sgid_index < QLNXR_MAX_SGID)
- sgid = dev->sgid_tbl[grh->sgid_index];
- else
- sgid = dev->sgid_tbl[0];
rc = ib_ud_header_init(send_size, false /* LRH */, true /* ETH */,
has_vlan, has_grh_ipv6, ip_ver, has_udp,
@@ -550,7 +546,7 @@ qlnxr_gsi_build_header(struct qlnxr_dev *dev,
udh->grh.flow_label = grh->flow_label;
udh->grh.hop_limit = grh->hop_limit;
udh->grh.destination_gid = grh->dgid;
- memcpy(&udh->grh.source_gid.raw, &sgid.raw,
+ memcpy(&udh->grh.source_gid.raw, sgid_attr->gid.raw,
sizeof(udh->grh.source_gid.raw));
QL_DPRINT12(dev->ha, "header: tc: %x, flow_label : %x, "
"hop_limit: %x \n", udh->grh.traffic_class,
@@ -574,7 +570,7 @@ qlnxr_gsi_build_header(struct qlnxr_dev *dev,
udh->ip4.frag_off = htons(IP_DF);
udh->ip4.ttl = grh->hop_limit;
- ipv4_addr = qedr_get_ipv4_from_gid(sgid.raw);
+ ipv4_addr = qedr_get_ipv4_from_gid(sgid_attr->gid.raw);
udh->ip4.saddr = ipv4_addr;
ipv4_addr = qedr_get_ipv4_from_gid(grh->dgid.raw);
udh->ip4.daddr = ipv4_addr;
diff --git a/sys/dev/qlnx/qlnxr/qlnxr_verbs.c b/sys/dev/qlnx/qlnxr/qlnxr_verbs.c
index a0d95e312cd3..564ab9607801 100644
--- a/sys/dev/qlnx/qlnxr/qlnxr_verbs.c
+++ b/sys/dev/qlnx/qlnxr/qlnxr_verbs.c
@@ -5499,7 +5499,7 @@ qlnxr_create_ah(struct ib_ah *ibah,
QL_DPRINT12(ha, "in create_ah\n");
- ah->attr = *attr;
+ rdma_copy_ah_attr(&ah->attr, attr);
return (0);
}
@@ -5507,6 +5507,9 @@ qlnxr_create_ah(struct ib_ah *ibah,
void
qlnxr_destroy_ah(struct ib_ah *ibah, u32 flags)
{
+ struct qlnxr_ah *ah = get_qlnxr_ah(ibah);
+
+ rdma_destroy_ah_attr(&ah->attr);
}
int
diff --git a/sys/ofed/drivers/infiniband/core/core_priv.h b/sys/ofed/drivers/infiniband/core/core_priv.h
index 3a61defb540b..198dac54cdf0 100644
--- a/sys/ofed/drivers/infiniband/core/core_priv.h
+++ b/sys/ofed/drivers/infiniband/core/core_priv.h
@@ -86,8 +86,8 @@ void ib_cache_cleanup(void);
typedef void (*roce_netdev_callback)(struct ib_device *device, u8 port,
if_t idev, void *cookie);
-typedef int (*roce_netdev_filter)(struct ib_device *device, u8 port,
- if_t idev, void *cookie);
+typedef bool (*roce_netdev_filter)(struct ib_device *device, u8 port,
+ if_t idev, void *cookie);
void ib_enum_roce_netdev(struct ib_device *ib_dev,
roce_netdev_filter filter,
diff --git a/sys/ofed/drivers/infiniband/core/ib_addr.c b/sys/ofed/drivers/infiniband/core/ib_addr.c
index 893fd0bb2b37..1810230c34f5 100644
--- a/sys/ofed/drivers/infiniband/core/ib_addr.c
+++ b/sys/ofed/drivers/infiniband/core/ib_addr.c
@@ -73,7 +73,7 @@ static DEFINE_SPINLOCK(lock);
static LIST_HEAD(req_list);
static struct workqueue_struct *addr_wq;
-int rdma_addr_size(struct sockaddr *addr)
+int rdma_addr_size(const struct sockaddr *addr)
{
switch (addr->sa_family) {
case AF_INET:
@@ -716,7 +716,7 @@ static void process_one_req(struct work_struct *_work)
spin_unlock_bh(&lock);
}
-int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
+int rdma_resolve_ip(struct sockaddr *src_addr, const struct sockaddr *dst_addr,
struct rdma_dev_addr *addr, int timeout_ms,
void (*callback)(int status, struct sockaddr *src_addr,
struct rdma_dev_addr *addr, void *context),
diff --git a/sys/ofed/drivers/infiniband/core/ib_cache.c b/sys/ofed/drivers/infiniband/core/ib_cache.c
index c0c40b2e92c0..7bf3213140ff 100644
--- a/sys/ofed/drivers/infiniband/core/ib_cache.c
+++ b/sys/ofed/drivers/infiniband/core/ib_cache.c
@@ -69,20 +69,28 @@ enum gid_attr_find_mask {
GID_ATTR_FIND_MASK_GID_TYPE = 1UL << 3,
};
-enum gid_table_entry_props {
- GID_TABLE_ENTRY_INVALID = 1UL << 0,
- GID_TABLE_ENTRY_DEFAULT = 1UL << 1,
+enum gid_table_entry_state {
+ GID_TABLE_ENTRY_INVALID = 1,
+ GID_TABLE_ENTRY_VALID = 2,
+ /*
+ * Indicates that entry is pending to be removed, there may
+ * be active users of this GID entry.
+ * When last user of the GID entry releases reference to it,
+ * GID entry is detached from the table.
+ */
+ GID_TABLE_ENTRY_PENDING_DEL = 3,
};
struct ib_gid_table_entry {
- unsigned long props;
- union ib_gid gid;
- struct ib_gid_attr attr;
- void *context;
+ struct kref kref;
+ struct work_struct del_work;
+ struct ib_gid_attr attr;
+ void *context;
+ enum gid_table_entry_state state;
};
struct ib_gid_table {
- int sz;
+ int sz;
/* In RoCE, adding a GID to the table requires:
* (a) Find if this GID is already exists.
* (b) Find a free space.
@@ -94,13 +102,16 @@ struct ib_gid_table {
*
**/
/* Any writer to data_vec must hold this lock and the write side of
- * rwlock. readers must hold only rwlock. All writers must be in a
+ * rwlock. Readers must hold only rwlock. All writers must be in a
* sleepable context.
*/
- struct mutex lock;
- /* rwlock protects data_vec[ix]->props. */
- rwlock_t rwlock;
- struct ib_gid_table_entry *data_vec;
+ struct mutex lock;
+ /* rwlock protects data_vec[ix]->state and entry pointer.
+ */
+ rwlock_t rwlock;
+ struct ib_gid_table_entry **data_vec;
+ /* bit field, each bit indicates the index of default GID */
+ u32 default_gid_indices;
};
static void dispatch_gid_change_event(struct ib_device *ib_dev, u8 port)
@@ -138,6 +149,19 @@ bool rdma_is_zero_gid(const union ib_gid *gid)
}
EXPORT_SYMBOL(rdma_is_zero_gid);
+/** is_gid_index_default - Check if a given index belongs to
+ * reserved default GIDs or not.
+ * @table: GID table pointer
+ * @index: Index to check in GID table
+ * Returns true if index is one of the reserved default GID index otherwise
+ * returns false.
+ */
+static bool is_gid_index_default(const struct ib_gid_table *table,
+ unsigned int index)
+{
+ return index < 32 && (BIT(index) & table->default_gid_indices);
+}
+
int ib_cache_gid_parse_type_str(const char *buf)
{
unsigned int i;
@@ -167,26 +191,136 @@ static struct ib_gid_table *rdma_gid_table(struct ib_device *device, u8 port)
return device->cache.ports[port - rdma_start_port(device)].gid;
}
-static void del_roce_gid(struct ib_device *device, u8 port_num,
- struct ib_gid_table *table, int ix)
+static bool is_gid_entry_free(const struct ib_gid_table_entry *entry)
+{
+ return !entry;
+}
+
+static bool is_gid_entry_valid(const struct ib_gid_table_entry *entry)
+{
+ return entry && entry->state == GID_TABLE_ENTRY_VALID;
+}
+
+static void schedule_free_gid(struct kref *kref)
{
+ struct ib_gid_table_entry *entry =
+ container_of(kref, struct ib_gid_table_entry, kref);
+
+ queue_work(ib_wq, &entry->del_work);
+}
+
+static void free_gid_entry_locked(struct ib_gid_table_entry *entry)
+{
+ struct ib_device *device = entry->attr.device;
+ u8 port_num = entry->attr.port_num;
+ struct ib_gid_table *table = rdma_gid_table(device, port_num);
+
pr_debug("%s device=%s port=%d index=%d gid %pI6\n", __func__,
- device->name, port_num, ix,
- table->data_vec[ix].gid.raw);
+ device->name, port_num, entry->attr.index,
+ entry->attr.gid.raw);
*** 4396 LINES SKIPPED ***