git: b633e08c705f - main - ibcore: Kernel space update based on Linux 5.7-rc1.

Hans Petter Selasky hselasky at FreeBSD.org
Wed Jul 28 11:34:57 UTC 2021


The branch main has been updated by hselasky:

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

commit b633e08c705fe43180567eae26923d6f6f98c8d9
Author:     Hans Petter Selasky <hselasky at FreeBSD.org>
AuthorDate: 2021-06-16 13:02:00 +0000
Commit:     Hans Petter Selasky <hselasky at FreeBSD.org>
CommitDate: 2021-07-28 11:28:29 +0000

    ibcore: Kernel space update based on Linux 5.7-rc1.
    
    Overview:
    
    This is the first stage of a RDMA stack upgrade introducing kernel
    changes only based on Linux 5.7-rc1.
    
    This patch is based on about four main areas of work:
    - Update of the IB uobjects system:
      - The memory holding so-called AH, CQ, PD, SRQ and UCONTEXT objects
        is now managed by ibcore. This also require some changes in the
        kernel verbs API. The updated verbs changes are typically about
        initialize and deinitialize objects, and remove allocation and
        free of memory.
    
    - Update of the uverbs IOCTL framework:
      - The parsing and handling of user-space commands has been
        completely refactored to integrate with the updated IB uobjects
        system.
    
    - Various changes and updates to the generic uverbs interfaces in
      device drivers including the new uAPI surface.
    
    - The mlx5_ib_devx.c in mlx5ib and related mlx5 core changes.
    
    Dependencies:
    
    - The mlx4ib driver code has been updated with the minimum changes
    needed.
    
    - The mlx5ib driver code has been updated with the minimum changes
    needed including DV support.
    
    Compatibility:
    
    - All user-space facing APIs are backwards compatible after this
      change.
    
    - All kernel-space facing RDMA APIs are backwards compatible after
      this change, with exception of ib_create_ah() and ib_destroy_ah()
      which takes a new flag.
    
    - The "ib_device_ops" structure exist, but only contains the driver ID
      and some structure sizes.
    
    Differences from Linux:
    
    - Infiniband drivers must use the INIT_IB_DEVICE_OPS() macro to set
      the sizes needed for allocating various IB objects, when adding
      IB device instances.
    
    Security:
    
    - PRIV_NET_RAW is needed to use raw ethernet transmit features.
    - PRIV_DRIVER is needed to use other privileged operations.
    
    Based on upstream Linux, Torvalds (5.7-rc1):
    8632e9b5645bbc2331d21d892b0d6961c1a08429
    
    MFC after:      1 week
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D31149
    Sponsored by:   NVIDIA Networking
---
 sys/conf/files                                     |   26 +
 sys/dev/cxgbe/iw_cxgbe/cq.c                        |   32 +-
 sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h                  |   36 +-
 sys/dev/cxgbe/iw_cxgbe/mem.c                       |    4 +-
 sys/dev/cxgbe/iw_cxgbe/provider.c                  |   96 +-
 sys/dev/cxgbe/iw_cxgbe/qp.c                        |    5 +-
 sys/dev/mlx4/mlx4_ib/mlx4_ib.h                     |   37 +-
 sys/dev/mlx4/mlx4_ib/mlx4_ib_ah.c                  |   74 +-
 sys/dev/mlx4/mlx4_ib/mlx4_ib_cq.c                  |   89 +-
 sys/dev/mlx4/mlx4_ib/mlx4_ib_mad.c                 |   65 +-
 sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c                |  201 +-
 sys/dev/mlx4/mlx4_ib/mlx4_ib_mr.c                  |    9 +-
 sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c                  |   42 +-
 sys/dev/mlx4/mlx4_ib/mlx4_ib_srq.c                 |   84 +-
 sys/dev/mlx5/device.h                              |   22 +-
 sys/dev/mlx5/driver.h                              |   34 +-
 sys/dev/mlx5/mlx5_core/mlx5_eq.c                   |    8 +-
 sys/dev/mlx5/mlx5_core/mlx5_fw.c                   |    8 +-
 sys/dev/mlx5/mlx5_core/mlx5_mr.c                   |   12 +-
 sys/dev/mlx5/mlx5_core/mlx5_pd.c                   |    8 +-
 sys/dev/mlx5/mlx5_core/mlx5_tls.c                  |    2 +-
 sys/dev/mlx5/mlx5_core/mlx5_transobj.c             |   15 +-
 sys/dev/mlx5/mlx5_core/transobj.h                  |   10 +-
 sys/dev/mlx5/mlx5_en/en.h                          |    2 +-
 sys/dev/mlx5/mlx5_en/mlx5_en_main.c                |   18 +-
 sys/dev/mlx5/mlx5_en/mlx5_en_rl.c                  |    2 +-
 sys/dev/mlx5/mlx5_ib/mlx5_ib.h                     |  132 +-
 sys/dev/mlx5/mlx5_ib/mlx5_ib_ah.c                  |   38 +-
 sys/dev/mlx5/mlx5_ib/mlx5_ib_cq.c                  |   88 +-
 sys/dev/mlx5/mlx5_ib/mlx5_ib_devx.c                | 2930 ++++++++++++++
 sys/dev/mlx5/mlx5_ib/mlx5_ib_gsi.c                 |    2 +-
 sys/dev/mlx5/mlx5_ib/mlx5_ib_main.c                |  525 ++-
 sys/dev/mlx5/mlx5_ib/mlx5_ib_mr.c                  |    8 +-
 sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c                  |  175 +-
 sys/dev/mlx5/mlx5_ib/mlx5_ib_srq.c                 |  126 +-
 sys/dev/mlx5/mlx5_ifc.h                            |  560 ++-
 sys/dev/mlx5/qp.h                                  |    2 +-
 sys/dev/mlx5/srq.h                                 |    1 +
 sys/dev/mthca/mthca_dev.h                          |    9 +-
 sys/dev/mthca/mthca_mad.c                          |    7 +-
 sys/dev/mthca/mthca_provider.c                     |  317 +-
 sys/dev/mthca/mthca_qp.c                           |   35 +-
 sys/dev/mthca/mthca_srq.c                          |   42 +-
 sys/dev/qlnx/qlnxr/qlnxr_def.h                     |    1 +
 sys/dev/qlnx/qlnxr/qlnxr_os.c                      |    7 +
 sys/dev/qlnx/qlnxr/qlnxr_verbs.c                   |  243 +-
 sys/dev/qlnx/qlnxr/qlnxr_verbs.h                   |   62 +-
 sys/modules/ibcore/Makefile                        |   13 +
 sys/modules/mlx5/Makefile                          |    1 +
 sys/modules/mlx5en/Makefile                        |    1 +
 sys/modules/mlx5fpga_tools/Makefile                |    1 +
 sys/modules/mlx5ib/Makefile                        |    1 +
 sys/modules/mlxfw/Makefile                         |    1 +
 sys/ofed/drivers/infiniband/core/core_priv.h       |   49 +
 sys/ofed/drivers/infiniband/core/ib_agent.c        |    4 +-
 sys/ofed/drivers/infiniband/core/ib_cm.c           |    6 +-
 sys/ofed/drivers/infiniband/core/ib_core_uverbs.c  |  390 ++
 sys/ofed/drivers/infiniband/core/ib_cq.c           |   32 +-
 sys/ofed/drivers/infiniband/core/ib_mad_rmpp.c     |   10 +-
 sys/ofed/drivers/infiniband/core/ib_rdma_core.c    |  943 +++++
 sys/ofed/drivers/infiniband/core/ib_sa_query.c     |    4 +-
 sys/ofed/drivers/infiniband/core/ib_user_mad.c     |    6 +-
 sys/ofed/drivers/infiniband/core/ib_uverbs_cmd.c   | 4024 +++++++++-----------
 sys/ofed/drivers/infiniband/core/ib_uverbs_ioctl.c |  767 ++++
 sys/ofed/drivers/infiniband/core/ib_uverbs_main.c  | 1339 +++----
 .../drivers/infiniband/core/ib_uverbs_std_types.c  |  359 ++
 .../infiniband/core/ib_uverbs_std_types_async_fd.c |   54 +
 .../infiniband/core/ib_uverbs_std_types_counters.c |  161 +
 .../infiniband/core/ib_uverbs_std_types_cq.c       |  214 ++
 .../infiniband/core/ib_uverbs_std_types_device.c   |  261 ++
 .../infiniband/core/ib_uverbs_std_types_dm.c       |  118 +
 .../core/ib_uverbs_std_types_flow_action.c         |  449 +++
 .../infiniband/core/ib_uverbs_std_types_mr.c       |  221 ++
 sys/ofed/drivers/infiniband/core/ib_uverbs_uapi.c  |  731 ++++
 sys/ofed/drivers/infiniband/core/ib_verbs.c        |  453 ++-
 sys/ofed/drivers/infiniband/core/rdma_core.h       |  189 +
 sys/ofed/drivers/infiniband/core/uverbs.h          |  215 +-
 sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c   |    4 +-
 sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c       |    8 +-
 sys/ofed/drivers/infiniband/ulp/sdp/sdp_tx.c       |    8 +-
 sys/ofed/include/rdma/ib_verbs.h                   |  959 +++--
 sys/ofed/include/rdma/signature.h                  |  124 +
 sys/ofed/include/rdma/uverbs_ioctl.h               |  958 +++++
 sys/ofed/include/rdma/uverbs_named_ioctl.h         |  124 +
 sys/ofed/include/rdma/uverbs_std_types.h           |  193 +
 sys/ofed/include/rdma/uverbs_types.h               |  210 +
 sys/ofed/include/uapi/rdma/ib_user_ioctl_cmds.h    |  259 ++
 sys/ofed/include/uapi/rdma/ib_user_ioctl_verbs.h   |  211 +
 sys/ofed/include/uapi/rdma/ib_user_mad.h           |   20 +-
 sys/ofed/include/uapi/rdma/ib_user_verbs.h         |  424 ++-
 sys/ofed/include/uapi/rdma/mlx5-abi.h              |   18 +
 sys/ofed/include/uapi/rdma/mlx5_user_ioctl_cmds.h  |  283 ++
 sys/ofed/include/uapi/rdma/mlx5_user_ioctl_verbs.h |   87 +
 sys/ofed/include/uapi/rdma/rdma_user_ioctl.h       |   63 +
 sys/ofed/include/uapi/rdma/rdma_user_ioctl_cmds.h  |   92 +
 95 files changed, 16284 insertions(+), 5029 deletions(-)

diff --git a/sys/conf/files b/sys/conf/files
index 5e47c907e793..3d76d9909f77 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -4628,6 +4628,8 @@ ofed/drivers/infiniband/core/ib_cm.c			optional ofed	\
 	compile-with "${OFED_C}"
 ofed/drivers/infiniband/core/ib_cma.c			optional ofed	\
 	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_core_uverbs.c		optional ofed	\
+	compile-with "${OFED_C}"
 ofed/drivers/infiniband/core/ib_cq.c			optional ofed	\
 	compile-with "${OFED_C}"
 ofed/drivers/infiniband/core/ib_device.c		optional ofed	\
@@ -4648,6 +4650,8 @@ ofed/drivers/infiniband/core/ib_multicast.c		optional ofed	\
 	compile-with "${OFED_C}"
 ofed/drivers/infiniband/core/ib_packer.c		optional ofed	\
 	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_rdma_core.c		optional ofed	\
+	compile-with "${OFED_C}"
 ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c		optional ofed	\
 	compile-with "${OFED_C}"
 ofed/drivers/infiniband/core/ib_sa_query.c		optional ofed	\
@@ -4668,10 +4672,30 @@ ofed/drivers/infiniband/core/ib_user_mad.c		optional ofed	\
 	compile-with "${OFED_C}"
 ofed/drivers/infiniband/core/ib_uverbs_cmd.c		optional ofed	\
 	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_uverbs_ioctl.c		optional ofed	\
+	compile-with "${OFED_C}"
 ofed/drivers/infiniband/core/ib_uverbs_main.c		optional ofed	\
 	compile-with "${OFED_C}"
 ofed/drivers/infiniband/core/ib_uverbs_marshall.c	optional ofed	\
 	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_uverbs_std_types.c	optional ofed	\
+	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_uverbs_std_types_async_fd.c	optional ofed	\
+	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_uverbs_std_types_counters.c	optional ofed	\
+	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_uverbs_std_types_cq.c		optional ofed	\
+	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_uverbs_std_types_device.c	optional ofed	\
+	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_uverbs_std_types_dm.c		optional ofed	\
+	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_uverbs_std_types_flow_action.c	optional ofed	\
+	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_uverbs_std_types_mr.c	optional ofed	\
+	compile-with "${OFED_C}"
+ofed/drivers/infiniband/core/ib_uverbs_uapi.c		optional ofed	\
+	compile-with "${OFED_C}"
 ofed/drivers/infiniband/core/ib_verbs.c			optional ofed	\
 	compile-with "${OFED_C}"
 
@@ -4827,6 +4851,8 @@ dev/mlx5/mlx5_ib/mlx5_ib_cong.c			optional mlx5ib pci ofed \
 	compile-with "${OFED_C}"
 dev/mlx5/mlx5_ib/mlx5_ib_cq.c			optional mlx5ib pci ofed \
 	compile-with "${OFED_C}"
+dev/mlx5/mlx5_ib/mlx5_ib_devx.c			optional mlx5ib pci ofed \
+	compile-with "${OFED_C}"
 dev/mlx5/mlx5_ib/mlx5_ib_doorbell.c		optional mlx5ib pci ofed \
 	compile-with "${OFED_C}"
 dev/mlx5/mlx5_ib/mlx5_ib_gsi.c			optional mlx5ib pci ofed \
diff --git a/sys/dev/cxgbe/iw_cxgbe/cq.c b/sys/dev/cxgbe/iw_cxgbe/cq.c
index 55d50d5caf18..ab49e643e02d 100644
--- a/sys/dev/cxgbe/iw_cxgbe/cq.c
+++ b/sys/dev/cxgbe/iw_cxgbe/cq.c
@@ -883,7 +883,7 @@ int c4iw_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
 	return !err || err == -ENODATA ? npolled : err;
 }
 
-int c4iw_destroy_cq(struct ib_cq *ib_cq)
+void c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
 {
 	struct c4iw_cq *chp;
 	struct c4iw_ucontext *ucontext;
@@ -895,22 +895,20 @@ int c4iw_destroy_cq(struct ib_cq *ib_cq)
 	atomic_dec(&chp->refcnt);
 	wait_event(chp->wait, !atomic_read(&chp->refcnt));
 
-	ucontext = ib_cq->uobject ? to_c4iw_ucontext(ib_cq->uobject->context)
-				  : NULL;
+	ucontext = rdma_udata_to_drv_context(udata, struct c4iw_ucontext,
+	    ibucontext);
 	destroy_cq(&chp->rhp->rdev, &chp->cq,
 		   ucontext ? &ucontext->uctx : &chp->cq.rdev->uctx);
-	kfree(chp);
-	return 0;
 }
 
-struct ib_cq *
-c4iw_create_cq(struct ib_device *ibdev, const struct ib_cq_init_attr *attr,
-    struct ib_ucontext *ib_context, struct ib_udata *udata)
+int c4iw_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
+		   struct ib_udata *udata)
 {
+	struct ib_device *ibdev = ibcq->device;
 	int entries = attr->cqe;
 	int vector = attr->comp_vector;
 	struct c4iw_dev *rhp;
-	struct c4iw_cq *chp;
+	struct c4iw_cq *chp = to_c4iw_cq(ibcq);
 	struct c4iw_create_cq_resp uresp;
 	struct c4iw_ucontext *ucontext = NULL;
 	int ret;
@@ -919,17 +917,12 @@ c4iw_create_cq(struct ib_device *ibdev, const struct ib_cq_init_attr *attr,
 
 	CTR3(KTR_IW_CXGBE, "%s ib_dev %p entries %d", __func__, ibdev, entries);
 	if (attr->flags)
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 
 	rhp = to_c4iw_dev(ibdev);
 
-	chp = kzalloc(sizeof(*chp), GFP_KERNEL);
-	if (!chp)
-		return ERR_PTR(-ENOMEM);
-
-
-	if (ib_context)
-		ucontext = to_c4iw_ucontext(ib_context);
+	ucontext = rdma_udata_to_drv_context(udata, struct c4iw_ucontext,
+	    ibucontext);
 
 	/* account for the status page. */
 	entries++;
@@ -1020,7 +1013,7 @@ c4iw_create_cq(struct ib_device *ibdev, const struct ib_cq_init_attr *attr,
 	    "%s cqid 0x%0x chp %p size %u memsize %zu, dma_addr 0x%0llx",
 	    __func__, chp->cq.cqid, chp, chp->cq.size, chp->cq.memsize,
 	    (unsigned long long) chp->cq.dma_addr);
-	return &chp->ibcq;
+	return 0;
 err5:
 	kfree(mm2);
 err4:
@@ -1031,8 +1024,7 @@ err2:
 	destroy_cq(&chp->rhp->rdev, &chp->cq,
 		   ucontext ? &ucontext->uctx : &rhp->rdev.uctx);
 err1:
-	kfree(chp);
-	return ERR_PTR(ret);
+	return ret;
 }
 
 int c4iw_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata)
diff --git a/sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h b/sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h
index 59ca38a96004..03d3b2b0ad38 100644
--- a/sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h
+++ b/sys/dev/cxgbe/iw_cxgbe/iw_cxgbe.h
@@ -55,6 +55,7 @@
 
 #include <rdma/ib_verbs.h>
 #include <rdma/iw_cm.h>
+#include <rdma/uverbs_ioctl.h>
 
 #include "common/common.h"
 #include "common/t4_msg.h"
@@ -474,6 +475,14 @@ struct c4iw_qp_attributes {
 	u8 send_term;
 };
 
+struct c4iw_ib_srq {
+	struct ib_srq ibsrq;
+};
+
+struct c4iw_ib_ah {
+	struct ib_ah ibah;
+};
+
 struct c4iw_qp {
 	struct ib_qp ibqp;
 	struct c4iw_dev *rhp;
@@ -501,7 +510,6 @@ struct c4iw_ucontext {
 	u32 key;
 	spinlock_t mmap_lock;
 	struct list_head mmaps;
-	struct kref kref;
 };
 
 static inline struct c4iw_ucontext *to_c4iw_ucontext(struct ib_ucontext *c)
@@ -509,17 +517,6 @@ static inline struct c4iw_ucontext *to_c4iw_ucontext(struct ib_ucontext *c)
 	return container_of(c, struct c4iw_ucontext, ibucontext);
 }
 
-void _c4iw_free_ucontext(struct kref *kref);
-
-static inline void c4iw_put_ucontext(struct c4iw_ucontext *ucontext)
-{
-	kref_put(&ucontext->kref, _c4iw_free_ucontext);
-}
-static inline void c4iw_get_ucontext(struct c4iw_ucontext *ucontext)
-{
-	kref_get(&ucontext->kref);
-}
-
 struct c4iw_mm_entry {
 	struct list_head entry;
 	u64 addr;
@@ -938,7 +935,7 @@ int c4iw_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len);
 void c4iw_qp_add_ref(struct ib_qp *qp);
 void c4iw_qp_rem_ref(struct ib_qp *qp);
 struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
-			u32 max_num_sg);
+		u32 max_num_sg, struct ib_udata *udata);
 int c4iw_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
 		int sg_nents, unsigned int *sg_offset);
 int c4iw_dealloc_mw(struct ib_mw *mw);
@@ -947,16 +944,15 @@ struct ib_mw *c4iw_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
 struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64
 		virt, int acc, struct ib_udata *udata);
 struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc);
-int c4iw_dereg_mr(struct ib_mr *ib_mr);
+int c4iw_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
 void c4iw_invalidate_mr(struct c4iw_dev *rhp, u32 rkey);
-int c4iw_destroy_cq(struct ib_cq *ib_cq);
-struct ib_cq *c4iw_create_cq(struct ib_device *ibdev,
-				const struct ib_cq_init_attr *attr,
-				struct ib_ucontext *ib_context,
-				struct ib_udata *udata);
+void c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
+int c4iw_create_cq(struct ib_cq *ibcq,
+		   const struct ib_cq_init_attr *attr,
+		   struct ib_udata *udata);
 int c4iw_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata);
 int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
-int c4iw_destroy_qp(struct ib_qp *ib_qp);
+int c4iw_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata);
 struct ib_qp *c4iw_create_qp(struct ib_pd *pd,
 			     struct ib_qp_init_attr *attrs,
 			     struct ib_udata *udata);
diff --git a/sys/dev/cxgbe/iw_cxgbe/mem.c b/sys/dev/cxgbe/iw_cxgbe/mem.c
index dab812d58eec..c6eb8cff6da9 100644
--- a/sys/dev/cxgbe/iw_cxgbe/mem.c
+++ b/sys/dev/cxgbe/iw_cxgbe/mem.c
@@ -610,7 +610,7 @@ int c4iw_dealloc_mw(struct ib_mw *mw)
 
 struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd,
 			    enum ib_mr_type mr_type,
-			    u32 max_num_sg)
+			    u32 max_num_sg, struct ib_udata *udata)
 {
 	struct c4iw_dev *rhp;
 	struct c4iw_pd *php;
@@ -700,7 +700,7 @@ int c4iw_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
 }
 
 
-int c4iw_dereg_mr(struct ib_mr *ib_mr)
+int c4iw_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata)
 {
 	struct c4iw_dev *rhp;
 	struct c4iw_mr *mhp;
diff --git a/sys/dev/cxgbe/iw_cxgbe/provider.c b/sys/dev/cxgbe/iw_cxgbe/provider.c
index 02a32fa4c1fc..10b990e21f98 100644
--- a/sys/dev/cxgbe/iw_cxgbe/provider.c
+++ b/sys/dev/cxgbe/iw_cxgbe/provider.c
@@ -58,16 +58,15 @@ static int c4iw_modify_port(struct ib_device *ibdev,
 	return -ENOSYS;
 }
 
-static struct ib_ah *c4iw_ah_create(struct ib_pd *pd,
-				    struct ib_ah_attr *ah_attr,
-				    struct ib_udata *udata)
+static int c4iw_ah_create(struct ib_ah *ah,
+			  struct ib_ah_attr *ah_attr, u32 flags,
+			  struct ib_udata *udata)
 {
-	return ERR_PTR(-ENOSYS);
+	return -ENOSYS;
 }
 
-static int c4iw_ah_destroy(struct ib_ah *ah)
+static void c4iw_ah_destroy(struct ib_ah *ah, u32 flags)
 {
-	return -ENOSYS;
 }
 
 static int c4iw_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
@@ -93,35 +92,27 @@ static int c4iw_process_mad(struct ib_device *ibdev, int mad_flags,
 	return -ENOSYS;
 }
 
-void _c4iw_free_ucontext(struct kref *kref)
+static void c4iw_dealloc_ucontext(struct ib_ucontext *context)
 {
-	struct c4iw_ucontext *ucontext;
+	struct c4iw_ucontext *ucontext = to_c4iw_ucontext(context);
 	struct c4iw_dev *rhp;
 	struct c4iw_mm_entry *mm, *tmp;
 
-	ucontext = container_of(kref, struct c4iw_ucontext, kref);
+	pr_debug("context %p\n", context);
 	rhp = to_c4iw_dev(ucontext->ibucontext.device);
 
 	CTR2(KTR_IW_CXGBE, "%s ucontext %p", __func__, ucontext);
+
 	list_for_each_entry_safe(mm, tmp, &ucontext->mmaps, entry)
 		kfree(mm);
 	c4iw_release_dev_ucontext(&rhp->rdev, &ucontext->uctx);
-	kfree(ucontext);
 }
 
-static int c4iw_dealloc_ucontext(struct ib_ucontext *context)
+static int c4iw_alloc_ucontext(struct ib_ucontext *ucontext,
+			       struct ib_udata *udata)
 {
-	struct c4iw_ucontext *ucontext = to_c4iw_ucontext(context);
-
-	CTR2(KTR_IW_CXGBE, "%s context %p", __func__, context);
-	c4iw_put_ucontext(ucontext);
-	return 0;
-}
-
-static struct ib_ucontext *c4iw_alloc_ucontext(struct ib_device *ibdev,
-					       struct ib_udata *udata)
-{
-	struct c4iw_ucontext *context;
+	struct ib_device *ibdev = ucontext->device;
+	struct c4iw_ucontext *context = to_c4iw_ucontext(ucontext);
 	struct c4iw_dev *rhp = to_c4iw_dev(ibdev);
 	static int warned;
 	struct c4iw_alloc_ucontext_resp uresp;
@@ -129,16 +120,9 @@ static struct ib_ucontext *c4iw_alloc_ucontext(struct ib_device *ibdev,
 	struct c4iw_mm_entry *mm = NULL;
 
 	PDBG("%s ibdev %p\n", __func__, ibdev);
-	context = kzalloc(sizeof(*context), GFP_KERNEL);
-	if (!context) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
 	c4iw_init_dev_ucontext(&rhp->rdev, &context->uctx);
 	INIT_LIST_HEAD(&context->mmaps);
 	spin_lock_init(&context->mmap_lock);
-	kref_init(&context->kref);
 
 	if (udata->outlen < sizeof(uresp) - sizeof(uresp.reserved)) {
 		if (!warned++)
@@ -150,7 +134,7 @@ static struct ib_ucontext *c4iw_alloc_ucontext(struct ib_device *ibdev,
 
 		mm = kmalloc(sizeof *mm, GFP_KERNEL);
 		if (!mm)
-			goto err_free;
+			goto err;
 
 		uresp.status_page_size = PAGE_SIZE;
 
@@ -169,13 +153,11 @@ static struct ib_ucontext *c4iw_alloc_ucontext(struct ib_device *ibdev,
 		mm->len = PAGE_SIZE;
 		insert_mmap(context, mm);
 	}
-	return &context->ibucontext;
+	return 0;
 err_mm:
 	kfree(mm);
-err_free:
-	kfree(context);
 err:
-	return ERR_PTR(ret);
+	return ret;
 }
 
 static int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
@@ -226,8 +208,8 @@ static int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
 	return ret;
 }
 
-static int
-c4iw_deallocate_pd(struct ib_pd *pd)
+static void
+c4iw_deallocate_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
 	struct c4iw_pd *php = to_c4iw_pd(pd);
 	struct c4iw_dev *rhp = php->rhp;
@@ -238,36 +220,29 @@ c4iw_deallocate_pd(struct ib_pd *pd)
 	mutex_lock(&rhp->rdev.stats.lock);
 	rhp->rdev.stats.pd.cur--;
 	mutex_unlock(&rhp->rdev.stats.lock);
-	kfree(php);
-
-	return (0);
 }
 
-static struct ib_pd *
-c4iw_allocate_pd(struct ib_device *ibdev, struct ib_ucontext *context,
-    struct ib_udata *udata)
+static int
+c4iw_allocate_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
-	struct c4iw_pd *php;
+	struct c4iw_pd *php = to_c4iw_pd(pd);
+	struct ib_device *ibdev = pd->device;
 	u32 pdid;
 	struct c4iw_dev *rhp;
 
-	CTR4(KTR_IW_CXGBE, "%s: ibdev %p, context %p, data %p", __func__, ibdev,
-	    context, udata);
+	CTR4(KTR_IW_CXGBE, "%s: ibdev %p, pd %p, data %p", __func__, ibdev,
+	    pd, udata);
 	rhp = (struct c4iw_dev *) ibdev;
 	pdid =  c4iw_get_resource(&rhp->rdev.resource.pdid_table);
 	if (!pdid)
-		return ERR_PTR(-EINVAL);
-	php = kzalloc(sizeof(*php), GFP_KERNEL);
-	if (!php) {
-		c4iw_put_resource(&rhp->rdev.resource.pdid_table, pdid);
-		return ERR_PTR(-ENOMEM);
-	}
+		return -EINVAL;
+
 	php->pdid = pdid;
 	php->rhp = rhp;
-	if (context) {
+	if (udata) {
 		if (ib_copy_to_udata(udata, &php->pdid, sizeof(u32))) {
-			c4iw_deallocate_pd(&php->ibpd);
-			return ERR_PTR(-EFAULT);
+			c4iw_deallocate_pd(&php->ibpd, udata);
+			return -EFAULT;
 		}
 	}
 	mutex_lock(&rhp->rdev.stats.lock);
@@ -276,10 +251,10 @@ c4iw_allocate_pd(struct ib_device *ibdev, struct ib_ucontext *context,
 		rhp->rdev.stats.pd.max = rhp->rdev.stats.pd.cur;
 	mutex_unlock(&rhp->rdev.stats.lock);
 
-	CTR6(KTR_IW_CXGBE,
+	CTR5(KTR_IW_CXGBE,
 	    "%s: ibdev %p, context %p, data %p, pddid 0x%x, pd %p", __func__,
-	    ibdev, context, udata, pdid, php);
-	return (&php->ibpd);
+	    ibdev, udata, pdid, php);
+	return (0);
 }
 
 static int
@@ -436,6 +411,13 @@ c4iw_register_device(struct c4iw_dev *dev)
 	ret = linux_pci_attach_device(sc->dev, NULL, NULL, &dev->pdev);
 	if (ret)
 		return (ret);
+
+#define	c4iw_ib_cq c4iw_cq
+#define	c4iw_ib_pd c4iw_pd
+#define	c4iw_ib_qp c4iw_qp
+#define	c4iw_ib_ucontext c4iw_ucontext
+	INIT_IB_DEVICE_OPS(&ibdev->ops, c4iw, CXGB4);
+
 	strlcpy(ibdev->name, device_get_nameunit(sc->dev), sizeof(ibdev->name));
 	memset(&ibdev->node_guid, 0, sizeof(ibdev->node_guid));
 	memcpy(&ibdev->node_guid, sc->port[0]->vi[0].hw_addr, ETHER_ADDR_LEN);
diff --git a/sys/dev/cxgbe/iw_cxgbe/qp.c b/sys/dev/cxgbe/iw_cxgbe/qp.c
index c1006109762c..b2901f93988e 100644
--- a/sys/dev/cxgbe/iw_cxgbe/qp.c
+++ b/sys/dev/cxgbe/iw_cxgbe/qp.c
@@ -583,8 +583,6 @@ static void free_qp_work(struct work_struct *work)
 	destroy_qp(&rhp->rdev, &qhp->wq,
 		   ucontext ? &ucontext->uctx : &rhp->rdev.uctx);
 
-	if (ucontext)
-		c4iw_put_ucontext(ucontext);
 	kfree(qhp);
 }
 
@@ -1678,7 +1676,7 @@ out:
 	return ret;
 }
 
-int c4iw_destroy_qp(struct ib_qp *ib_qp)
+int c4iw_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
 {
 	struct c4iw_dev *rhp;
 	struct c4iw_qp *qhp;
@@ -1879,7 +1877,6 @@ c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
 				rq_db_key_mm->len);
 		insert_mmap(ucontext, rq_db_key_mm);
 
-		c4iw_get_ucontext(ucontext);
 		qhp->ucontext = ucontext;
 	}
 	qhp->ibqp.qp_num = qhp->wq.sq.qid;
diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib.h b/sys/dev/mlx4/mlx4_ib/mlx4_ib.h
index 544ed1913419..60b1de77a81b 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib.h
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib.h
@@ -83,16 +83,11 @@ enum hw_bar_type {
 	HW_BAR_COUNT
 };
 
-struct mlx4_ib_vma_private_data {
-	struct vm_area_struct *vma;
-};
-
 struct mlx4_ib_ucontext {
 	struct ib_ucontext	ibucontext;
 	struct mlx4_uar		uar;
 	struct list_head	db_page_list;
 	struct mutex		db_page_mutex;
-	struct mlx4_ib_vma_private_data hw_bar_info[HW_BAR_COUNT];
 };
 
 struct mlx4_ib_pd {
@@ -726,39 +721,37 @@ int mlx4_ib_umem_write_mtt(struct mlx4_ib_dev *dev, struct mlx4_mtt *mtt,
 struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 				  u64 virt_addr, int access_flags,
 				  struct ib_udata *udata);
-int mlx4_ib_dereg_mr(struct ib_mr *mr);
+int mlx4_ib_dereg_mr(struct ib_mr *mr, struct ib_udata *udata);
 struct ib_mw *mlx4_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
 			       struct ib_udata *udata);
 int mlx4_ib_dealloc_mw(struct ib_mw *mw);
-struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd,
-			       enum ib_mr_type mr_type,
-			       u32 max_num_sg);
+struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
+			       u32 max_num_sg, struct ib_udata *udata);
 int mlx4_ib_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
 		      unsigned int *sg_offset);
 int mlx4_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period);
 int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata);
-struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
-				const struct ib_cq_init_attr *attr,
-				struct ib_ucontext *context,
-				struct ib_udata *udata);
-int mlx4_ib_destroy_cq(struct ib_cq *cq);
+int mlx4_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
+		      struct ib_udata *udata);
+void mlx4_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
 int mlx4_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
 int mlx4_ib_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
 void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
 void mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
 
-struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
-				struct ib_udata *udata);
+int mlx4_ib_create_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr, u32 flags,
+		      struct ib_udata *udata);
+int mlx4_ib_create_ah_slave(struct ib_ah *ah, struct ib_ah_attr *ah_attr,
+			    int slave_sgid_index, u8 *s_mac, u16 vlan_tag);
 int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr);
-int mlx4_ib_destroy_ah(struct ib_ah *ah);
+void mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags);
 
-struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
-				  struct ib_srq_init_attr *init_attr,
-				  struct ib_udata *udata);
+int mlx4_ib_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *init_attr,
+		       struct ib_udata *udata);
 int mlx4_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
 		       enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
 int mlx4_ib_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
-int mlx4_ib_destroy_srq(struct ib_srq *srq);
+void mlx4_ib_destroy_srq(struct ib_srq *srq, struct ib_udata *udata);
 void mlx4_ib_free_srq_wqe(struct mlx4_ib_srq *srq, int wqe_index);
 int mlx4_ib_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
 			  const struct ib_recv_wr **bad_wr);
@@ -766,7 +759,7 @@ int mlx4_ib_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
 struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
 				struct ib_qp_init_attr *init_attr,
 				struct ib_udata *udata);
-int mlx4_ib_destroy_qp(struct ib_qp *qp);
+int mlx4_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata);
 int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 		      int attr_mask, struct ib_udata *udata);
 int mlx4_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,
diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_ah.c b/sys/dev/mlx4/mlx4_ib/mlx4_ib_ah.c
index 33c0f9e6b4e2..bb924a08fabb 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_ah.c
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_ah.c
@@ -42,10 +42,11 @@
 
 #include "mlx4_ib.h"
 
-static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
-				  struct mlx4_ib_ah *ah)
+static int create_ib_ah(struct ib_ah *ib_ah, struct ib_ah_attr *ah_attr)
 {
-	struct mlx4_dev *dev = to_mdev(pd->device)->dev;
+	struct ib_pd *pd = ib_ah->pd;
+	struct mlx4_ib_ah *ah = to_mah(ib_ah);
+	struct mlx4_dev *dev = to_mdev(ib_ah->device)->dev;
 
 	ah->av.ib.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
 	ah->av.ib.g_slid  = ah_attr->src_path_bits;
@@ -67,14 +68,14 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
 		       !(1 << ah->av.ib.stat_rate & dev->caps.stat_rate_support))
 			--ah->av.ib.stat_rate;
 	}
-
-	return &ah->ibah;
+	return 0;
 }
 
-static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
-				    struct mlx4_ib_ah *ah)
+static int create_iboe_ah(struct ib_ah *ib_ah, struct ib_ah_attr *ah_attr)
 {
-	struct mlx4_ib_dev *ibdev = to_mdev(pd->device);
+	struct ib_pd *pd = ib_ah->pd;
+	struct mlx4_ib_dev *ibdev = to_mdev(ib_ah->device);
+	struct mlx4_ib_ah *ah = to_mah(ib_ah);
 	struct mlx4_dev *dev = ibdev->dev;
 	int is_mcast = 0;
 	struct in6_addr in6;
@@ -93,7 +94,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
 	ret = ib_get_cached_gid(pd->device, ah_attr->port_num,
 				ah_attr->grh.sgid_index, &sgid, &gid_attr);
 	if (ret)
-		return ERR_PTR(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);
@@ -105,7 +106,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
 	ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
 	ret = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index);
 	if (ret < 0)
-		return ERR_PTR(ret);
+		return ret;
 	ah->av.eth.gid_index = ret;
 	ah->av.eth.vlan = cpu_to_be16(vlan_tag);
 	ah->av.eth.hop_limit = ah_attr->grh.hop_limit;
@@ -125,23 +126,15 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
 	memcpy(ah->av.eth.dgid, ah_attr->grh.dgid.raw, 16);
 	ah->av.eth.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 29);
 
-	return &ah->ibah;
+	return 0;
 }
 
-struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
-				struct ib_udata *udata)
-
+int mlx4_ib_create_ah(struct ib_ah *ib_ah, struct ib_ah_attr *ah_attr,
+		      u32 flags, struct ib_udata *udata)
 {
-	struct mlx4_ib_ah *ah;
-	struct ib_ah *ret;
-
-	ah = kzalloc(sizeof *ah, GFP_ATOMIC);
-	if (!ah)
-		return ERR_PTR(-ENOMEM);
-
-	if (rdma_port_get_link_layer(pd->device, ah_attr->port_num) == IB_LINK_LAYER_ETHERNET) {
+	if (rdma_port_get_link_layer(ib_ah->pd->device, ah_attr->port_num) == IB_LINK_LAYER_ETHERNET) {
 		if (!(ah_attr->ah_flags & IB_AH_GRH)) {
-			ret = ERR_PTR(-EINVAL);
+			return -EINVAL;
 		} else {
 			/*
 			 * TBD: need to handle the case when we get
@@ -151,15 +144,35 @@ struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
 			 * local addresses which we can translate
 			 * without going to sleep.
 			 */
-			ret = create_iboe_ah(pd, ah_attr, ah);
+			return create_iboe_ah(ib_ah, ah_attr);
 		}
+	}
+	return create_ib_ah(ib_ah, ah_attr);
+}
 
-		if (IS_ERR(ret))
-			kfree(ah);
+int mlx4_ib_create_ah_slave(struct ib_ah *ah, struct ib_ah_attr *ah_attr,
+			    int slave_sgid_index, u8 *s_mac, u16 vlan_tag)
+{
+	struct ib_ah_attr slave_attr = *ah_attr;
+	struct mlx4_ib_ah *mah = to_mah(ah);
+	int ret;
 
+	slave_attr.grh.sgid_index = slave_sgid_index;
+	ret = mlx4_ib_create_ah(ah, &slave_attr, 0, NULL);
+	if (ret)
 		return ret;
-	} else
-		return create_ib_ah(pd, ah_attr, ah); /* never fails */
+
+	/* get rid of force-loopback bit */
+	mah->av.ib.port_pd &= cpu_to_be32(0x7FFFFFFF);
+
+	if (rdma_port_get_link_layer(ah->pd->device, ah_attr->port_num) == IB_LINK_LAYER_ETHERNET)
+		memcpy(mah->av.eth.s_mac, s_mac, 6);
+
+	if (vlan_tag < 0x1000)
+		vlan_tag |= (ah_attr->sl & 7) << 13;
+	mah->av.eth.vlan = cpu_to_be16(vlan_tag);
+
+	return 0;
 }
 
 int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
@@ -195,8 +208,7 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
 	return 0;
 }
 
-int mlx4_ib_destroy_ah(struct ib_ah *ah)
+void mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags)
 {
-	kfree(to_mah(ah));
-	return 0;
+	return;
 }
diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_cq.c b/sys/dev/mlx4/mlx4_ib/mlx4_ib_cq.c
index 215c428e7af7..87845ef1f17b 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_cq.c
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_cq.c
@@ -39,6 +39,7 @@
 
 #include "mlx4_ib.h"
 #include <rdma/mlx4-abi.h>
+#include <rdma/uverbs_ioctl.h>
 
 static void mlx4_ib_cq_comp(struct mlx4_cq *cq)
 {
@@ -135,14 +136,16 @@ static void mlx4_ib_free_cq_buf(struct mlx4_ib_dev *dev, struct mlx4_ib_cq_buf *
 	mlx4_buf_free(dev->dev, (cqe + 1) * buf->entry_size, &buf->buf);
 }
 
-static int mlx4_ib_get_cq_umem(struct mlx4_ib_dev *dev, struct ib_ucontext *context,
-			       struct mlx4_ib_cq_buf *buf, struct ib_umem **umem,
-			       u64 buf_addr, int cqe)
+static int mlx4_ib_get_cq_umem(struct mlx4_ib_dev *dev, struct ib_udata *udata,
+			       struct mlx4_ib_cq_buf *buf,
+			       struct ib_umem **umem, u64 buf_addr, int cqe)
 {
 	int err;
 	int cqe_size = dev->dev->caps.cqe_size;
+	struct mlx4_ib_ucontext *context = rdma_udata_to_drv_context(
+		udata, struct mlx4_ib_ucontext, ibucontext);
 
-	*umem = ib_umem_get(context, buf_addr, cqe * cqe_size,
+	*umem = ib_umem_get(&context->ibucontext, buf_addr, cqe * cqe_size,
 			    IB_ACCESS_LOCAL_WRITE, 1);
 	if (IS_ERR(*umem))
 		return PTR_ERR(*umem);
@@ -168,27 +171,25 @@ err_buf:
 }
 
 #define CQ_CREATE_FLAGS_SUPPORTED IB_CQ_FLAGS_TIMESTAMP_COMPLETION
-struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
-				const struct ib_cq_init_attr *attr,
-				struct ib_ucontext *context,
-				struct ib_udata *udata)
+int mlx4_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
+		      struct ib_udata *udata)
 {
+	struct ib_device *ibdev = ibcq->device;
 	int entries = attr->cqe;
 	int vector = attr->comp_vector;
 	struct mlx4_ib_dev *dev = to_mdev(ibdev);
-	struct mlx4_ib_cq *cq;
+	struct mlx4_ib_cq *cq = to_mcq(ibcq);
 	struct mlx4_uar *uar;
+	void *buf_addr;
 	int err;
+	struct mlx4_ib_ucontext *context = rdma_udata_to_drv_context(
+		udata, struct mlx4_ib_ucontext, ibucontext);
 
 	if (entries < 1 || entries > dev->dev->caps.max_cqes)
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 
 	if (attr->flags & ~CQ_CREATE_FLAGS_SUPPORTED)
-		return ERR_PTR(-EINVAL);
-
-	cq = kmalloc(sizeof *cq, GFP_KERNEL);
-	if (!cq)
-		return ERR_PTR(-ENOMEM);
+		return -EINVAL;
 
 	entries      = roundup_pow_of_two(entries + 1);
 	cq->ibcq.cqe = entries - 1;
@@ -200,7 +201,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
 	INIT_LIST_HEAD(&cq->send_qp_list);
 	INIT_LIST_HEAD(&cq->recv_qp_list);
 
-	if (context) {
+	if (udata) {
 		struct mlx4_ib_create_cq ucmd;
 
 		if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) {
@@ -208,17 +209,17 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
 			goto err_cq;
 		}
 
-		err = mlx4_ib_get_cq_umem(dev, context, &cq->buf, &cq->umem,
+		buf_addr = (void *)(unsigned long)ucmd.buf_addr;
+		err = mlx4_ib_get_cq_umem(dev, udata, &cq->buf, &cq->umem,
 					  ucmd.buf_addr, entries);
 		if (err)
 			goto err_cq;
 
-		err = mlx4_ib_db_map_user(to_mucontext(context), ucmd.db_addr,
-					  &cq->db);
+		err = mlx4_ib_db_map_user(context, ucmd.db_addr, &cq->db);
 		if (err)
 			goto err_mtt;
 
-		uar = &to_mucontext(context)->uar;
+		uar = &context->uar;
 	} else {
 		err = mlx4_db_alloc(dev->dev, &cq->db, 1, GFP_KERNEL);
 		if (err)
@@ -233,6 +234,8 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
 		if (err)
 			goto err_db;
 
+		buf_addr = &cq->buf.buf;
+
 		uar = &dev->priv_uar;
 	}
 
@@ -248,37 +251,33 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
 	cq->mcq.comp = mlx4_ib_cq_comp;
 	cq->mcq.event = mlx4_ib_cq_event;
 
*** 28581 LINES SKIPPED ***


More information about the dev-commits-src-main mailing list