git: 75cde38e9493 - main - OFED: Various changes from Linux 4.17

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Wed, 24 Jun 2026 19:51:16 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=75cde38e949345c9d63e400bd4707d6eec817941

commit 75cde38e949345c9d63e400bd4707d6eec817941
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.17
    
    This contains changes from the following Linux commits:
    
    a3b641af72ba RDMA/CM: move rdma_id_private to cma_priv.h
    6612b4983f7e IB/core: Fix comments of GID query functions
    b26c4a1138df IB/{core, ipoib}: Simplify ib_find_gid() for unused ndev
    5ac08a341303 IB/cma: Use rdma_protocol_roce() and remove cma_protocol_roce_dev_port()
    a9c06aeba997 IB/core: Remove rdma_resolve_ip_route() as exported symbol
    a22af59ea9a5 IB/cm: Add and use a helper function to add cm_id's to the port list
    cb12a8e2fa5f IB/cm: Introduce and use helper function to get cm_port from path
    0a5141593567 IB/core: Refactor ib_init_ah_attr_from_path() for RoCE
    e41a7c41947d IB/core: Move rdma_addr_find_l2_eth_by_grh to core_priv.h
    98f1f4e0ed26 IB/core: Refer to RoCE port property instead of GID table property
    114cc9c4b182 IB/cma: Resolve route only while receiving CM requests
    9137108cc3d6 RDMA/rdma_cm: Fix use after free race with process_one_req
    190fb9c4d130 IB/core: Refer to RoCE port property to decide building cache
    22d24f75a193 IB/core: Search GID only for IB link layer
    4ab7cb4bf362 IB/core: Refer to RoCE port property instead of GID table property
    3401857ea347 IB/core: Generate GID change event regardless of RoCE GID table property
    218b9e3eb8b5 RDMA/cma: Move rdma_cm_state to cma_priv.h
    8435168d50e6 RDMA/ucma: Don't allow setting RDMA_OPTION_IB_PATH without an RDMA device
    72e1ff0fb7e0 RDMA/core: Update query_gid documentation for HCA drivers
    0e1f9b924471 RDMA/providers: Simplify query_gid callback of RoCE providers
    598ff6bae689 IB/core: Refactor GID modify code for RoCE
    f35faa4ba956 IB/core: Simplify ib_query_gid to always refer to cache
    14169e333e71 IB/providers: Avoid zero GID check for RoCE
    414448d249d8 RDMA: Use ib_gid_attr during GID modification
    ee6548d1d98d RDMA/rdma_cm: Delete rdma_addr_client
    44e75052bc2a RDMA/rdma_cm: Make rdma_addr_cancel into a fence
    e19c0d237873 RDMA/rdma_cm: Remove process_req and timer sorting
    a66ed149b0da IB/core: Don't allow default GID addition at non reseved slots
    dc5640f294e4 IB/core: Fix deleting default GIDs when changing mac adddress
    22c01ee4b8a8 IB/core: Fix to avoid deleting IPv6 look alike default GIDs
    9aa169213d11 RDMA/cma: Do not query GID during QP state transition to RTR
    aec05afe641b IB/core: Remove redundant return
    
    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                |  22 +-
 sys/dev/bnxt/bnxt_re/ib_verbs.h                |   6 +-
 sys/dev/bnxt/bnxt_re/main.c                    |   1 -
 sys/dev/irdma/fbsd_kcompat.h                   |   6 +-
 sys/dev/irdma/irdma_kcompat.c                  |  31 +-
 sys/dev/irdma/irdma_verbs.c                    |   1 -
 sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c            |  49 +--
 sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c              |   2 -
 sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c            |  13 +-
 sys/dev/qlnx/qlnxr/qlnxr_os.c                  |   1 -
 sys/dev/qlnx/qlnxr/qlnxr_verbs.c               |  38 --
 sys/dev/qlnx/qlnxr/qlnxr_verbs.h               |   5 -
 sys/ofed/drivers/infiniband/core/cma_priv.h    |  95 +++++
 sys/ofed/drivers/infiniband/core/core_priv.h   |  10 +
 sys/ofed/drivers/infiniband/core/ib_addr.c     | 148 +++----
 sys/ofed/drivers/infiniband/core/ib_cache.c    | 529 ++++++++++++++-----------
 sys/ofed/drivers/infiniband/core/ib_cm.c       |  53 ++-
 sys/ofed/drivers/infiniband/core/ib_cma.c      |  77 +---
 sys/ofed/drivers/infiniband/core/ib_device.c   |  18 +-
 sys/ofed/drivers/infiniband/core/ib_sa_query.c | 192 ++++-----
 sys/ofed/drivers/infiniband/core/ib_sysfs.c    |  16 +-
 sys/ofed/drivers/infiniband/core/ib_ucma.c     |   3 +
 sys/ofed/drivers/infiniband/core/ib_umem.c     |   2 -
 sys/ofed/include/rdma/ib_addr.h                |  29 +-
 sys/ofed/include/rdma/ib_cache.h               |  29 --
 sys/ofed/include/rdma/ib_sa.h                  |  13 +
 sys/ofed/include/rdma/ib_verbs.h               |  44 +-
 sys/ofed/include/rdma/rdma_cm.h                |  14 -
 28 files changed, 696 insertions(+), 751 deletions(-)

diff --git a/sys/dev/bnxt/bnxt_re/ib_verbs.c b/sys/dev/bnxt/bnxt_re/ib_verbs.c
index eacd5c1abab5..516d0bb8cddf 100644
--- a/sys/dev/bnxt/bnxt_re/ib_verbs.c
+++ b/sys/dev/bnxt/bnxt_re/ib_verbs.c
@@ -443,12 +443,11 @@ int bnxt_re_query_gid(struct ib_device *ibdev, u8 port_num,
 	return rc;
 }
 
-int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num,
-		    unsigned int index, void **context)
+int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context)
 {
 	int rc = 0;
 	struct bnxt_re_gid_ctx *ctx, **ctx_tbl;
-	struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
+	struct bnxt_re_dev *rdev = to_bnxt_re_dev(attr->device, ibdev);
 	struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl;
 	struct bnxt_qplib_gid *gid_to_del;
 	u16 vlan_id = 0xFFFF;
@@ -482,14 +481,14 @@ int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num,
 			dev_dbg(rdev_to_dev(rdev),
 				"Trying to delete GID0 while QP1 is alive\n");
 			if (!ctx->refcnt) {
-				rdev->gid_map[index] = -1;
+				rdev->gid_map[attr->index] = -1;
 				ctx_tbl = sgid_tbl->ctx;
 				ctx_tbl[ctx->idx] = NULL;
 				kfree(ctx);
 			}
 			return 0;
 		}
-		rdev->gid_map[index] = -1;
+		rdev->gid_map[attr->index] = -1;
 		if (!ctx->refcnt) {
 			rc = bnxt_qplib_del_sgid(sgid_tbl, gid_to_del,
 						 vlan_id, true);
@@ -510,15 +509,14 @@ int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num,
 	return rc;
 }
 
-int bnxt_re_add_gid(struct ib_device *ibdev, u8 port_num,
-		    unsigned int index, const union ib_gid *gid,
+int bnxt_re_add_gid(const union ib_gid *gid,
 		    const struct ib_gid_attr *attr, void **context)
 {
 	int rc;
 	u32 tbl_idx = 0;
 	u16 vlan_id = 0xFFFF;
 	struct bnxt_re_gid_ctx *ctx, **ctx_tbl;
-	struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
+	struct bnxt_re_dev *rdev = to_bnxt_re_dev(attr->device, ibdev);
 	struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl;
 	if ((attr->ndev) && is_vlan_dev(attr->ndev))
 		vlan_id = vlan_dev_vlan_id(attr->ndev);
@@ -540,8 +538,8 @@ int bnxt_re_add_gid(struct ib_device *ibdev, u8 port_num,
 			ctx_tbl[tbl_idx]->refcnt++;
 		}
 		*context = ctx_tbl[tbl_idx];
-		/* tbl_idx is the HW table index and index is the stack index */
-		rdev->gid_map[index] = tbl_idx;
+		/* tbl_idx is the HW table index and attr->index is the stack index */
+		rdev->gid_map[attr->index] = tbl_idx;
 		return 0;
 	} else if (rc < 0) {
 		dev_err(rdev_to_dev(rdev), "Add GID failed rc = 0x%x\n", rc);
@@ -556,8 +554,8 @@ int bnxt_re_add_gid(struct ib_device *ibdev, u8 port_num,
 		ctx->idx = tbl_idx;
 		ctx->refcnt = 1;
 		ctx_tbl[tbl_idx] = ctx;
-		/* tbl_idx is the HW table index and index is the stack index */
-		rdev->gid_map[index] = tbl_idx;
+		/* tbl_idx is the HW table index and attr->index is the stack index */
+		rdev->gid_map[attr->index] = tbl_idx;
 		*context = ctx;
 	}
 	return rc;
diff --git a/sys/dev/bnxt/bnxt_re/ib_verbs.h b/sys/dev/bnxt/bnxt_re/ib_verbs.h
index 332c88e07a3d..4158aabb8fef 100644
--- a/sys/dev/bnxt/bnxt_re/ib_verbs.h
+++ b/sys/dev/bnxt/bnxt_re/ib_verbs.h
@@ -295,10 +295,8 @@ int bnxt_re_get_port_immutable(struct ib_device *ibdev, u8 port_num,
 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(struct ib_device *ibdev, u8 port_num,
-		    unsigned int index, void **context);
-int bnxt_re_add_gid(struct ib_device *ibdev, u8 port_num,
-		    unsigned int index, const union ib_gid *gid,
+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_query_gid(struct ib_device *ibdev, u8 port_num,
 		      int index, union ib_gid *gid);
diff --git a/sys/dev/bnxt/bnxt_re/main.c b/sys/dev/bnxt/bnxt_re/main.c
index 991931bdd396..e6ec286006fa 100644
--- a/sys/dev/bnxt/bnxt_re/main.c
+++ b/sys/dev/bnxt/bnxt_re/main.c
@@ -2179,7 +2179,6 @@ static int bnxt_re_register_ib(struct bnxt_re_dev *rdev)
 	ibdev->modify_port		= bnxt_re_modify_port;
 	ibdev->get_port_immutable	= bnxt_re_get_port_immutable;
 	ibdev->query_pkey		= bnxt_re_query_pkey;
-	ibdev->query_gid		= bnxt_re_query_gid;
 	ibdev->get_netdev		= bnxt_re_get_netdev;
 	ibdev->add_gid			= bnxt_re_add_gid;
 	ibdev->del_gid			= bnxt_re_del_gid;
diff --git a/sys/dev/irdma/fbsd_kcompat.h b/sys/dev/irdma/fbsd_kcompat.h
index 8dcbbd8e5144..8f9d7f86e481 100644
--- a/sys/dev/irdma/fbsd_kcompat.h
+++ b/sys/dev/irdma/fbsd_kcompat.h
@@ -156,8 +156,6 @@ int irdma_iw_port_immutable(struct ib_device *ibdev, u8 port_num,
 			    struct ib_port_immutable *immutable);
 int irdma_query_gid(struct ib_device *ibdev, u8 port, int index,
 		    union ib_gid *gid);
-int irdma_query_gid_roce(struct ib_device *ibdev, u8 port, int index,
-			 union ib_gid *gid);
 int irdma_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
 		     u16 *pkey);
 int irdma_query_port(struct ib_device *ibdev, u8 port,
@@ -255,9 +253,9 @@ 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(struct ib_device *, u8, unsigned int, const union ib_gid *,
+int irdma_add_gid(const union ib_gid *,
 		  const struct ib_gid_attr *, void **);
-int irdma_del_gid(struct ib_device *, u8, unsigned int, 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);
 void ib_unregister_device_put(struct ib_device *device);
diff --git a/sys/dev/irdma/irdma_kcompat.c b/sys/dev/irdma/irdma_kcompat.c
index a320d614d127..4472c61dd0e0 100644
--- a/sys/dev/irdma/irdma_kcompat.c
+++ b/sys/dev/irdma/irdma_kcompat.c
@@ -77,10 +77,7 @@ irdma_get_dev_fw_str(struct ib_device *dev,
 }
 
 int
-irdma_add_gid(struct ib_device *device,
-	      u8 port_num,
-	      unsigned int index,
-	      const union ib_gid *gid,
+irdma_add_gid(const union ib_gid *gid,
 	      const struct ib_gid_attr *attr,
 	      void **context)
 {
@@ -88,9 +85,7 @@ irdma_add_gid(struct ib_device *device,
 }
 
 int
-irdma_del_gid(struct ib_device *device,
-	      u8 port_num,
-	      unsigned int index,
+irdma_del_gid(const struct ib_gid_attr *attr,
 	      void **context)
 {
 	return 0;
@@ -1516,28 +1511,6 @@ ib_unregister_device_put(struct ib_device *device)
 	ib_unregister_device(device);
 }
 
-/**
- * irdma_query_gid_roce - Query port GID for Roce
- * @ibdev: device pointer from stack
- * @port: port number
- * @index: Entry index
- * @gid: Global ID
- */
-int
-irdma_query_gid_roce(struct ib_device *ibdev, u8 port, int index,
-		     union ib_gid *gid)
-{
-	int ret;
-
-	ret = ib_get_cached_gid(ibdev, port, index, gid, NULL);
-	if (ret == -EAGAIN) {
-		memcpy(gid, &zgid, sizeof(*gid));
-		return 0;
-	}
-
-	return ret;
-}
-
 /**
  * irdma_modify_port - modify port attributes
  * @ibdev: device pointer from stack
diff --git a/sys/dev/irdma/irdma_verbs.c b/sys/dev/irdma/irdma_verbs.c
index eea241873522..6eba47e696c1 100644
--- a/sys/dev/irdma/irdma_verbs.c
+++ b/sys/dev/irdma/irdma_verbs.c
@@ -3328,7 +3328,6 @@ irdma_set_device_roce_ops(struct ib_device *ibdev)
 	dev_ops->get_port_immutable = irdma_roce_port_immutable;
 	dev_ops->modify_qp = irdma_modify_qp_roce;
 	dev_ops->query_ah = irdma_query_ah;
-	dev_ops->query_gid = irdma_query_gid_roce;
 	dev_ops->query_pkey = irdma_query_pkey;
 	ibdev->add_gid = irdma_add_gid;
 	ibdev->del_gid = irdma_del_gid;
diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c b/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
index ae82f8c1a187..9f51bac12d51 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
@@ -252,14 +252,11 @@ 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(struct ib_device *device,
-			   u8 port_num,
-			   unsigned int index,
-			   const union ib_gid *gid,
+static int mlx4_ib_add_gid(const union ib_gid *gid,
 			   const struct ib_gid_attr *attr,
 			   void **context)
 {
-	struct mlx4_ib_dev *ibdev = to_mdev(device);
+	struct mlx4_ib_dev *ibdev = to_mdev(attr->device);
 	struct mlx4_ib_iboe *iboe = &ibdev->iboe;
 	struct mlx4_port_gid_table   *port_gid_table;
 	int free = -1, found = -1;
@@ -268,16 +265,16 @@ static int mlx4_ib_add_gid(struct ib_device *device,
 	int i;
 	struct gid_entry *gids = NULL;
 
-	if (!rdma_cap_roce_gid_table(device, port_num))
+	if (!rdma_cap_roce_gid_table(attr->device, attr->port_num))
 		return -EINVAL;
 
-	if (port_num > MLX4_MAX_PORTS)
+	if (attr->port_num > MLX4_MAX_PORTS)
 		return -EINVAL;
 
 	if (!context)
 		return -EINVAL;
 
-	port_gid_table = &iboe->gids[port_num - 1];
+	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)) &&
@@ -324,33 +321,30 @@ static int mlx4_ib_add_gid(struct ib_device *device,
 	spin_unlock_bh(&iboe->lock);
 
 	if (!ret && hw_update) {
-		ret = mlx4_ib_update_gids(gids, ibdev, port_num);
+		ret = mlx4_ib_update_gids(gids, ibdev, attr->port_num);
 		kfree(gids);
 	}
 
 	return ret;
 }
 
-static int mlx4_ib_del_gid(struct ib_device *device,
-			   u8 port_num,
-			   unsigned int index,
-			   void **context)
+static int mlx4_ib_del_gid(const struct ib_gid_attr *attr, void **context)
 {
 	struct gid_cache_context *ctx = *context;
-	struct mlx4_ib_dev *ibdev = to_mdev(device);
+	struct mlx4_ib_dev *ibdev = to_mdev(attr->device);
 	struct mlx4_ib_iboe *iboe = &ibdev->iboe;
 	struct mlx4_port_gid_table   *port_gid_table;
 	int ret = 0;
 	int hw_update = 0;
 	struct gid_entry *gids = NULL;
 
-	if (!rdma_cap_roce_gid_table(device, port_num))
+	if (!rdma_cap_roce_gid_table(attr->device, attr->port_num))
 		return -EINVAL;
 
-	if (port_num > MLX4_MAX_PORTS)
+	if (attr->port_num > MLX4_MAX_PORTS)
 		return -EINVAL;
 
-	port_gid_table = &iboe->gids[port_num - 1];
+	port_gid_table = &iboe->gids[attr->port_num - 1];
 	spin_lock_bh(&iboe->lock);
 	if (ctx) {
 		ctx->refcount--;
@@ -382,7 +376,7 @@ static int mlx4_ib_del_gid(struct ib_device *device,
 	spin_unlock_bh(&iboe->lock);
 
 	if (!ret && hw_update) {
-		ret = mlx4_ib_update_gids(gids, ibdev, port_num);
+		ret = mlx4_ib_update_gids(gids, ibdev, attr->port_num);
 		kfree(gids);
 	}
 	return ret;
@@ -417,9 +411,6 @@ int mlx4_ib_gid_index_to_real_index(struct mlx4_ib_dev *ibdev,
 	if (attr.ndev)
 		if_rele(attr.ndev);
 
-	if (!memcmp(&gid, &zgid, sizeof(gid)))
-		return -EINVAL;
-
 	spin_lock_irqsave(&iboe->lock, flags);
 	port_gid_table = &iboe->gids[port_num - 1];
 
@@ -825,24 +816,10 @@ out:
 static int mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
 			     union ib_gid *gid)
 {
-	int ret;
-
 	if (rdma_protocol_ib(ibdev, port))
 		return __mlx4_ib_query_gid(ibdev, port, index, gid, 0);
 
-	if (!rdma_protocol_roce(ibdev, port))
-		return -ENODEV;
-
-	if (!rdma_cap_roce_gid_table(ibdev, port))
-		return -ENODEV;
-
-	ret = ib_get_cached_gid(ibdev, port, index, gid, NULL);
-	if (ret == -EAGAIN) {
-		memcpy(gid, &zgid, sizeof(*gid));
-		return 0;
-	}
-
-	return ret;
+	return 0;
 }
 
 static int mlx4_ib_query_sl2vl(struct ib_device *ibdev, u8 port, u64 *sl2vl_tbl)
diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c b/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c
index c4ab30c8bcb6..42606907a2e3 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c
@@ -1787,8 +1787,6 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
 
 			status = ib_get_cached_gid(ibqp->device, port_num,
 						   index, &gid, &gid_attr);
-			if (!status && !memcmp(&gid, &zgid, sizeof(gid)))
-				status = -ENOENT;
 			if (!status && gid_attr.ndev) {
 				vlan = rdma_vlan_dev_vlan_id(gid_attr.ndev);
 				memcpy(smac, if_getlladdr(gid_attr.ndev), ETH_ALEN);
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
index cf1e5f4324d8..a1159f91829d 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c
@@ -428,18 +428,19 @@ 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(struct ib_device *device, u8 port_num,
-			   unsigned int index, const union ib_gid *gid,
+static int mlx5_ib_add_gid(const union ib_gid *gid,
 			   const struct ib_gid_attr *attr,
 			   __always_unused void **context)
 {
-	return set_roce_addr(device, port_num, index, gid, attr);
+	return set_roce_addr(attr->device, attr->port_num, attr->index, gid,
+			     attr);
 }
 
-static int mlx5_ib_del_gid(struct ib_device *device, u8 port_num,
-			   unsigned int index, __always_unused void **context)
+static int mlx5_ib_del_gid(const struct ib_gid_attr *attr,
+			   __always_unused void **context)
 {
-	return set_roce_addr(device, port_num, index, NULL, NULL);
+	return set_roce_addr(attr->device, attr->port_num, attr->index, NULL,
+			     NULL);
 }
 
 __be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num,
diff --git a/sys/dev/qlnx/qlnxr/qlnxr_os.c b/sys/dev/qlnx/qlnxr/qlnxr_os.c
index fd32080af599..c2f87f91e450 100644
--- a/sys/dev/qlnx/qlnxr/qlnxr_os.c
+++ b/sys/dev/qlnx/qlnxr/qlnxr_os.c
@@ -197,7 +197,6 @@ qlnxr_register_device(qlnxr_dev_t *dev)
                 ibdev->query_gid = qlnxr_iw_query_gid;
         } else {
                 ibdev->node_type = RDMA_NODE_IB_CA;
-                ibdev->query_gid = qlnxr_query_gid;
                 ibdev->uverbs_cmd_mask |=
 			(1ull << IB_USER_VERBS_CMD_CREATE_SRQ) |
 			(1ull << IB_USER_VERBS_CMD_DESTROY_SRQ) |
diff --git a/sys/dev/qlnx/qlnxr/qlnxr_verbs.c b/sys/dev/qlnx/qlnxr/qlnxr_verbs.c
index d27052fa56bf..6f640d2b274d 100644
--- a/sys/dev/qlnx/qlnxr/qlnxr_verbs.c
+++ b/sys/dev/qlnx/qlnxr/qlnxr_verbs.c
@@ -118,44 +118,6 @@ qlnxr_iw_query_gid(struct ib_device *ibdev, u8 port, int index,
 	return 0;
 }
 
-int
-qlnxr_query_gid(struct ib_device *ibdev, u8 port, int index,
-	union ib_gid *sgid)
-{
-	struct qlnxr_dev	*dev;
-	qlnx_host_t		*ha;
-
-	dev = get_qlnxr_dev(ibdev);
-	ha = dev->ha;
-	QL_DPRINT12(ha, "enter index: %d\n", index);
-#if 0
-	int ret = 0;
-	/* @@@: if DEFINE_ROCE_GID_TABLE to be used here */
-	//if (!rdma_cap_roce_gid_table(ibdev, port)) {
-	if (!(rdma_protocol_roce(ibdev, port) &&
-		ibdev->add_gid && ibdev->del_gid)) {
-		QL_DPRINT11(ha, "acquire gid failed\n");
-		return -ENODEV;
-	}
-
-	ret = ib_get_cached_gid(ibdev, port, index, sgid, NULL);
-	if (ret == -EAGAIN) {
-		memcpy(sgid, &zgid, sizeof(*sgid));
-		return 0;
-	}
-#endif
-	if ((index >= QLNXR_MAX_SGID) || (index < 0)) {
-		QL_DPRINT12(ha, "invalid gid index %d\n", index);
-		memset(sgid, 0, sizeof(*sgid));
-		return -EINVAL;
-	}
-	memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid));
-
-	QL_DPRINT12(ha, "exit : %p\n", sgid);
-
-	return 0;
-}
-
 int
 qlnxr_create_srq(struct ib_srq *ibsrq,
 		 struct ib_srq_init_attr *init_attr,
diff --git a/sys/dev/qlnx/qlnxr/qlnxr_verbs.h b/sys/dev/qlnx/qlnxr/qlnxr_verbs.h
index dbb5e8602952..7be308ad6d9d 100644
--- a/sys/dev/qlnx/qlnxr/qlnxr_verbs.h
+++ b/sys/dev/qlnx/qlnxr/qlnxr_verbs.h
@@ -34,11 +34,6 @@ extern int qlnxr_iw_query_gid(struct ib_device *,
 			int index,
 			union ib_gid *gid);
 
-extern int qlnxr_query_gid(struct ib_device *,
-			u8 port,
-			int index,
-			union ib_gid *gid);
-
 extern int qlnxr_create_srq(struct ib_srq *ibsrq,
 			struct ib_srq_init_attr *,
 			struct ib_udata *);
diff --git a/sys/ofed/drivers/infiniband/core/cma_priv.h b/sys/ofed/drivers/infiniband/core/cma_priv.h
new file mode 100644
index 000000000000..ba054364d205
--- /dev/null
+++ b/sys/ofed/drivers/infiniband/core/cma_priv.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
+ * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved.
+ * Copyright (c) 2005-2006 Intel Corporation.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _CMA_PRIV_H
+#define _CMA_PRIV_H
+
+enum rdma_cm_state {
+	RDMA_CM_IDLE,
+	RDMA_CM_ADDR_QUERY,
+	RDMA_CM_ADDR_RESOLVED,
+	RDMA_CM_ROUTE_QUERY,
+	RDMA_CM_ROUTE_RESOLVED,
+	RDMA_CM_CONNECT,
+	RDMA_CM_DISCONNECT,
+	RDMA_CM_ADDR_BOUND,
+	RDMA_CM_LISTEN,
+	RDMA_CM_DEVICE_REMOVAL,
+	RDMA_CM_DESTROYING
+};
+
+struct rdma_id_private {
+	struct rdma_cm_id	id;
+
+	struct rdma_bind_list	*bind_list;
+	struct hlist_node	node;
+	struct list_head	list; /* listen_any_list or cma_device.list */
+	struct list_head	listen_list; /* per device listens */
+	struct cma_device	*cma_dev;
+	struct list_head	mc_list;
+
+	int			internal_id;
+	enum rdma_cm_state	state;
+	spinlock_t		lock;
+	struct mutex		qp_mutex;
+
+	struct completion	comp;
+	atomic_t		refcount;
+	struct mutex		handler_mutex;
+
+	int			backlog;
+	int			timeout_ms;
+	struct ib_sa_query	*query;
+	int			query_id;
+	union {
+		struct ib_cm_id	*ib;
+		struct iw_cm_id	*iw;
+	} cm_id;
+
+	u32			seq_num;
+	u32			qkey;
+	u32			qp_num;
+	pid_t			owner;
+	u32			options;
+	u8			srq;
+	u8			tos;
+	u8			tos_set:1;
+	u8			timeout_set:1;
+	u8			reuseaddr;
+	u8			afonly;
+	u8			timeout;
+	enum ib_gid_type	gid_type;
+};
+#endif /* _CMA_PRIV_H */
diff --git a/sys/ofed/drivers/infiniband/core/core_priv.h b/sys/ofed/drivers/infiniband/core/core_priv.h
index 508119e9259d..3a61defb540b 100644
--- a/sys/ofed/drivers/infiniband/core/core_priv.h
+++ b/sys/ofed/drivers/infiniband/core/core_priv.h
@@ -183,6 +183,16 @@ static inline struct ib_qp *_ib_create_qp(struct ib_device *dev,
 	return qp;
 }
 
+struct rdma_dev_addr;
+int rdma_resolve_ip_route(struct sockaddr *src_addr,
+			  const struct sockaddr *dst_addr,
+			  struct rdma_dev_addr *addr);
+
+int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
+				 const union ib_gid *dgid,
+				 u8 *dmac, if_t ndev,
+				 int *hoplimit);
+
 struct rdma_umap_priv {
 	struct vm_area_struct *vma;
 	struct list_head list;
diff --git a/sys/ofed/drivers/infiniband/core/ib_addr.c b/sys/ofed/drivers/infiniband/core/ib_addr.c
index 2a00e449ecda..893fd0bb2b37 100644
--- a/sys/ofed/drivers/infiniband/core/ib_addr.c
+++ b/sys/ofed/drivers/infiniband/core/ib_addr.c
@@ -61,7 +61,6 @@ struct addr_req {
 	struct sockaddr_storage src_addr;
 	struct sockaddr_storage dst_addr;
 	struct rdma_dev_addr *addr;
-	struct rdma_addr_client *client;
 	void *context;
 	void (*callback)(int status, struct sockaddr *src_addr,
 			 struct rdma_dev_addr *addr, void *context);
@@ -70,11 +69,8 @@ struct addr_req {
 	int status;
 };
 
-static void process_req(struct work_struct *work);
-
-static DEFINE_MUTEX(lock);
+static DEFINE_SPINLOCK(lock);
 static LIST_HEAD(req_list);
-static DECLARE_DELAYED_WORK(work, process_req);
 static struct workqueue_struct *addr_wq;
 
 int rdma_addr_size(struct sockaddr *addr)
@@ -108,28 +104,6 @@ int rdma_addr_size_kss(struct sockaddr_storage *addr)
 }
 EXPORT_SYMBOL(rdma_addr_size_kss);
 
-static struct rdma_addr_client self;
-
-void rdma_addr_register_client(struct rdma_addr_client *client)
-{
-	atomic_set(&client->refcount, 1);
-	init_completion(&client->comp);
-}
-EXPORT_SYMBOL(rdma_addr_register_client);
-
-static inline void put_client(struct rdma_addr_client *client)
-{
-	if (atomic_dec_and_test(&client->refcount))
-		complete(&client->comp);
-}
-
-void rdma_addr_unregister_client(struct rdma_addr_client *client)
-{
-	put_client(client);
-	wait_for_completion(&client->comp);
-}
-EXPORT_SYMBOL(rdma_addr_unregister_client);
-
 static inline void
 rdma_copy_addr_sub(u8 *dst, const u8 *src, unsigned min, unsigned max)
 {
@@ -211,7 +185,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
 }
 EXPORT_SYMBOL(rdma_translate_ip);
 
-static void set_timeout(struct delayed_work *delayed_work, unsigned long time)
+static void set_timeout(struct addr_req *req, unsigned long time)
 {
 	unsigned long delay;
 
@@ -221,23 +195,15 @@ static void set_timeout(struct delayed_work *delayed_work, unsigned long time)
 	else if (delay > hz)
 		delay = hz;
 
-	mod_delayed_work(addr_wq, delayed_work, delay);
+	mod_delayed_work(addr_wq, &req->work, delay);
 }
 
 static void queue_req(struct addr_req *req)
 {
-	struct addr_req *temp_req;
-
-	mutex_lock(&lock);
-	list_for_each_entry_reverse(temp_req, &req_list, list) {
-		if (time_after_eq(req->timeout, temp_req->timeout))
-			break;
-	}
-
-	list_add(&req->list, &temp_req->list);
-
-	set_timeout(&req->work, req->timeout);
-	mutex_unlock(&lock);
+	spin_lock_bh(&lock);
+	list_add_tail(&req->list, &req_list);
+	set_timeout(req, req->timeout);
+	spin_unlock_bh(&lock);
 }
 
 #if defined(INET) || defined(INET6)
@@ -714,7 +680,6 @@ static void process_one_req(struct work_struct *_work)
 	struct addr_req *req;
 	struct sockaddr *src_in, *dst_in;
 
-	mutex_lock(&lock);
 	req = container_of(_work, struct addr_req, work.work);
 
 	if (req->status == -ENODATA) {
@@ -725,62 +690,33 @@ static void process_one_req(struct work_struct *_work)
 			req->status = -ETIMEDOUT;
 		} else if (req->status == -ENODATA) {
 			/* requeue the work for retrying again */
-			set_timeout(&req->work, req->timeout);
-			mutex_unlock(&lock);
+			spin_lock_bh(&lock);
+			if (!list_empty(&req->list))
+				set_timeout(req, req->timeout);
+			spin_unlock_bh(&lock);
 			return;
 		}
 	}
-	list_del(&req->list);
-	mutex_unlock(&lock);
 
 	req->callback(req->status, (struct sockaddr *)&req->src_addr,
 		req->addr, req->context);
-	put_client(req->client);
-	kfree(req);
-}
-
-static void process_req(struct work_struct *work)
-{
-	struct addr_req *req, *temp_req;
-	struct sockaddr *src_in, *dst_in;
-	struct list_head done_list;
-
-	INIT_LIST_HEAD(&done_list);
-
-	mutex_lock(&lock);
-	list_for_each_entry_safe(req, temp_req, &req_list, list) {
-		if (req->status == -ENODATA) {
-			src_in = (struct sockaddr *) &req->src_addr;
-			dst_in = (struct sockaddr *) &req->dst_addr;
-			req->status = addr_resolve(src_in, dst_in, req->addr);
-			if (req->status && time_after_eq(jiffies, req->timeout))
-				req->status = -ETIMEDOUT;
-			else if (req->status == -ENODATA) {
-				set_timeout(&req->work, req->timeout);
-				continue;
-			}
-		}
-		list_move_tail(&req->list, &done_list);
-	}
+	req->callback = NULL;
 
-	mutex_unlock(&lock);
-
-	list_for_each_entry_safe(req, temp_req, &done_list, list) {
-		list_del(&req->list);
-		/* It is safe to cancel other work items from this work item
-		 * because at a time there can be only one work item running
-		 * with this single threaded work queue.
+	spin_lock_bh(&lock);
+	if (!list_empty(&req->list)) {
+		/*
+		 * Although the work will normally have been canceled by the
+		 * workqueue, it can still be requeued as long as it is on the
+		 * req_list.
 		 */
 		cancel_delayed_work(&req->work);
-		req->callback(req->status, (struct sockaddr *) &req->src_addr,
-			req->addr, req->context);
-		put_client(req->client);
+		list_del_init(&req->list);
 		kfree(req);
 	}
+	spin_unlock_bh(&lock);
 }
 
-int rdma_resolve_ip(struct rdma_addr_client *client,
-		    struct sockaddr *src_addr, struct sockaddr *dst_addr,
+int rdma_resolve_ip(struct sockaddr *src_addr, 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),
@@ -812,8 +748,6 @@ int rdma_resolve_ip(struct rdma_addr_client *client,
 	req->addr = addr;
 	req->callback = callback;
 	req->context = context;
-	req->client = client;
-	atomic_inc(&client->refcount);
 	INIT_DELAYED_WORK(&req->work, process_one_req);
 
 	req->status = addr_resolve(src_in, dst_in, addr);
@@ -828,7 +762,6 @@ int rdma_resolve_ip(struct rdma_addr_client *client,
 		break;
 	default:
 		ret = req->status;
-		atomic_dec(&client->refcount);
 		goto err;
 	}
 	return ret;
@@ -856,23 +789,40 @@ int rdma_resolve_ip_route(struct sockaddr *src_addr,
 
 	return addr_resolve(src_in, dst_addr, addr);
 }
-EXPORT_SYMBOL(rdma_resolve_ip_route);
 
 void rdma_addr_cancel(struct rdma_dev_addr *addr)
 {
 	struct addr_req *req, *temp_req;
+	struct addr_req *found = NULL;
 
-	mutex_lock(&lock);
+	spin_lock_bh(&lock);
 	list_for_each_entry_safe(req, temp_req, &req_list, list) {
 		if (req->addr == addr) {
-			req->status = -ECANCELED;
-			req->timeout = jiffies;
-			list_move(&req->list, &req_list);
-			set_timeout(&req->work, req->timeout);
+			/*
+			 * Removing from the list means we take ownership of
+			 * the req
+			 */
+			list_del_init(&req->list);
+			found = req;
 			break;
 		}
 	}
-	mutex_unlock(&lock);
+	spin_unlock_bh(&lock);
+
+	if (!found)
+		return;
+
+	/*
+	 * sync canceling the work after removing it from the req_list
+	 * guarentees no work is running and none will be started.
+	 */
+	cancel_delayed_work_sync(&found->work);
+
+	if (found->callback)
+		found->callback(-ECANCELED, (struct sockaddr *)&found->src_addr,
+			      found->addr, found->context);
+
+	kfree(found);
 }
 EXPORT_SYMBOL(rdma_addr_cancel);
 
@@ -907,8 +857,8 @@ int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
 	dev_addr.net = dev_net(ndev);
 
 	init_completion(&ctx.comp);
-	ret = rdma_resolve_ip(&self, &sgid_addr._sockaddr, &dgid_addr._sockaddr,
-			&dev_addr, 1000, resolve_cb, &ctx);
+	ret = rdma_resolve_ip(&sgid_addr._sockaddr, &dgid_addr._sockaddr,
+			      &dev_addr, 1000, resolve_cb, &ctx);
 	if (ret)
 		return ret;
 
@@ -929,13 +879,11 @@ int addr_init(void)
 	if (!addr_wq)
 		return -ENOMEM;
 
-	rdma_addr_register_client(&self);
-
 	return 0;
 }
 
 void addr_cleanup(void)
 {
-	rdma_addr_unregister_client(&self);
 	destroy_workqueue(addr_wq);
+	WARN_ON(!list_empty(&req_list));
 }
diff --git a/sys/ofed/drivers/infiniband/core/ib_cache.c b/sys/ofed/drivers/infiniband/core/ib_cache.c
index 878b2915f25d..1b7f0dfd4761 100644
--- a/sys/ofed/drivers/infiniband/core/ib_cache.c
+++ b/sys/ofed/drivers/infiniband/core/ib_cache.c
@@ -62,8 +62,6 @@ struct ib_update_work {
 union ib_gid zgid;
 EXPORT_SYMBOL(zgid);
 
-static const struct ib_gid_attr zattr;
-
 enum gid_attr_find_mask {
 	GID_ATTR_FIND_MASK_GID          = 1UL << 0,
 	GID_ATTR_FIND_MASK_NETDEV	= 1UL << 1,
@@ -76,15 +74,6 @@ enum gid_table_entry_props {
 	GID_TABLE_ENTRY_DEFAULT		= 1UL << 1,
 };
 
-enum gid_table_write_action {
-	GID_TABLE_WRITE_ACTION_ADD,
-	GID_TABLE_WRITE_ACTION_DEL,
-	/* MODIFY only updates the GID table. Currently only used by
-	 * ib_cache_update.
-	 */
-	GID_TABLE_WRITE_ACTION_MODIFY
-};
-
 struct ib_gid_table_entry {
 	unsigned long	    props;
 	union ib_gid        gid;
@@ -103,31 +92,26 @@ struct ib_gid_table {
 	 * (a) Find the GID
 	 * (b) Delete it.
 	 *
-	 * Add/delete should be carried out atomically.
-	 * This is done by locking this mutex from multiple
-	 * writers. We don't need this lock for IB, as the MAD
-	 * layer replaces all entries. All data_vec entries
-	 * are locked by this lock.
 	 **/
-	struct mutex         lock;
-	/* This lock protects the table entries from being
-	 * read and written simultaneously.
+	/* 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
+	 * sleepable context.
 	 */
+	struct mutex         lock;
+	/* rwlock protects data_vec[ix]->props. */
 	rwlock_t	     rwlock;
 	struct ib_gid_table_entry *data_vec;
 };
 
 static void dispatch_gid_change_event(struct ib_device *ib_dev, u8 port)
 {
-	if (rdma_cap_roce_gid_table(ib_dev, port)) {
-		struct ib_event event;
+	struct ib_event event;
 
-		event.device		= ib_dev;
-		event.element.port_num	= port;
-		event.event		= IB_EVENT_GID_CHANGE;
+	event.device		= ib_dev;
+	event.element.port_num	= port;
+	event.event		= IB_EVENT_GID_CHANGE;
 
-		ib_dispatch_event(&event);
-	}
+	ib_dispatch_event(&event);
 }
 
 static const char * const gid_type_str[] = {
@@ -168,94 +152,127 @@ int ib_cache_gid_parse_type_str(const char *buf)
*** 1609 LINES SKIPPED ***