Re: [PATCH rdma-next 4/4] RDMA: Handle SRQ allocations by IB/core

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 3/26/19 7:56 AM, Leon Romanovsky wrote:
> From: Leon Romanovsky <leonro@xxxxxxxxxxxx>
> 
> Convert SRQ allocation from drivers to be in the IB/core
> 
> Reuse knowledge of SRQ allocation and clean ib_destroy_srq() to perform
> SRQ destroy in the opposite order of allocation: first decrease counters
> and after release object.

vmw_pvrdma conversion looks fine to me.

Acked-by: Adit Ranadive <aditr@xxxxxxxxxx>

> 
> Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx>
> ---
>  drivers/infiniband/core/device.c              |  1 +
>  drivers/infiniband/core/uverbs_cmd.c          | 13 +++-
>  drivers/infiniband/core/verbs.c               | 76 ++++++++++---------
>  drivers/infiniband/hw/bnxt_re/ib_verbs.c      | 32 +++-----
>  drivers/infiniband/hw/bnxt_re/ib_verbs.h      | 10 +--
>  drivers/infiniband/hw/bnxt_re/main.c          |  1 +
>  drivers/infiniband/hw/bnxt_re/qplib_fp.c      | 12 ++-
>  drivers/infiniband/hw/bnxt_re/qplib_fp.h      |  4 +-
>  drivers/infiniband/hw/cxgb4/iw_cxgb4.h        |  7 +-
>  drivers/infiniband/hw/cxgb4/provider.c        |  1 +
>  drivers/infiniband/hw/cxgb4/qp.c              | 32 +++-----
>  drivers/infiniband/hw/hns/hns_roce_device.h   |  8 +-
>  drivers/infiniband/hw/hns/hns_roce_main.c     |  2 +
>  drivers/infiniband/hw/hns/hns_roce_srq.c      | 52 +++++--------
>  drivers/infiniband/hw/mlx4/main.c             |  1 +
>  drivers/infiniband/hw/mlx4/mlx4_ib.h          |  7 +-
>  drivers/infiniband/hw/mlx4/srq.c              | 47 ++++--------
>  drivers/infiniband/hw/mlx5/main.c             | 36 ++++++---
>  drivers/infiniband/hw/mlx5/mlx5_ib.h          |  7 +-
>  drivers/infiniband/hw/mlx5/srq.c              | 59 ++++++--------
>  drivers/infiniband/hw/mlx5/srq.h              |  2 +-
>  drivers/infiniband/hw/mlx5/srq_cmd.c          |  8 +-
>  drivers/infiniband/hw/mthca/mthca_provider.c  | 53 +++++--------
>  drivers/infiniband/hw/ocrdma/ocrdma_hw.c      |  8 +-
>  drivers/infiniband/hw/ocrdma/ocrdma_hw.h      |  2 +-
>  drivers/infiniband/hw/ocrdma/ocrdma_main.c    |  2 +
>  drivers/infiniband/hw/ocrdma/ocrdma_verbs.c   | 47 +++++-------
>  drivers/infiniband/hw/ocrdma/ocrdma_verbs.h   |  6 +-
>  drivers/infiniband/hw/qedr/main.c             |  1 +
>  drivers/infiniband/hw/qedr/verbs.c            | 32 +++-----
>  drivers/infiniband/hw/qedr/verbs.h            |  7 +-
>  .../infiniband/hw/vmw_pvrdma/pvrdma_main.c    |  2 +
>  drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c | 42 ++++------
>  .../infiniband/hw/vmw_pvrdma/pvrdma_verbs.h   |  7 +-
>  drivers/infiniband/sw/rdmavt/srq.c            | 43 ++++-------
>  drivers/infiniband/sw/rdmavt/srq.h            |  7 +-
>  drivers/infiniband/sw/rdmavt/vt.c             |  1 +
>  drivers/infiniband/sw/rxe/rxe_pool.c          |  2 +-
>  drivers/infiniband/sw/rxe/rxe_verbs.c         | 31 +++-----
>  drivers/infiniband/sw/rxe/rxe_verbs.h         |  2 +-
>  include/rdma/ib_verbs.h                       |  9 ++-
>  41 files changed, 311 insertions(+), 411 deletions(-)
> 
> diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
> index dad531f2d82a..77342829655e 100644
> --- a/drivers/infiniband/core/device.c
> +++ b/drivers/infiniband/core/device.c
> @@ -2366,6 +2366,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
>  
>  	SET_OBJ_SIZE(dev_ops, ib_ah);
>  	SET_OBJ_SIZE(dev_ops, ib_pd);
> +	SET_OBJ_SIZE(dev_ops, ib_srq);
>  	SET_OBJ_SIZE(dev_ops, ib_ucontext);
>  }
>  EXPORT_SYMBOL(ib_set_device_ops);
> diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
> index 062a86c04123..af0f1c4ba613 100644
> --- a/drivers/infiniband/core/uverbs_cmd.c
> +++ b/drivers/infiniband/core/uverbs_cmd.c
> @@ -3411,9 +3411,9 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
>  	obj->uevent.events_reported = 0;
>  	INIT_LIST_HEAD(&obj->uevent.event_list);
>  
> -	srq = pd->device->ops.create_srq(pd, &attr, udata);
> -	if (IS_ERR(srq)) {
> -		ret = PTR_ERR(srq);
> +	srq = rdma_zalloc_drv_obj(ib_dev, ib_srq);
> +	if (!srq) {
> +		ret = -ENOMEM;
>  		goto err_put;
>  	}
>  
> @@ -3424,6 +3424,10 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
>  	srq->event_handler = attr.event_handler;
>  	srq->srq_context   = attr.srq_context;
>  
> +	ret = pd->device->ops.create_srq(srq, &attr, udata);
> +	if (ret)
> +		goto err_free;
> +
>  	if (ib_srq_has_cq(cmd->srq_type)) {
>  		srq->ext.cq       = attr.ext.cq;
>  		atomic_inc(&attr.ext.cq->usecnt);
> @@ -3462,7 +3466,8 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
>  
>  err_copy:
>  	ib_destroy_srq(srq);
> -
> +err_free:
> +	kfree(srq);
>  err_put:
>  	uobj_put_obj_read(pd);
>  
> diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
> index cd37a13af11f..ea3cd0fb6665 100644
> --- a/drivers/infiniband/core/verbs.c
> +++ b/drivers/infiniband/core/verbs.c
> @@ -961,31 +961,38 @@ struct ib_srq *ib_create_srq(struct ib_pd *pd,
>  			     struct ib_srq_init_attr *srq_init_attr)
>  {
>  	struct ib_srq *srq;
> +	int ret;
>  
>  	if (!pd->device->ops.create_srq)
>  		return ERR_PTR(-EOPNOTSUPP);
>  
> -	srq = pd->device->ops.create_srq(pd, srq_init_attr, NULL);
> -
> -	if (!IS_ERR(srq)) {
> -		srq->device    	   = pd->device;
> -		srq->pd        	   = pd;
> -		srq->uobject       = NULL;
> -		srq->event_handler = srq_init_attr->event_handler;
> -		srq->srq_context   = srq_init_attr->srq_context;
> -		srq->srq_type      = srq_init_attr->srq_type;
> -		if (ib_srq_has_cq(srq->srq_type)) {
> -			srq->ext.cq   = srq_init_attr->ext.cq;
> -			atomic_inc(&srq->ext.cq->usecnt);
> -		}
> -		if (srq->srq_type == IB_SRQT_XRC) {
> -			srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd;
> -			atomic_inc(&srq->ext.xrc.xrcd->usecnt);
> -		}
> -		atomic_inc(&pd->usecnt);
> -		atomic_set(&srq->usecnt, 0);
> +	srq = rdma_zalloc_drv_obj(pd->device, ib_srq);
> +	if (!srq)
> +		return ERR_PTR(-ENOMEM);
> +
> +	srq->device = pd->device;
> +	srq->pd = pd;
> +	srq->event_handler = srq_init_attr->event_handler;
> +	srq->srq_context = srq_init_attr->srq_context;
> +	srq->srq_type = srq_init_attr->srq_type;
> +
> +	ret = pd->device->ops.create_srq(srq, srq_init_attr, NULL);
> +	if (ret) {
> +		kfree(srq);
> +		return ERR_PTR(ret);
>  	}
>  
> +	if (ib_srq_has_cq(srq->srq_type)) {
> +		srq->ext.cq = srq_init_attr->ext.cq;
> +		atomic_inc(&srq->ext.cq->usecnt);
> +	}
> +	if (srq->srq_type == IB_SRQT_XRC) {
> +		srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd;
> +		atomic_inc(&srq->ext.xrc.xrcd->usecnt);
> +	}
> +	atomic_inc(&pd->usecnt);
> +	atomic_set(&srq->usecnt, 0);
> +
>  	return srq;
>  }
>  EXPORT_SYMBOL(ib_create_srq);
> @@ -1011,31 +1018,30 @@ EXPORT_SYMBOL(ib_query_srq);
>  int ib_destroy_srq(struct ib_srq *srq)
>  {
>  	struct ib_pd *pd;
> -	enum ib_srq_type srq_type;
> -	struct ib_xrcd *uninitialized_var(xrcd);
> -	struct ib_cq *uninitialized_var(cq);
> -	int ret;
>  
>  	if (atomic_read(&srq->usecnt))
>  		return -EBUSY;
>  
>  	pd = srq->pd;
> -	srq_type = srq->srq_type;
> -	if (ib_srq_has_cq(srq_type))
> -		cq = srq->ext.cq;
> -	if (srq_type == IB_SRQT_XRC)
> +	atomic_dec(&pd->usecnt);
> +
> +	if (srq->srq_type == IB_SRQT_XRC) {
> +		struct ib_xrcd *xrcd;
> +
>  		xrcd = srq->ext.xrc.xrcd;
> +		atomic_dec(&xrcd->usecnt);
> +	}
> +	if (ib_srq_has_cq(srq->srq_type)) {
> +		struct ib_cq *cq;
>  
> -	ret = srq->device->ops.destroy_srq(srq);
> -	if (!ret) {
> -		atomic_dec(&pd->usecnt);
> -		if (srq_type == IB_SRQT_XRC)
> -			atomic_dec(&xrcd->usecnt);
> -		if (ib_srq_has_cq(srq_type))
> -			atomic_dec(&cq->usecnt);
> +		cq = srq->ext.cq;
> +		atomic_dec(&cq->usecnt);
>  	}
>  
> -	return ret;
> +	srq->device->ops.destroy_srq(srq);
> +	kfree(srq);
> +
> +	return 0;
>  }
>  EXPORT_SYMBOL(ib_destroy_srq);
>  
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> index aef84fb73aca..acb7218618a4 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> @@ -1306,30 +1306,22 @@ static enum ib_mtu __to_ib_mtu(u32 mtu)
>  }
>  
>  /* Shared Receive Queues */
> -int bnxt_re_destroy_srq(struct ib_srq *ib_srq)
> +void bnxt_re_destroy_srq(struct ib_srq *ib_srq)
>  {
>  	struct bnxt_re_srq *srq = container_of(ib_srq, struct bnxt_re_srq,
>  					       ib_srq);
>  	struct bnxt_re_dev *rdev = srq->rdev;
>  	struct bnxt_qplib_srq *qplib_srq = &srq->qplib_srq;
>  	struct bnxt_qplib_nq *nq = NULL;
> -	int rc;
>  
>  	if (qplib_srq->cq)
>  		nq = qplib_srq->cq->nq;
> -	rc = bnxt_qplib_destroy_srq(&rdev->qplib_res, qplib_srq);
> -	if (rc) {
> -		dev_err(rdev_to_dev(rdev), "Destroy HW SRQ failed!");
> -		return rc;
> -	}
> -
> +	bnxt_qplib_destroy_srq(&rdev->qplib_res, qplib_srq);
>  	if (srq->umem)
>  		ib_umem_release(srq->umem);
> -	kfree(srq);
>  	atomic_dec(&rdev->srq_count);
>  	if (nq)
>  		nq->budget--;
> -	return 0;
>  }
>  
>  static int bnxt_re_init_user_srq(struct bnxt_re_dev *rdev,
> @@ -1362,14 +1354,16 @@ static int bnxt_re_init_user_srq(struct bnxt_re_dev *rdev,
>  	return 0;
>  }
>  
> -struct ib_srq *bnxt_re_create_srq(struct ib_pd *ib_pd,
> -				  struct ib_srq_init_attr *srq_init_attr,
> -				  struct ib_udata *udata)
> +int bnxt_re_create_srq(struct ib_srq *ib_srq,
> +		       struct ib_srq_init_attr *srq_init_attr,
> +		       struct ib_udata *udata)
>  {
> +	struct ib_pd *ib_pd = ib_srq->pd;
>  	struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
>  	struct bnxt_re_dev *rdev = pd->rdev;
>  	struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
> -	struct bnxt_re_srq *srq;
> +	struct bnxt_re_srq *srq =
> +		container_of(ib_srq, struct bnxt_re_srq, ib_srq);
>  	struct bnxt_qplib_nq *nq = NULL;
>  	int rc, entries;
>  
> @@ -1384,11 +1378,6 @@ struct ib_srq *bnxt_re_create_srq(struct ib_pd *ib_pd,
>  		goto exit;
>  	}
>  
> -	srq = kzalloc(sizeof(*srq), GFP_KERNEL);
> -	if (!srq) {
> -		rc = -ENOMEM;
> -		goto exit;
> -	}
>  	srq->rdev = rdev;
>  	srq->qplib_srq.pd = &pd->qplib_pd;
>  	srq->qplib_srq.dpi = &rdev->dpi_privileged;
> @@ -1434,14 +1423,13 @@ struct ib_srq *bnxt_re_create_srq(struct ib_pd *ib_pd,
>  		nq->budget++;
>  	atomic_inc(&rdev->srq_count);
>  
> -	return &srq->ib_srq;
> +	return 0;
>  
>  fail:
>  	if (srq->umem)
>  		ib_umem_release(srq->umem);
> -	kfree(srq);
>  exit:
> -	return ERR_PTR(rc);
> +	return rc;
>  }
>  
>  int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr,
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> index 1150cd369588..c59a93dc4926 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> @@ -69,9 +69,9 @@ struct bnxt_re_ah {
>  };
>  
>  struct bnxt_re_srq {
> +	struct ib_srq		ib_srq;
>  	struct bnxt_re_dev	*rdev;
>  	u32			srq_limit;
> -	struct ib_srq		ib_srq;
>  	struct bnxt_qplib_srq	qplib_srq;
>  	struct ib_umem		*umem;
>  	spinlock_t		lock;		/* protect srq */
> @@ -171,14 +171,14 @@ int bnxt_re_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr, u32 flags,
>  int bnxt_re_modify_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
>  int bnxt_re_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
>  void bnxt_re_destroy_ah(struct ib_ah *ah, u32 flags);
> -struct ib_srq *bnxt_re_create_srq(struct ib_pd *pd,
> -				  struct ib_srq_init_attr *srq_init_attr,
> -				  struct ib_udata *udata);
> +int bnxt_re_create_srq(struct ib_srq *srq,
> +		       struct ib_srq_init_attr *srq_init_attr,
> +		       struct ib_udata *udata);
>  int bnxt_re_modify_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr,
>  		       enum ib_srq_attr_mask srq_attr_mask,
>  		       struct ib_udata *udata);
>  int bnxt_re_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
> -int bnxt_re_destroy_srq(struct ib_srq *srq);
> +void bnxt_re_destroy_srq(struct ib_srq *srq);
>  int bnxt_re_post_srq_recv(struct ib_srq *srq, const struct ib_recv_wr *recv_wr,
>  			  const struct ib_recv_wr **bad_recv_wr);
>  struct ib_qp *bnxt_re_create_qp(struct ib_pd *pd,
> diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> index ec22853f8363..bbdfbbf5e9a5 100644
> --- a/drivers/infiniband/hw/bnxt_re/main.c
> +++ b/drivers/infiniband/hw/bnxt_re/main.c
> @@ -639,6 +639,7 @@ static const struct ib_device_ops bnxt_re_dev_ops = {
>  	.req_notify_cq = bnxt_re_req_notify_cq,
>  	INIT_RDMA_OBJ_SIZE(ib_ah, bnxt_re_ah, ib_ah),
>  	INIT_RDMA_OBJ_SIZE(ib_pd, bnxt_re_pd, ib_pd),
> +	INIT_RDMA_OBJ_SIZE(ib_srq, bnxt_re_srq, ib_srq),
>  	INIT_RDMA_OBJ_SIZE(ib_ucontext, bnxt_re_ucontext, ib_uctx),
>  };
>  
> diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
> index 71c34d5b0ac0..7f770d5b71b8 100644
> --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
> +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
> @@ -507,7 +507,7 @@ static void bnxt_qplib_arm_srq(struct bnxt_qplib_srq *srq, u32 arm_type)
>  	writeq(val, db);
>  }
>  
> -int bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res,
> +void bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res,
>  			   struct bnxt_qplib_srq *srq)
>  {
>  	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
> @@ -521,14 +521,12 @@ int bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res,
>  	/* Configure the request */
>  	req.srq_cid = cpu_to_le32(srq->id);
>  
> -	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
> -					  (void *)&resp, NULL, 0);
> +	rc = bnxt_qplib_rcfw_send_message(rcfw, (struct cmdq_base *)&req,
> +					  (struct creq_base *)&resp, NULL, 0);
> +	kfree(srq->swq);
>  	if (rc)
> -		return rc;
> -
> +		return;
>  	bnxt_qplib_free_hwq(res->pdev, &srq->hwq);
> -	kfree(srq->swq);
> -	return 0;
>  }
>  
>  int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
> diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
> index 3f618b5f1f06..4f378b0e54d2 100644
> --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
> +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
> @@ -521,8 +521,8 @@ int bnxt_qplib_modify_srq(struct bnxt_qplib_res *res,
>  			  struct bnxt_qplib_srq *srq);
>  int bnxt_qplib_query_srq(struct bnxt_qplib_res *res,
>  			 struct bnxt_qplib_srq *srq);
> -int bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res,
> -			   struct bnxt_qplib_srq *srq);
> +void bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res,
> +			    struct bnxt_qplib_srq *srq);
>  int bnxt_qplib_post_srq_recv(struct bnxt_qplib_srq *srq,
>  			     struct bnxt_qplib_swqe *wqe);
>  int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp);
> diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> index 4c918fe2430e..577b4d0fd992 100644
> --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> @@ -1002,10 +1002,9 @@ int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
>  int c4iw_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *attr,
>  		    enum ib_srq_attr_mask srq_attr_mask,
>  		    struct ib_udata *udata);
> -int c4iw_destroy_srq(struct ib_srq *ib_srq);
> -struct ib_srq *c4iw_create_srq(struct ib_pd *pd,
> -			       struct ib_srq_init_attr *attrs,
> -			       struct ib_udata *udata);
> +void c4iw_destroy_srq(struct ib_srq *ib_srq);
> +int c4iw_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *attrs,
> +		    struct ib_udata *udata);
>  int c4iw_destroy_qp(struct ib_qp *ib_qp);
>  struct ib_qp *c4iw_create_qp(struct ib_pd *pd,
>  			     struct ib_qp_init_attr *attrs,
> diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
> index 507c54572cc9..6d9528c44357 100644
> --- a/drivers/infiniband/hw/cxgb4/provider.c
> +++ b/drivers/infiniband/hw/cxgb4/provider.c
> @@ -546,6 +546,7 @@ static const struct ib_device_ops c4iw_dev_ops = {
>  	.reg_user_mr = c4iw_reg_user_mr,
>  	.req_notify_cq = c4iw_arm_cq,
>  	INIT_RDMA_OBJ_SIZE(ib_pd, c4iw_pd, ibpd),
> +	INIT_RDMA_OBJ_SIZE(ib_srq, c4iw_srq, ibsrq),
>  	INIT_RDMA_OBJ_SIZE(ib_ucontext, c4iw_ucontext, ibucontext),
>  };
>  
> diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
> index b2ae5b40cc3e..90f7080ac491 100644
> --- a/drivers/infiniband/hw/cxgb4/qp.c
> +++ b/drivers/infiniband/hw/cxgb4/qp.c
> @@ -2683,11 +2683,12 @@ void c4iw_copy_wr_to_srq(struct t4_srq *srq, union t4_recv_wr *wqe, u8 len16)
>  	}
>  }
>  
> -struct ib_srq *c4iw_create_srq(struct ib_pd *pd, struct ib_srq_init_attr *attrs,
> +int c4iw_create_srq(struct ib_srq *ib_srq, struct ib_srq_init_attr *attrs,
>  			       struct ib_udata *udata)
>  {
> +	struct ib_pd *pd = ib_srq->pd;
>  	struct c4iw_dev *rhp;
> -	struct c4iw_srq *srq;
> +	struct c4iw_srq *srq = to_c4iw_srq(ib_srq);
>  	struct c4iw_pd *php;
>  	struct c4iw_create_srq_resp uresp;
>  	struct c4iw_ucontext *ucontext;
> @@ -2702,11 +2703,11 @@ struct ib_srq *c4iw_create_srq(struct ib_pd *pd, struct ib_srq_init_attr *attrs,
>  	rhp = php->rhp;
>  
>  	if (!rhp->rdev.lldi.vr->srq.size)
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	if (attrs->attr.max_wr > rhp->rdev.hw_queue.t4_max_rq_size)
> -		return ERR_PTR(-E2BIG);
> +		return -E2BIG;
>  	if (attrs->attr.max_sge > T4_MAX_RECV_SGE)
> -		return ERR_PTR(-E2BIG);
> +		return -E2BIG;
>  
>  	/*
>  	 * SRQ RQT and RQ must be a power of 2 and at least 16 deep.
> @@ -2717,15 +2718,9 @@ struct ib_srq *c4iw_create_srq(struct ib_pd *pd, struct ib_srq_init_attr *attrs,
>  	ucontext = rdma_udata_to_drv_context(udata, struct c4iw_ucontext,
>  					     ibucontext);
>  
> -	srq = kzalloc(sizeof(*srq), GFP_KERNEL);
> -	if (!srq)
> -		return ERR_PTR(-ENOMEM);
> -
>  	srq->wr_waitp = c4iw_alloc_wr_wait(GFP_KERNEL);
> -	if (!srq->wr_waitp) {
> -		ret = -ENOMEM;
> -		goto err_free_srq;
> -	}
> +	if (!srq->wr_waitp)
> +		return -ENOMEM;
>  
>  	srq->idx = c4iw_alloc_srq_idx(&rhp->rdev);
>  	if (srq->idx < 0) {
> @@ -2805,7 +2800,8 @@ struct ib_srq *c4iw_create_srq(struct ib_pd *pd, struct ib_srq_init_attr *attrs,
>  			(unsigned long)srq->wq.memsize, attrs->attr.max_wr);
>  
>  	spin_lock_init(&srq->lock);
> -	return &srq->ibsrq;
> +	return 0;
> +
>  err_free_srq_db_key_mm:
>  	kfree(srq_db_key_mm);
>  err_free_srq_key_mm:
> @@ -2821,12 +2817,10 @@ struct ib_srq *c4iw_create_srq(struct ib_pd *pd, struct ib_srq_init_attr *attrs,
>  	c4iw_free_srq_idx(&rhp->rdev, srq->idx);
>  err_free_wr_wait:
>  	c4iw_put_wr_wait(srq->wr_waitp);
> -err_free_srq:
> -	kfree(srq);
> -	return ERR_PTR(ret);
> +	return ret;
>  }
>  
> -int c4iw_destroy_srq(struct ib_srq *ibsrq)
> +void c4iw_destroy_srq(struct ib_srq *ibsrq)
>  {
>  	struct c4iw_dev *rhp;
>  	struct c4iw_srq *srq;
> @@ -2844,6 +2838,4 @@ int c4iw_destroy_srq(struct ib_srq *ibsrq)
>  		       srq->wr_waitp);
>  	c4iw_free_srq_idx(&rhp->rdev, srq->idx);
>  	c4iw_put_wr_wait(srq->wr_waitp);
> -	kfree(srq);
> -	return 0;
>  }
> diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
> index 876e88e8fc75..c04061af037c 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_device.h
> +++ b/drivers/infiniband/hw/hns/hns_roce_device.h
> @@ -1144,13 +1144,13 @@ int hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, u32 max_direct,
>  int hns_roce_ib_umem_write_mtt(struct hns_roce_dev *hr_dev,
>  			       struct hns_roce_mtt *mtt, struct ib_umem *umem);
>  
> -struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
> -				   struct ib_srq_init_attr *srq_init_attr,
> -				   struct ib_udata *udata);
> +int hns_roce_create_srq(struct ib_srq *srq,
> +			struct ib_srq_init_attr *srq_init_attr,
> +			struct ib_udata *udata);
>  int hns_roce_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr,
>  			enum ib_srq_attr_mask srq_attr_mask,
>  			struct ib_udata *udata);
> -int hns_roce_destroy_srq(struct ib_srq *ibsrq);
> +void hns_roce_destroy_srq(struct ib_srq *ibsrq);
>  
>  struct ib_qp *hns_roce_create_qp(struct ib_pd *ib_pd,
>  				 struct ib_qp_init_attr *init_attr,
> diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
> index ef28215adcbb..6ed73edf4727 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_main.c
> +++ b/drivers/infiniband/hw/hns/hns_roce_main.c
> @@ -490,6 +490,8 @@ static const struct ib_device_ops hns_roce_dev_frmr_ops = {
>  static const struct ib_device_ops hns_roce_dev_srq_ops = {
>  	.create_srq = hns_roce_create_srq,
>  	.destroy_srq = hns_roce_destroy_srq,
> +
> +	INIT_RDMA_OBJ_SIZE(ib_srq, hns_roce_srq, ibsrq),
>  };
>  
>  static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
> diff --git a/drivers/infiniband/hw/hns/hns_roce_srq.c b/drivers/infiniband/hw/hns/hns_roce_srq.c
> index a8ee2f6da967..af92909eeb09 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_srq.c
> +++ b/drivers/infiniband/hw/hns/hns_roce_srq.c
> @@ -206,13 +206,13 @@ static int hns_roce_create_idx_que(struct ib_pd *pd, struct hns_roce_srq *srq,
>  	return 0;
>  }
>  
> -struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
> -				   struct ib_srq_init_attr *srq_init_attr,
> -				   struct ib_udata *udata)
> +int hns_roce_create_srq(struct ib_srq *ib_srq,
> +			struct ib_srq_init_attr *srq_init_attr,
> +			struct ib_udata *udata)
>  {
> -	struct hns_roce_dev *hr_dev = to_hr_dev(pd->device);
> +	struct hns_roce_dev *hr_dev = to_hr_dev(ib_srq->device);
>  	struct hns_roce_ib_create_srq_resp resp = {};
> -	struct hns_roce_srq *srq;
> +	struct hns_roce_srq *srq = to_hr_srq(ib_srq);
>  	int srq_desc_size;
>  	int srq_buf_size;
>  	u32 page_shift;
> @@ -223,11 +223,7 @@ struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
>  	/* Check the actual SRQ wqe and SRQ sge num */
>  	if (srq_init_attr->attr.max_wr >= hr_dev->caps.max_srq_wrs ||
>  	    srq_init_attr->attr.max_sge > hr_dev->caps.max_srq_sges)
> -		return ERR_PTR(-EINVAL);
> -
> -	srq = kzalloc(sizeof(*srq), GFP_KERNEL);
> -	if (!srq)
> -		return ERR_PTR(-ENOMEM);
> +		return -EINVAL;
>  
>  	mutex_init(&srq->mutex);
>  	spin_lock_init(&srq->lock);
> @@ -249,17 +245,13 @@ struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
>  	if (udata) {
>  		struct hns_roce_ib_create_srq  ucmd;
>  
> -		if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
> -			ret = -EFAULT;
> -			goto err_srq;
> -		}
> +		if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)))
> +			return -EFAULT;
>  
>  		srq->umem =
>  			ib_umem_get(udata, ucmd.buf_addr, srq_buf_size, 0, 0);
> -		if (IS_ERR(srq->umem)) {
> -			ret = PTR_ERR(srq->umem);
> -			goto err_srq;
> -		}
> +		if (IS_ERR(srq->umem))
> +			return PTR_ERR(srq->umem);
>  
>  		if (hr_dev->caps.srqwqe_buf_pg_sz) {
>  			npages = (ib_umem_page_count(srq->umem) +
> @@ -321,11 +313,9 @@ struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
>  	} else {
>  		page_shift = PAGE_SHIFT + hr_dev->caps.srqwqe_buf_pg_sz;
>  		if (hns_roce_buf_alloc(hr_dev, srq_buf_size,
> -				      (1 << page_shift) * 2,
> -				      &srq->buf, page_shift)) {
> -			ret = -ENOMEM;
> -			goto err_srq;
> -		}
> +				       (1 << page_shift) * 2, &srq->buf,
> +				       page_shift))
> +			return -ENOMEM;
>  
>  		srq->head = 0;
>  		srq->tail = srq->max - 1;
> @@ -340,7 +330,7 @@ struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
>  			goto err_srq_mtt;
>  
>  		page_shift = PAGE_SHIFT + hr_dev->caps.idx_buf_pg_sz;
> -		ret = hns_roce_create_idx_que(pd, srq, page_shift);
> +		ret = hns_roce_create_idx_que(ib_srq->pd, srq, page_shift);
>  		if (ret) {
>  			dev_err(hr_dev->dev, "Create idx queue fail(%d)!\n",
>  				ret);
> @@ -372,7 +362,7 @@ struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
>  
>  	srq->db_reg_l = hr_dev->reg_base + SRQ_DB_REG;
>  
> -	ret = hns_roce_srq_alloc(hr_dev, to_hr_pd(pd)->pdn, cqn, 0,
> +	ret = hns_roce_srq_alloc(hr_dev, to_hr_pd(ib_srq->pd)->pdn, cqn, 0,
>  				 &srq->mtt, 0, srq);
>  	if (ret)
>  		goto err_wrid;
> @@ -389,7 +379,7 @@ struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
>  		}
>  	}
>  
> -	return &srq->ibsrq;
> +	return 0;
>  
>  err_srqc_alloc:
>  	hns_roce_srq_free(hr_dev, srq);
> @@ -418,12 +408,10 @@ struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
>  	else
>  		hns_roce_buf_free(hr_dev, srq_buf_size, &srq->buf);
>  
> -err_srq:
> -	kfree(srq);
> -	return ERR_PTR(ret);
> +	return ret;
>  }
>  
> -int hns_roce_destroy_srq(struct ib_srq *ibsrq)
> +void hns_roce_destroy_srq(struct ib_srq *ibsrq)
>  {
>  	struct hns_roce_dev *hr_dev = to_hr_dev(ibsrq->device);
>  	struct hns_roce_srq *srq = to_hr_srq(ibsrq);
> @@ -440,10 +428,6 @@ int hns_roce_destroy_srq(struct ib_srq *ibsrq)
>  		hns_roce_buf_free(hr_dev, srq->max << srq->wqe_shift,
>  				  &srq->buf);
>  	}
> -
> -	kfree(srq);
> -
> -	return 0;
>  }
>  
>  int hns_roce_init_srq_table(struct hns_roce_dev *hr_dev)
> diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
> index 535ec5c2704b..880d34349e79 100644
> --- a/drivers/infiniband/hw/mlx4/main.c
> +++ b/drivers/infiniband/hw/mlx4/main.c
> @@ -2562,6 +2562,7 @@ static const struct ib_device_ops mlx4_ib_dev_ops = {
>  
>  	INIT_RDMA_OBJ_SIZE(ib_ah, mlx4_ib_ah, ibah),
>  	INIT_RDMA_OBJ_SIZE(ib_pd, mlx4_ib_pd, ibpd),
> +	INIT_RDMA_OBJ_SIZE(ib_srq, mlx4_ib_srq, ibsrq),
>  	INIT_RDMA_OBJ_SIZE(ib_ucontext, mlx4_ib_ucontext, ibucontext),
>  };
>  
> diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
> index 8f1ad2a44573..47518b81c27c 100644
> --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
> +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
> @@ -760,13 +760,12 @@ int mlx4_ib_create_ah_slave(struct ib_ah *ah, struct rdma_ah_attr *ah_attr,
>  			    int slave_sgid_index, u8 *s_mac, u16 vlan_tag);
>  int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
>  
> -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);
>  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);
> diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c
> index 381cf899bcef..4572795de727 100644
> --- a/drivers/infiniband/hw/mlx4/srq.c
> +++ b/drivers/infiniband/hw/mlx4/srq.c
> @@ -69,14 +69,14 @@ static void mlx4_ib_srq_event(struct mlx4_srq *srq, enum mlx4_event type)
>  	}
>  }
>  
> -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 *ib_srq,
> +		       struct ib_srq_init_attr *init_attr,
> +		       struct ib_udata *udata)
>  {
> -	struct mlx4_ib_dev *dev = to_mdev(pd->device);
> +	struct mlx4_ib_dev *dev = to_mdev(ib_srq->device);
>  	struct mlx4_ib_ucontext *ucontext = rdma_udata_to_drv_context(
>  		udata, struct mlx4_ib_ucontext, ibucontext);
> -	struct mlx4_ib_srq *srq;
> +	struct mlx4_ib_srq *srq = to_msrq(ib_srq);
>  	struct mlx4_wqe_srq_next_seg *next;
>  	struct mlx4_wqe_data_seg *scatter;
>  	u32 cqn;
> @@ -89,11 +89,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
>  	/* Sanity check SRQ size before proceeding */
>  	if (init_attr->attr.max_wr  >= dev->dev->caps.max_srq_wqes ||
>  	    init_attr->attr.max_sge >  dev->dev->caps.max_srq_sge)
> -		return ERR_PTR(-EINVAL);
> -
> -	srq = kmalloc(sizeof *srq, GFP_KERNEL);
> -	if (!srq)
> -		return ERR_PTR(-ENOMEM);
> +		return -EINVAL;
>  
>  	mutex_init(&srq->mutex);
>  	spin_lock_init(&srq->lock);
> @@ -111,16 +107,12 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
>  	if (udata) {
>  		struct mlx4_ib_create_srq ucmd;
>  
> -		if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) {
> -			err = -EFAULT;
> -			goto err_srq;
> -		}
> +		if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)))
> +			return -EFAULT;
>  
>  		srq->umem = ib_umem_get(udata, ucmd.buf_addr, buf_size, 0, 0);
> -		if (IS_ERR(srq->umem)) {
> -			err = PTR_ERR(srq->umem);
> -			goto err_srq;
> -		}
> +		if (IS_ERR(srq->umem))
> +			return PTR_ERR(srq->umem);
>  
>  		err = mlx4_mtt_init(dev->dev, ib_umem_page_count(srq->umem),
>  				    srq->umem->page_shift, &srq->mtt);
> @@ -138,7 +130,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
>  	} else {
>  		err = mlx4_db_alloc(dev->dev, &srq->db, 0);
>  		if (err)
> -			goto err_srq;
> +			return err;
>  
>  		*srq->db.db = 0;
>  
> @@ -185,8 +177,8 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
>  	xrcdn = (init_attr->srq_type == IB_SRQT_XRC) ?
>  		to_mxrcd(init_attr->ext.xrc.xrcd)->xrcdn :
>  		(u16) dev->dev->caps.reserved_xrcds;
> -	err = mlx4_srq_alloc(dev->dev, to_mpd(pd)->pdn, cqn, xrcdn, &srq->mtt,
> -			     srq->db.dma, &srq->msrq);
> +	err = mlx4_srq_alloc(dev->dev, to_mpd(ib_srq->pd)->pdn, cqn, xrcdn,
> +			     &srq->mtt, srq->db.dma, &srq->msrq);
>  	if (err)
>  		goto err_wrid;
>  
> @@ -201,7 +193,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
>  
>  	init_attr->attr.max_wr = srq->msrq.max - 1;
>  
> -	return &srq->ibsrq;
> +	return 0;
>  
>  err_wrid:
>  	if (udata)
> @@ -222,10 +214,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
>  	if (!udata)
>  		mlx4_db_free(dev->dev, &srq->db);
>  
> -err_srq:
> -	kfree(srq);
> -
> -	return ERR_PTR(err);
> +	return err;
>  }
>  
>  int mlx4_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
> @@ -272,7 +261,7 @@ int mlx4_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
>  	return 0;
>  }
>  
> -int mlx4_ib_destroy_srq(struct ib_srq *srq)
> +void mlx4_ib_destroy_srq(struct ib_srq *srq)
>  {
>  	struct mlx4_ib_dev *dev = to_mdev(srq->device);
>  	struct mlx4_ib_srq *msrq = to_msrq(srq);
> @@ -289,10 +278,6 @@ int mlx4_ib_destroy_srq(struct ib_srq *srq)
>  			      &msrq->buf);
>  		mlx4_db_free(dev->dev, &msrq->db);
>  	}
> -
> -	kfree(msrq);
> -
> -	return 0;
>  }
>  
>  void mlx4_ib_free_srq_wqe(struct mlx4_ib_srq *srq, int wqe_index)
> diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
> index 9a8cf3a9e702..fc5420c076a2 100644
> --- a/drivers/infiniband/hw/mlx5/main.c
> +++ b/drivers/infiniband/hw/mlx5/main.c
> @@ -4791,19 +4791,21 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
>  	attr.ext.cq = devr->c0;
>  	attr.ext.xrc.xrcd = devr->x0;
>  
> -	devr->s0 = mlx5_ib_create_srq(devr->p0, &attr, NULL);
> -	if (IS_ERR(devr->s0)) {
> -		ret = PTR_ERR(devr->s0);
> +	devr->s0 = rdma_zalloc_drv_obj(ibdev, ib_srq);
> +	if (!devr->s0) {
> +		ret = -ENOMEM;
>  		goto error4;
>  	}
> +
>  	devr->s0->device	= &dev->ib_dev;
>  	devr->s0->pd		= devr->p0;
> -	devr->s0->uobject       = NULL;
> -	devr->s0->event_handler = NULL;
> -	devr->s0->srq_context   = NULL;
>  	devr->s0->srq_type      = IB_SRQT_XRC;
>  	devr->s0->ext.xrc.xrcd	= devr->x0;
>  	devr->s0->ext.cq	= devr->c0;
> +	ret = mlx5_ib_create_srq(devr->s0, &attr, NULL);
> +	if (ret)
> +		goto err_create;
> +
>  	atomic_inc(&devr->s0->ext.xrc.xrcd->usecnt);
>  	atomic_inc(&devr->s0->ext.cq->usecnt);
>  	atomic_inc(&devr->p0->usecnt);
> @@ -4813,18 +4815,21 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
>  	attr.attr.max_sge = 1;
>  	attr.attr.max_wr = 1;
>  	attr.srq_type = IB_SRQT_BASIC;
> -	devr->s1 = mlx5_ib_create_srq(devr->p0, &attr, NULL);
> -	if (IS_ERR(devr->s1)) {
> -		ret = PTR_ERR(devr->s1);
> +	devr->s1 = rdma_zalloc_drv_obj(ibdev, ib_srq);
> +	if (!devr->s1) {
> +		ret = -ENOMEM;
>  		goto error5;
>  	}
> +
>  	devr->s1->device	= &dev->ib_dev;
>  	devr->s1->pd		= devr->p0;
> -	devr->s1->uobject       = NULL;
> -	devr->s1->event_handler = NULL;
> -	devr->s1->srq_context   = NULL;
>  	devr->s1->srq_type      = IB_SRQT_BASIC;
>  	devr->s1->ext.cq	= devr->c0;
> +
> +	ret = mlx5_ib_create_srq(devr->s1, &attr, NULL);
> +	if (ret)
> +		goto error6;
> +
>  	atomic_inc(&devr->p0->usecnt);
>  	atomic_set(&devr->s1->usecnt, 0);
>  
> @@ -4836,8 +4841,12 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
>  
>  	return 0;
>  
> +error6:
> +	kfree(devr->s1);
>  error5:
>  	mlx5_ib_destroy_srq(devr->s0);
> +err_create:
> +	kfree(devr->s0);
>  error4:
>  	mlx5_ib_dealloc_xrcd(devr->x1);
>  error3:
> @@ -4858,7 +4867,9 @@ static void destroy_dev_resources(struct mlx5_ib_resources *devr)
>  	int port;
>  
>  	mlx5_ib_destroy_srq(devr->s1);
> +	kfree(devr->s1);
>  	mlx5_ib_destroy_srq(devr->s0);
> +	kfree(devr->s0);
>  	mlx5_ib_dealloc_xrcd(devr->x0);
>  	mlx5_ib_dealloc_xrcd(devr->x1);
>  	mlx5_ib_destroy_cq(devr->c0);
> @@ -5984,6 +5995,7 @@ static const struct ib_device_ops mlx5_ib_dev_ops = {
>  
>  	INIT_RDMA_OBJ_SIZE(ib_ah, mlx5_ib_ah, ibah),
>  	INIT_RDMA_OBJ_SIZE(ib_pd, mlx5_ib_pd, ibpd),
> +	INIT_RDMA_OBJ_SIZE(ib_srq, mlx5_ib_srq, ibsrq),
>  	INIT_RDMA_OBJ_SIZE(ib_ucontext, mlx5_ib_ucontext, ibucontext),
>  };
>  
> diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
> index 9a55f9853881..a3fd199aaed9 100644
> --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
> +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
> @@ -1049,13 +1049,12 @@ void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index);
>  int mlx5_ib_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr, u32 flags,
>  		      struct ib_udata *udata);
>  int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
> -struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
> -				  struct ib_srq_init_attr *init_attr,
> -				  struct ib_udata *udata);
> +int mlx5_ib_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *init_attr,
> +		       struct ib_udata *udata);
>  int mlx5_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
>  		       enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
>  int mlx5_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr);
> -int mlx5_ib_destroy_srq(struct ib_srq *srq);
> +void mlx5_ib_destroy_srq(struct ib_srq *srq);
>  int mlx5_ib_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
>  			  const struct ib_recv_wr **bad_wr);
>  int mlx5_ib_enable_lb(struct mlx5_ib_dev *dev, bool td, bool qp);
> diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
> index 1ec1beb1296b..44fd7726e7b7 100644
> --- a/drivers/infiniband/hw/mlx5/srq.c
> +++ b/drivers/infiniband/hw/mlx5/srq.c
> @@ -208,16 +208,16 @@ static void destroy_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq)
>  	mlx5_db_free(dev->mdev, &srq->db);
>  }
>  
> -struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
> -				  struct ib_srq_init_attr *init_attr,
> -				  struct ib_udata *udata)
> +int mlx5_ib_create_srq(struct ib_srq *ib_srq,
> +		       struct ib_srq_init_attr *init_attr,
> +		       struct ib_udata *udata)
>  {
> -	struct mlx5_ib_dev *dev = to_mdev(pd->device);
> -	struct mlx5_ib_srq *srq;
> +	struct mlx5_ib_dev *dev = to_mdev(ib_srq->device);
> +	struct mlx5_ib_srq *srq = to_msrq(ib_srq);
>  	size_t desc_size;
>  	size_t buf_size;
>  	int err;
> -	struct mlx5_srq_attr in = {0};
> +	struct mlx5_srq_attr in = {};
>  	__u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz);
>  
>  	/* Sanity check SRQ size before proceeding */
> @@ -225,13 +225,9 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
>  		mlx5_ib_dbg(dev, "max_wr %d, cap %d\n",
>  			    init_attr->attr.max_wr,
>  			    max_srq_wqes);
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	}
>  
> -	srq = kmalloc(sizeof(*srq), GFP_KERNEL);
> -	if (!srq)
> -		return ERR_PTR(-ENOMEM);
> -
>  	mutex_init(&srq->mutex);
>  	spin_lock_init(&srq->lock);
>  	srq->msrq.max    = roundup_pow_of_two(init_attr->attr.max_wr + 1);
> @@ -239,35 +235,32 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
>  
>  	desc_size = sizeof(struct mlx5_wqe_srq_next_seg) +
>  		    srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg);
> -	if (desc_size == 0 || srq->msrq.max_gs > desc_size) {
> -		err = -EINVAL;
> -		goto err_srq;
> -	}
> +	if (desc_size == 0 || srq->msrq.max_gs > desc_size)
> +		return -EINVAL;
> +
>  	desc_size = roundup_pow_of_two(desc_size);
>  	desc_size = max_t(size_t, 32, desc_size);
> -	if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg)) {
> -		err = -EINVAL;
> -		goto err_srq;
> -	}
> +	if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg))
> +		return -EINVAL;
> +
>  	srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) /
>  		sizeof(struct mlx5_wqe_data_seg);
>  	srq->msrq.wqe_shift = ilog2(desc_size);
>  	buf_size = srq->msrq.max * desc_size;
> -	if (buf_size < desc_size) {
> -		err = -EINVAL;
> -		goto err_srq;
> -	}
> +	if (buf_size < desc_size)
> +		return -EINVAL;
> +
>  	in.type = init_attr->srq_type;
>  
>  	if (udata)
> -		err = create_srq_user(pd, srq, &in, udata, buf_size);
> +		err = create_srq_user(ib_srq->pd, srq, &in, udata, buf_size);
>  	else
>  		err = create_srq_kernel(dev, srq, &in, buf_size);
>  
>  	if (err) {
>  		mlx5_ib_warn(dev, "create srq %s failed, err %d\n",
>  			     udata ? "user" : "kernel", err);
> -		goto err_srq;
> +		return err;
>  	}
>  
>  	in.log_size = ilog2(srq->msrq.max);
> @@ -297,7 +290,7 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
>  	else
>  		in.cqn = to_mcq(dev->devr.c0)->mcq.cqn;
>  
> -	in.pd = to_mpd(pd)->pdn;
> +	in.pd = to_mpd(ib_srq->pd)->pdn;
>  	in.db_record = srq->db.dma;
>  	err = mlx5_cmd_create_srq(dev, &srq->msrq, &in);
>  	kvfree(in.pas);
> @@ -320,21 +313,18 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
>  
>  	init_attr->attr.max_wr = srq->msrq.max - 1;
>  
> -	return &srq->ibsrq;
> +	return 0;
>  
>  err_core:
>  	mlx5_cmd_destroy_srq(dev, &srq->msrq);
>  
>  err_usr_kern_srq:
>  	if (udata)
> -		destroy_srq_user(pd, srq);
> +		destroy_srq_user(ib_srq->pd, srq);
>  	else
>  		destroy_srq_kernel(dev, srq);
>  
> -err_srq:
> -	kfree(srq);
> -
> -	return ERR_PTR(err);
> +	return err;
>  }
>  
>  int mlx5_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
> @@ -387,7 +377,7 @@ int mlx5_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
>  	return ret;
>  }
>  
> -int mlx5_ib_destroy_srq(struct ib_srq *srq)
> +void mlx5_ib_destroy_srq(struct ib_srq *srq)
>  {
>  	struct mlx5_ib_dev *dev = to_mdev(srq->device);
>  	struct mlx5_ib_srq *msrq = to_msrq(srq);
> @@ -400,9 +390,6 @@ int mlx5_ib_destroy_srq(struct ib_srq *srq)
>  	} else {
>  		destroy_srq_kernel(dev, msrq);
>  	}
> -
> -	kfree(srq);
> -	return 0;
>  }
>  
>  void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index)
> diff --git a/drivers/infiniband/hw/mlx5/srq.h b/drivers/infiniband/hw/mlx5/srq.h
> index c330af35ff10..e509d0caeb56 100644
> --- a/drivers/infiniband/hw/mlx5/srq.h
> +++ b/drivers/infiniband/hw/mlx5/srq.h
> @@ -59,7 +59,7 @@ struct mlx5_srq_table {
>  
>  int mlx5_cmd_create_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq,
>  			struct mlx5_srq_attr *in);
> -int mlx5_cmd_destroy_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq);
> +void mlx5_cmd_destroy_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq);
>  int mlx5_cmd_query_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq,
>  		       struct mlx5_srq_attr *out);
>  int mlx5_cmd_arm_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq,
> diff --git a/drivers/infiniband/hw/mlx5/srq_cmd.c b/drivers/infiniband/hw/mlx5/srq_cmd.c
> index 63ac38bb3498..dd1bd8382e37 100644
> --- a/drivers/infiniband/hw/mlx5/srq_cmd.c
> +++ b/drivers/infiniband/hw/mlx5/srq_cmd.c
> @@ -611,7 +611,7 @@ int mlx5_cmd_create_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq,
>  	return err;
>  }
>  
> -int mlx5_cmd_destroy_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq)
> +void mlx5_cmd_destroy_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq)
>  {
>  	struct mlx5_srq_table *table = &dev->srq_table;
>  	struct mlx5_core_srq *tmp;
> @@ -621,16 +621,14 @@ int mlx5_cmd_destroy_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq)
>  	tmp = radix_tree_delete(&table->tree, srq->srqn);
>  	spin_unlock_irq(&table->lock);
>  	if (!tmp || tmp != srq)
> -		return -EINVAL;
> +		return;
>  
>  	err = destroy_srq_split(dev, srq);
>  	if (err)
> -		return err;
> +		return;
>  
>  	mlx5_core_res_put(&srq->common);
>  	wait_for_completion(&srq->common.free);
> -
> -	return 0;
>  }
>  
>  int mlx5_cmd_query_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq,
> diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
> index ae9b47d438d2..d58987360ad5 100644
> --- a/drivers/infiniband/hw/mthca/mthca_provider.c
> +++ b/drivers/infiniband/hw/mthca/mthca_provider.c
> @@ -404,65 +404,53 @@ static void mthca_ah_destroy(struct ib_ah *ah, u32 flags)
>  	mthca_destroy_ah(to_mdev(ah->device), to_mah(ah));
>  }
>  
> -static struct ib_srq *mthca_create_srq(struct ib_pd *pd,
> -				       struct ib_srq_init_attr *init_attr,
> -				       struct ib_udata *udata)
> +static int mthca_create_srq(struct ib_srq *ibsrq,
> +			    struct ib_srq_init_attr *init_attr,
> +			    struct ib_udata *udata)
>  {
>  	struct mthca_create_srq ucmd;
>  	struct mthca_ucontext *context = rdma_udata_to_drv_context(
>  		udata, struct mthca_ucontext, ibucontext);
> -	struct mthca_srq *srq;
> +	struct mthca_srq *srq = to_msrq(ibsrq);
>  	int err;
>  
>  	if (init_attr->srq_type != IB_SRQT_BASIC)
> -		return ERR_PTR(-EOPNOTSUPP);
> -
> -	srq = kmalloc(sizeof *srq, GFP_KERNEL);
> -	if (!srq)
> -		return ERR_PTR(-ENOMEM);
> +		return -EOPNOTSUPP;
>  
>  	if (udata) {
> -		if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) {
> -			err = -EFAULT;
> -			goto err_free;
> -		}
> +		if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)))
> +			return -EFAULT;
>  
> -		err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
> +		err = mthca_map_user_db(to_mdev(ibsrq->device), &context->uar,
>  					context->db_tab, ucmd.db_index,
>  					ucmd.db_page);
>  
>  		if (err)
> -			goto err_free;
> +			return err;
>  
>  		srq->mr.ibmr.lkey = ucmd.lkey;
>  		srq->db_index     = ucmd.db_index;
>  	}
>  
> -	err = mthca_alloc_srq(to_mdev(pd->device), to_mpd(pd),
> +	err = mthca_alloc_srq(to_mdev(ibsrq->device), to_mpd(ibsrq->pd),
>  			      &init_attr->attr, srq, udata);
>  
>  	if (err && udata)
> -		mthca_unmap_user_db(to_mdev(pd->device), &context->uar,
> +		mthca_unmap_user_db(to_mdev(ibsrq->device), &context->uar,
>  				    context->db_tab, ucmd.db_index);
>  
>  	if (err)
> -		goto err_free;
> +		return err;
>  
> -	if (context && ib_copy_to_udata(udata, &srq->srqn, sizeof (__u32))) {
> -		mthca_free_srq(to_mdev(pd->device), srq);
> -		err = -EFAULT;
> -		goto err_free;
> +	if (context && ib_copy_to_udata(udata, &srq->srqn, sizeof(__u32))) {
> +		mthca_free_srq(to_mdev(ibsrq->device), srq);
> +		return -EFAULT;
>  	}
>  
> -	return &srq->ibsrq;
> -
> -err_free:
> -	kfree(srq);
> -
> -	return ERR_PTR(err);
> +	return 0;
>  }
>  
> -static int mthca_destroy_srq(struct ib_srq *srq)
> +static void mthca_destroy_srq(struct ib_srq *srq)
>  {
>  	struct mthca_ucontext *context;
>  
> @@ -474,9 +462,6 @@ static int mthca_destroy_srq(struct ib_srq *srq)
>  	}
>  
>  	mthca_free_srq(to_mdev(srq->device), to_msrq(srq));
> -	kfree(srq);
> -
> -	return 0;
>  }
>  
>  static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
> @@ -1197,6 +1182,8 @@ static const struct ib_device_ops mthca_dev_arbel_srq_ops = {
>  	.modify_srq = mthca_modify_srq,
>  	.post_srq_recv = mthca_arbel_post_srq_recv,
>  	.query_srq = mthca_query_srq,
> +
> +	INIT_RDMA_OBJ_SIZE(ib_srq, mthca_srq, ibsrq),
>  };
>  
>  static const struct ib_device_ops mthca_dev_tavor_srq_ops = {
> @@ -1205,6 +1192,8 @@ static const struct ib_device_ops mthca_dev_tavor_srq_ops = {
>  	.modify_srq = mthca_modify_srq,
>  	.post_srq_recv = mthca_tavor_post_srq_recv,
>  	.query_srq = mthca_query_srq,
> +
> +	INIT_RDMA_OBJ_SIZE(ib_srq, mthca_srq, ibsrq),
>  };
>  
>  static const struct ib_device_ops mthca_dev_arbel_fmr_ops = {
> diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
> index e693eb352959..5d96b5a94583 100644
> --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
> +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
> @@ -2863,21 +2863,19 @@ int ocrdma_mbx_query_srq(struct ocrdma_srq *srq, struct ib_srq_attr *srq_attr)
>  	return status;
>  }
>  
> -int ocrdma_mbx_destroy_srq(struct ocrdma_dev *dev, struct ocrdma_srq *srq)
> +void ocrdma_mbx_destroy_srq(struct ocrdma_dev *dev, struct ocrdma_srq *srq)
>  {
> -	int status = -ENOMEM;
>  	struct ocrdma_destroy_srq *cmd;
>  	struct pci_dev *pdev = dev->nic_info.pdev;
>  	cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DELETE_SRQ, sizeof(*cmd));
>  	if (!cmd)
> -		return status;
> +		return;
>  	cmd->id = srq->id;
> -	status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
> +	ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
>  	if (srq->rq.va)
>  		dma_free_coherent(&pdev->dev, srq->rq.len,
>  				  srq->rq.va, srq->rq.pa);
>  	kfree(cmd);
> -	return status;
>  }
>  
>  static int ocrdma_mbx_get_dcbx_config(struct ocrdma_dev *dev, u32 ptype,
> diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
> index 88d45aa19ded..06ec59326a90 100644
> --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
> +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
> @@ -137,7 +137,7 @@ int ocrdma_mbx_create_srq(struct ocrdma_dev *, struct ocrdma_srq *,
>  			  struct ocrdma_pd *);
>  int ocrdma_mbx_modify_srq(struct ocrdma_srq *, struct ib_srq_attr *);
>  int ocrdma_mbx_query_srq(struct ocrdma_srq *, struct ib_srq_attr *);
> -int ocrdma_mbx_destroy_srq(struct ocrdma_dev *, struct ocrdma_srq *);
> +void ocrdma_mbx_destroy_srq(struct ocrdma_dev *dev, struct ocrdma_srq *srq);
>  
>  int ocrdma_alloc_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah);
>  void ocrdma_free_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah);
> diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
> index 8642a2e60be7..34d3d59f3ca7 100644
> --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
> +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
> @@ -191,6 +191,8 @@ static const struct ib_device_ops ocrdma_dev_srq_ops = {
>  	.modify_srq = ocrdma_modify_srq,
>  	.post_srq_recv = ocrdma_post_srq_recv,
>  	.query_srq = ocrdma_query_srq,
> +
> +	INIT_RDMA_OBJ_SIZE(ib_srq, ocrdma_srq, ibsrq),
>  };
>  
>  static int ocrdma_register_device(struct ocrdma_dev *dev)
> diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
> index b4e1777c2c97..2c9519f2af1f 100644
> --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
> +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
> @@ -1793,45 +1793,43 @@ static int ocrdma_copy_srq_uresp(struct ocrdma_dev *dev, struct ocrdma_srq *srq,
>  	return status;
>  }
>  
> -struct ib_srq *ocrdma_create_srq(struct ib_pd *ibpd,
> -				 struct ib_srq_init_attr *init_attr,
> -				 struct ib_udata *udata)
> +int ocrdma_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init_attr,
> +		      struct ib_udata *udata)
>  {
> -	int status = -ENOMEM;
> -	struct ocrdma_pd *pd = get_ocrdma_pd(ibpd);
> -	struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device);
> -	struct ocrdma_srq *srq;
> +	int status;
> +	struct ocrdma_pd *pd = get_ocrdma_pd(ibsrq->pd);
> +	struct ocrdma_dev *dev = get_ocrdma_dev(ibsrq->device);
> +	struct ocrdma_srq *srq = get_ocrdma_srq(ibsrq);
>  
>  	if (init_attr->attr.max_sge > dev->attr.max_recv_sge)
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	if (init_attr->attr.max_wr > dev->attr.max_rqe)
> -		return ERR_PTR(-EINVAL);
> -
> -	srq = kzalloc(sizeof(*srq), GFP_KERNEL);
> -	if (!srq)
> -		return ERR_PTR(status);
> +		return -EINVAL;
>  
>  	spin_lock_init(&srq->q_lock);
>  	srq->pd = pd;
>  	srq->db = dev->nic_info.db + (pd->id * dev->nic_info.db_page_size);
>  	status = ocrdma_mbx_create_srq(dev, srq, init_attr, pd);
>  	if (status)
> -		goto err;
> +		return status;
>  
> -	if (udata == NULL) {
> -		status = -ENOMEM;
> +	if (!udata) {
>  		srq->rqe_wr_id_tbl = kcalloc(srq->rq.max_cnt, sizeof(u64),
>  					     GFP_KERNEL);
> -		if (srq->rqe_wr_id_tbl == NULL)
> +		if (!srq->rqe_wr_id_tbl) {
> +			status = -ENOMEM;
>  			goto arm_err;
> +		}
>  
>  		srq->bit_fields_len = (srq->rq.max_cnt / 32) +
>  		    (srq->rq.max_cnt % 32 ? 1 : 0);
>  		srq->idx_bit_fields =
>  		    kmalloc_array(srq->bit_fields_len, sizeof(u32),
>  				  GFP_KERNEL);
> -		if (srq->idx_bit_fields == NULL)
> +		if (!srq->idx_bit_fields) {
> +			status = -ENOMEM;
>  			goto arm_err;
> +		}
>  		memset(srq->idx_bit_fields, 0xff,
>  		       srq->bit_fields_len * sizeof(u32));
>  	}
> @@ -1848,15 +1846,13 @@ struct ib_srq *ocrdma_create_srq(struct ib_pd *ibpd,
>  			goto arm_err;
>  	}
>  
> -	return &srq->ibsrq;
> +	return 0;
>  
>  arm_err:
>  	ocrdma_mbx_destroy_srq(dev, srq);
> -err:
>  	kfree(srq->rqe_wr_id_tbl);
>  	kfree(srq->idx_bit_fields);
> -	kfree(srq);
> -	return ERR_PTR(status);
> +	return status;
>  }
>  
>  int ocrdma_modify_srq(struct ib_srq *ibsrq,
> @@ -1885,15 +1881,14 @@ int ocrdma_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
>  	return status;
>  }
>  
> -int ocrdma_destroy_srq(struct ib_srq *ibsrq)
> +void ocrdma_destroy_srq(struct ib_srq *ibsrq)
>  {
> -	int status;
>  	struct ocrdma_srq *srq;
>  	struct ocrdma_dev *dev = get_ocrdma_dev(ibsrq->device);
>  
>  	srq = get_ocrdma_srq(ibsrq);
>  
> -	status = ocrdma_mbx_destroy_srq(dev, srq);
> +	ocrdma_mbx_destroy_srq(dev, srq);
>  
>  	if (srq->pd->uctx)
>  		ocrdma_del_mmap(srq->pd->uctx, (u64) srq->rq.pa,
> @@ -1901,8 +1896,6 @@ int ocrdma_destroy_srq(struct ib_srq *ibsrq)
>  
>  	kfree(srq->idx_bit_fields);
>  	kfree(srq->rqe_wr_id_tbl);
> -	kfree(srq);
> -	return status;
>  }
>  
>  /* unprivileged verbs and their support functions. */
> diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h
> index 4c04ab40798e..7debe0e871aa 100644
> --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h
> +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h
> @@ -93,12 +93,12 @@ int ocrdma_query_qp(struct ib_qp *,
>  int ocrdma_destroy_qp(struct ib_qp *);
>  void ocrdma_del_flush_qp(struct ocrdma_qp *qp);
>  
> -struct ib_srq *ocrdma_create_srq(struct ib_pd *, struct ib_srq_init_attr *,
> -				 struct ib_udata *);
> +int ocrdma_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *attr,
> +		      struct ib_udata *udata);
>  int ocrdma_modify_srq(struct ib_srq *, struct ib_srq_attr *,
>  		      enum ib_srq_attr_mask, struct ib_udata *);
>  int ocrdma_query_srq(struct ib_srq *, struct ib_srq_attr *);
> -int ocrdma_destroy_srq(struct ib_srq *);
> +void ocrdma_destroy_srq(struct ib_srq *ibsrq);
>  int ocrdma_post_srq_recv(struct ib_srq *, const struct ib_recv_wr *,
>  			 const struct ib_recv_wr **bad_recv_wr);
>  
> diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c
> index d460a6c02e06..73ef9d2bb6bf 100644
> --- a/drivers/infiniband/hw/qedr/main.c
> +++ b/drivers/infiniband/hw/qedr/main.c
> @@ -242,6 +242,7 @@ static const struct ib_device_ops qedr_dev_ops = {
>  
>  	INIT_RDMA_OBJ_SIZE(ib_ah, qedr_ah, ibah),
>  	INIT_RDMA_OBJ_SIZE(ib_pd, qedr_pd, ibpd),
> +	INIT_RDMA_OBJ_SIZE(ib_srq, qedr_srq, ibsrq),
>  	INIT_RDMA_OBJ_SIZE(ib_ucontext, qedr_ucontext, ibucontext),
>  };
>  
> diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
> index fc58f0cc1944..77b556a3d21d 100644
> --- a/drivers/infiniband/hw/qedr/verbs.c
> +++ b/drivers/infiniband/hw/qedr/verbs.c
> @@ -1264,7 +1264,7 @@ static void qedr_set_roce_db_info(struct qedr_dev *dev, struct qedr_qp *qp)
>  	}
>  }
>  
> -static int qedr_check_srq_params(struct ib_pd *ibpd, struct qedr_dev *dev,
> +static int qedr_check_srq_params(struct qedr_dev *dev,
>  				 struct ib_srq_init_attr *attrs,
>  				 struct ib_udata *udata)
>  {
> @@ -1385,33 +1385,28 @@ static int qedr_idr_add(struct qedr_dev *dev, struct qedr_idr *qidr,
>  static void qedr_idr_remove(struct qedr_dev *dev,
>  			    struct qedr_idr *qidr, u32 id);
>  
> -struct ib_srq *qedr_create_srq(struct ib_pd *ibpd,
> -			       struct ib_srq_init_attr *init_attr,
> -			       struct ib_udata *udata)
> +int qedr_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init_attr,
> +		    struct ib_udata *udata)
>  {
>  	struct qed_rdma_destroy_srq_in_params destroy_in_params;
>  	struct qed_rdma_create_srq_in_params in_params = {};
> -	struct qedr_dev *dev = get_qedr_dev(ibpd->device);
> +	struct qedr_dev *dev = get_qedr_dev(ibsrq->device);
>  	struct qed_rdma_create_srq_out_params out_params;
> -	struct qedr_pd *pd = get_qedr_pd(ibpd);
> +	struct qedr_pd *pd = get_qedr_pd(ibsrq->pd);
>  	struct qedr_create_srq_ureq ureq = {};
>  	u64 pbl_base_addr, phy_prod_pair_addr;
>  	struct qedr_srq_hwq_info *hw_srq;
>  	u32 page_cnt, page_size;
> -	struct qedr_srq *srq;
> +	struct qedr_srq *srq = get_qedr_srq(ibsrq);
>  	int rc = 0;
>  
>  	DP_DEBUG(dev, QEDR_MSG_QP,
>  		 "create SRQ called from %s (pd %p)\n",
>  		 (udata) ? "User lib" : "kernel", pd);
>  
> -	rc = qedr_check_srq_params(ibpd, dev, init_attr, udata);
> +	rc = qedr_check_srq_params(dev, init_attr, udata);
>  	if (rc)
> -		return ERR_PTR(-EINVAL);
> -
> -	srq = kzalloc(sizeof(*srq), GFP_KERNEL);
> -	if (!srq)
> -		return ERR_PTR(-ENOMEM);
> +		return -EINVAL;
>  
>  	srq->dev = dev;
>  	hw_srq = &srq->hw_srq;
> @@ -1473,7 +1468,7 @@ struct ib_srq *qedr_create_srq(struct ib_pd *ibpd,
>  
>  	DP_DEBUG(dev, QEDR_MSG_SRQ,
>  		 "create srq: created srq with srq_id=0x%0x\n", srq->srq_id);
> -	return &srq->ibsrq;
> +	return 0;
>  
>  err2:
>  	destroy_in_params.srq_id = srq->srq_id;
> @@ -1485,12 +1480,10 @@ struct ib_srq *qedr_create_srq(struct ib_pd *ibpd,
>  	else
>  		qedr_free_srq_kernel_params(srq);
>  err0:
> -	kfree(srq);
> -
> -	return ERR_PTR(-EFAULT);
> +	return -EFAULT;
>  }
>  
> -int qedr_destroy_srq(struct ib_srq *ibsrq)
> +void qedr_destroy_srq(struct ib_srq *ibsrq)
>  {
>  	struct qed_rdma_destroy_srq_in_params in_params = {};
>  	struct qedr_dev *dev = get_qedr_dev(ibsrq->device);
> @@ -1508,9 +1501,6 @@ int qedr_destroy_srq(struct ib_srq *ibsrq)
>  	DP_DEBUG(dev, QEDR_MSG_SRQ,
>  		 "destroy srq: destroyed srq with srq_id=0x%0x\n",
>  		 srq->srq_id);
> -	kfree(srq);
> -
> -	return 0;
>  }
>  
>  int qedr_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
> diff --git a/drivers/infiniband/hw/qedr/verbs.h b/drivers/infiniband/hw/qedr/verbs.h
> index b2f18667e93e..6e1e6f43be41 100644
> --- a/drivers/infiniband/hw/qedr/verbs.h
> +++ b/drivers/infiniband/hw/qedr/verbs.h
> @@ -66,13 +66,12 @@ int qedr_query_qp(struct ib_qp *, struct ib_qp_attr *qp_attr,
>  		  int qp_attr_mask, struct ib_qp_init_attr *);
>  int qedr_destroy_qp(struct ib_qp *ibqp);
>  
> -struct ib_srq *qedr_create_srq(struct ib_pd *ibpd,
> -			       struct ib_srq_init_attr *attr,
> -			       struct ib_udata *udata);
> +int qedr_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *attr,
> +		    struct ib_udata *udata);
>  int qedr_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
>  		    enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
>  int qedr_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr);
> -int qedr_destroy_srq(struct ib_srq *ibsrq);
> +void qedr_destroy_srq(struct ib_srq *ibsrq);
>  int qedr_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
>  		       const struct ib_recv_wr **bad_recv_wr);
>  int qedr_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr, u32 flags,
> diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
> index 6cbc271a1b7d..823846947a5b 100644
> --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
> +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
> @@ -206,6 +206,8 @@ static const struct ib_device_ops pvrdma_dev_srq_ops = {
>  	.destroy_srq = pvrdma_destroy_srq,
>  	.modify_srq = pvrdma_modify_srq,
>  	.query_srq = pvrdma_query_srq,
> +
> +	INIT_RDMA_OBJ_SIZE(ib_srq, pvrdma_srq, ibsrq),
>  };
>  
>  static int pvrdma_register_device(struct pvrdma_dev *dev)
> diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
> index 951d9d68107a..e0014c563662 100644
> --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
> +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
> @@ -94,19 +94,18 @@ int pvrdma_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
>   * @init_attr: shared receive queue attributes
>   * @udata: user data
>   *
> - * @return: the ib_srq pointer on success, otherwise returns an errno.
> + * @return: 0 on success, otherwise returns an errno.
>   */
> -struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
> -				 struct ib_srq_init_attr *init_attr,
> -				 struct ib_udata *udata)
> +int pvrdma_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init_attr,
> +		      struct ib_udata *udata)
>  {
> -	struct pvrdma_srq *srq = NULL;
> -	struct pvrdma_dev *dev = to_vdev(pd->device);
> +	struct pvrdma_srq *srq = to_vsrq(ibsrq);
> +	struct pvrdma_dev *dev = to_vdev(ibsrq->device);
>  	union pvrdma_cmd_req req;
>  	union pvrdma_cmd_resp rsp;
>  	struct pvrdma_cmd_create_srq *cmd = &req.create_srq;
>  	struct pvrdma_cmd_create_srq_resp *resp = &rsp.create_srq_resp;
> -	struct pvrdma_create_srq_resp srq_resp = {0};
> +	struct pvrdma_create_srq_resp srq_resp = {};
>  	struct pvrdma_create_srq ucmd;
>  	unsigned long flags;
>  	int ret;
> @@ -115,31 +114,25 @@ struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
>  		/* No support for kernel clients. */
>  		dev_warn(&dev->pdev->dev,
>  			 "no shared receive queue support for kernel client\n");
> -		return ERR_PTR(-EOPNOTSUPP);
> +		return -EOPNOTSUPP;
>  	}
>  
>  	if (init_attr->srq_type != IB_SRQT_BASIC) {
>  		dev_warn(&dev->pdev->dev,
>  			 "shared receive queue type %d not supported\n",
>  			 init_attr->srq_type);
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	}
>  
>  	if (init_attr->attr.max_wr  > dev->dsr->caps.max_srq_wr ||
>  	    init_attr->attr.max_sge > dev->dsr->caps.max_srq_sge) {
>  		dev_warn(&dev->pdev->dev,
>  			 "shared receive queue size invalid\n");
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	}
>  
>  	if (!atomic_add_unless(&dev->num_srqs, 1, dev->dsr->caps.max_srq))
> -		return ERR_PTR(-ENOMEM);
> -
> -	srq = kmalloc(sizeof(*srq), GFP_KERNEL);
> -	if (!srq) {
> -		ret = -ENOMEM;
> -		goto err_srq;
> -	}
> +		return -ENOMEM;
>  
>  	spin_lock_init(&srq->lock);
>  	refcount_set(&srq->refcnt, 1);
> @@ -181,7 +174,7 @@ struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
>  	cmd->hdr.cmd = PVRDMA_CMD_CREATE_SRQ;
>  	cmd->srq_type = init_attr->srq_type;
>  	cmd->nchunks = srq->npages;
> -	cmd->pd_handle = to_vpd(pd)->pd_handle;
> +	cmd->pd_handle = to_vpd(ibsrq->pd)->pd_handle;
>  	cmd->attrs.max_wr = init_attr->attr.max_wr;
>  	cmd->attrs.max_sge = init_attr->attr.max_sge;
>  	cmd->attrs.srq_limit = init_attr->attr.srq_limit;
> @@ -205,20 +198,19 @@ struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
>  	if (ib_copy_to_udata(udata, &srq_resp, sizeof(srq_resp))) {
>  		dev_warn(&dev->pdev->dev, "failed to copy back udata\n");
>  		pvrdma_destroy_srq(&srq->ibsrq);
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	}
>  
> -	return &srq->ibsrq;
> +	return 0;
>  
>  err_page_dir:
>  	pvrdma_page_dir_cleanup(dev, &srq->pdir);
>  err_umem:
>  	ib_umem_release(srq->umem);
>  err_srq:
> -	kfree(srq);
>  	atomic_dec(&dev->num_srqs);
>  
> -	return ERR_PTR(ret);
> +	return ret;
>  }
>  
>  static void pvrdma_free_srq(struct pvrdma_dev *dev, struct pvrdma_srq *srq)
> @@ -246,10 +238,8 @@ static void pvrdma_free_srq(struct pvrdma_dev *dev, struct pvrdma_srq *srq)
>  /**
>   * pvrdma_destroy_srq - destroy shared receive queue
>   * @srq: the shared receive queue to destroy
> - *
> - * @return: 0 for success.
>   */
> -int pvrdma_destroy_srq(struct ib_srq *srq)
> +void pvrdma_destroy_srq(struct ib_srq *srq)
>  {
>  	struct pvrdma_srq *vsrq = to_vsrq(srq);
>  	union pvrdma_cmd_req req;
> @@ -268,8 +258,6 @@ int pvrdma_destroy_srq(struct ib_srq *srq)
>  			 ret);
>  
>  	pvrdma_free_srq(dev, vsrq);
> -
> -	return 0;
>  }
>  
>  /**
> diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
> index 0d05d8a15225..731c3197f838 100644
> --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
> +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
> @@ -421,13 +421,12 @@ int pvrdma_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr, u32 flags,
>  		     struct ib_udata *udata);
>  void pvrdma_destroy_ah(struct ib_ah *ah, u32 flags);
>  
> -struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
> -				 struct ib_srq_init_attr *init_attr,
> -				 struct ib_udata *udata);
> +int pvrdma_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *init_attr,
> +		      struct ib_udata *udata);
>  int pvrdma_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
>  		      enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
>  int pvrdma_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
> -int pvrdma_destroy_srq(struct ib_srq *srq);
> +void pvrdma_destroy_srq(struct ib_srq *srq);
>  
>  struct ib_qp *pvrdma_create_qp(struct ib_pd *pd,
>  			       struct ib_qp_init_attr *init_attr,
> diff --git a/drivers/infiniband/sw/rdmavt/srq.c b/drivers/infiniband/sw/rdmavt/srq.c
> index 895b3fabd0bf..47bbdaea2fee 100644
> --- a/drivers/infiniband/sw/rdmavt/srq.c
> +++ b/drivers/infiniband/sw/rdmavt/srq.c
> @@ -71,31 +71,26 @@ void rvt_driver_srq_init(struct rvt_dev_info *rdi)
>   * @srq_init_attr: the attributes of the SRQ
>   * @udata: data from libibverbs when creating a user SRQ
>   *
> - * Return: Allocated srq object
> + * Return: 0 on success
>   */
> -struct ib_srq *rvt_create_srq(struct ib_pd *ibpd,
> -			      struct ib_srq_init_attr *srq_init_attr,
> -			      struct ib_udata *udata)
> +int rvt_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *srq_init_attr,
> +		   struct ib_udata *udata)
>  {
> -	struct rvt_dev_info *dev = ib_to_rvt(ibpd->device);
> +	struct rvt_dev_info *dev = ib_to_rvt(ibsrq->device);
>  	struct rvt_ucontext *ucontext = rdma_udata_to_drv_context(
>  		udata, struct rvt_ucontext, ibucontext);
> -	struct rvt_srq *srq;
> +	struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq);
>  	u32 sz;
> -	struct ib_srq *ret;
> +	int ret;
>  
>  	if (srq_init_attr->srq_type != IB_SRQT_BASIC)
> -		return ERR_PTR(-EOPNOTSUPP);
> +		return -EOPNOTSUPP;
>  
>  	if (srq_init_attr->attr.max_sge == 0 ||
>  	    srq_init_attr->attr.max_sge > dev->dparms.props.max_srq_sge ||
>  	    srq_init_attr->attr.max_wr == 0 ||
>  	    srq_init_attr->attr.max_wr > dev->dparms.props.max_srq_wr)
> -		return ERR_PTR(-EINVAL);
> -
> -	srq = kzalloc_node(sizeof(*srq), GFP_KERNEL, dev->dparms.node);
> -	if (!srq)
> -		return ERR_PTR(-ENOMEM);
> +		return -EINVAL;
>  
>  	/*
>  	 * Need to use vmalloc() if we want to support large #s of entries.
> @@ -109,7 +104,7 @@ struct ib_srq *rvt_create_srq(struct ib_pd *ibpd,
>  		vzalloc_node(sizeof(struct rvt_rwq) + srq->rq.size * sz,
>  			     dev->dparms.node);
>  	if (!srq->rq.wq) {
> -		ret = ERR_PTR(-ENOMEM);
> +		ret = -ENOMEM;
>  		goto bail_srq;
>  	}
>  
> @@ -118,23 +113,20 @@ struct ib_srq *rvt_create_srq(struct ib_pd *ibpd,
>  	 * See rvt_mmap() for details.
>  	 */
>  	if (udata && udata->outlen >= sizeof(__u64)) {
> -		int err;
>  		u32 s = sizeof(struct rvt_rwq) + srq->rq.size * sz;
>  
>  		srq->ip =
>  		    rvt_create_mmap_info(dev, s, &ucontext->ibucontext,
>  					 srq->rq.wq);
>  		if (!srq->ip) {
> -			ret = ERR_PTR(-ENOMEM);
> +			ret = -ENOMEM;
>  			goto bail_wq;
>  		}
>  
> -		err = ib_copy_to_udata(udata, &srq->ip->offset,
> +		ret = ib_copy_to_udata(udata, &srq->ip->offset,
>  				       sizeof(srq->ip->offset));
> -		if (err) {
> -			ret = ERR_PTR(err);
> +		if (ret)
>  			goto bail_ip;
> -		}
>  	}
>  
>  	/*
> @@ -146,7 +138,7 @@ struct ib_srq *rvt_create_srq(struct ib_pd *ibpd,
>  	spin_lock(&dev->n_srqs_lock);
>  	if (dev->n_srqs_allocated == dev->dparms.props.max_srq) {
>  		spin_unlock(&dev->n_srqs_lock);
> -		ret = ERR_PTR(-ENOMEM);
> +		ret = -ENOMEM;
>  		goto bail_ip;
>  	}
>  
> @@ -159,14 +151,13 @@ struct ib_srq *rvt_create_srq(struct ib_pd *ibpd,
>  		spin_unlock_irq(&dev->pending_lock);
>  	}
>  
> -	return &srq->ibsrq;
> +	return 0;
>  
>  bail_ip:
>  	kfree(srq->ip);
>  bail_wq:
>  	vfree(srq->rq.wq);
>  bail_srq:
> -	kfree(srq);
>  	return ret;
>  }
>  
> @@ -338,9 +329,8 @@ int rvt_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr)
>   * rvt_destroy_srq - destory an srq
>   * @ibsrq: srq object to destroy
>   *
> - * Return always 0
>   */
> -int rvt_destroy_srq(struct ib_srq *ibsrq)
> +void rvt_destroy_srq(struct ib_srq *ibsrq)
>  {
>  	struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq);
>  	struct rvt_dev_info *dev = ib_to_rvt(ibsrq->device);
> @@ -352,7 +342,4 @@ int rvt_destroy_srq(struct ib_srq *ibsrq)
>  		kref_put(&srq->ip->ref, rvt_release_mmap_info);
>  	else
>  		vfree(srq->rq.wq);
> -	kfree(srq);
> -
> -	return 0;
>  }
> diff --git a/drivers/infiniband/sw/rdmavt/srq.h b/drivers/infiniband/sw/rdmavt/srq.h
> index bf0eaaf56465..edee08eba187 100644
> --- a/drivers/infiniband/sw/rdmavt/srq.h
> +++ b/drivers/infiniband/sw/rdmavt/srq.h
> @@ -50,13 +50,12 @@
>  
>  #include <rdma/rdma_vt.h>
>  void rvt_driver_srq_init(struct rvt_dev_info *rdi);
> -struct ib_srq *rvt_create_srq(struct ib_pd *ibpd,
> -			      struct ib_srq_init_attr *srq_init_attr,
> -			      struct ib_udata *udata);
> +int rvt_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *srq_init_attr,
> +		   struct ib_udata *udata);
>  int rvt_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
>  		   enum ib_srq_attr_mask attr_mask,
>  		   struct ib_udata *udata);
>  int rvt_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr);
> -int rvt_destroy_srq(struct ib_srq *ibsrq);
> +void rvt_destroy_srq(struct ib_srq *ibsrq);
>  
>  #endif          /* DEF_RVTSRQ_H */
> diff --git a/drivers/infiniband/sw/rdmavt/vt.c b/drivers/infiniband/sw/rdmavt/vt.c
> index f4b3bb57ab06..9546a837a8ac 100644
> --- a/drivers/infiniband/sw/rdmavt/vt.c
> +++ b/drivers/infiniband/sw/rdmavt/vt.c
> @@ -428,6 +428,7 @@ static const struct ib_device_ops rvt_dev_ops = {
>  
>  	INIT_RDMA_OBJ_SIZE(ib_ah, rvt_ah, ibah),
>  	INIT_RDMA_OBJ_SIZE(ib_pd, rvt_pd, ibpd),
> +	INIT_RDMA_OBJ_SIZE(ib_srq, rvt_srq, ibsrq),
>  	INIT_RDMA_OBJ_SIZE(ib_ucontext, rvt_ucontext, ibucontext),
>  };
>  
> diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c
> index 756bd36fd268..56cf18af016a 100644
> --- a/drivers/infiniband/sw/rxe/rxe_pool.c
> +++ b/drivers/infiniband/sw/rxe/rxe_pool.c
> @@ -57,7 +57,7 @@ struct rxe_type_info rxe_type_info[RXE_NUM_TYPES] = {
>  	[RXE_TYPE_SRQ] = {
>  		.name		= "rxe-srq",
>  		.size		= sizeof(struct rxe_srq),
> -		.flags		= RXE_POOL_INDEX,
> +		.flags		= RXE_POOL_INDEX | RXE_POOL_NO_ALLOC,
>  		.min_index	= RXE_MIN_SRQ_INDEX,
>  		.max_index	= RXE_MAX_SRQ_INDEX,
>  	},
> diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
> index c8c8a8a55a32..606ee6839722 100644
> --- a/drivers/infiniband/sw/rxe/rxe_verbs.c
> +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
> @@ -290,21 +290,20 @@ static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr)
>  	return err;
>  }
>  
> -static struct ib_srq *rxe_create_srq(struct ib_pd *ibpd,
> -				     struct ib_srq_init_attr *init,
> -				     struct ib_udata *udata)
> +static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init,
> +			  struct ib_udata *udata)
>  {
>  	int err;
> -	struct rxe_dev *rxe = to_rdev(ibpd->device);
> -	struct rxe_pd *pd = to_rpd(ibpd);
> +	struct rxe_dev *rxe = to_rdev(ibsrq->device);
> +	struct rxe_pd *pd = to_rpd(ibsrq->pd);
>  	struct rxe_ucontext *ucontext =
>  		rdma_udata_to_drv_context(udata, struct rxe_ucontext, ibuc);
> -	struct rxe_srq *srq;
> +	struct rxe_srq *srq = to_rsrq(ibsrq);
>  	struct rxe_create_srq_resp __user *uresp = NULL;
>  
>  	if (udata) {
>  		if (udata->outlen < sizeof(*uresp))
> -			return ERR_PTR(-EINVAL);
> +			return -EINVAL;
>  		uresp = udata->outbuf;
>  	}
>  
> @@ -312,13 +311,10 @@ static struct ib_srq *rxe_create_srq(struct ib_pd *ibpd,
>  	if (err)
>  		goto err1;
>  
> -	srq = rxe_alloc(&rxe->srq_pool);
> -	if (!srq) {
> -		err = -ENOMEM;
> +	err = rxe_add_to_pool(&rxe->srq_pool, &srq->pelem);
> +	if (err)
>  		goto err1;
> -	}
>  
> -	rxe_add_index(srq);
>  	rxe_add_ref(pd);
>  	srq->pd = pd;
>  
> @@ -326,14 +322,13 @@ static struct ib_srq *rxe_create_srq(struct ib_pd *ibpd,
>  	if (err)
>  		goto err2;
>  
> -	return &srq->ibsrq;
> +	return 0;
>  
>  err2:
>  	rxe_drop_ref(pd);
> -	rxe_drop_index(srq);
>  	rxe_drop_ref(srq);
>  err1:
> -	return ERR_PTR(err);
> +	return err;
>  }
>  
>  static int rxe_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
> @@ -381,7 +376,7 @@ static int rxe_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr)
>  	return 0;
>  }
>  
> -static int rxe_destroy_srq(struct ib_srq *ibsrq)
> +static void rxe_destroy_srq(struct ib_srq *ibsrq)
>  {
>  	struct rxe_srq *srq = to_rsrq(ibsrq);
>  
> @@ -389,10 +384,7 @@ static int rxe_destroy_srq(struct ib_srq *ibsrq)
>  		rxe_queue_cleanup(srq->rq.queue);
>  
>  	rxe_drop_ref(srq->pd);
> -	rxe_drop_index(srq);
>  	rxe_drop_ref(srq);
> -
> -	return 0;
>  }
>  
>  static int rxe_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
> @@ -1171,6 +1163,7 @@ static const struct ib_device_ops rxe_dev_ops = {
>  
>  	INIT_RDMA_OBJ_SIZE(ib_ah, rxe_ah, ibah),
>  	INIT_RDMA_OBJ_SIZE(ib_pd, rxe_pd, ibpd),
> +	INIT_RDMA_OBJ_SIZE(ib_srq, rxe_srq, ibsrq),
>  	INIT_RDMA_OBJ_SIZE(ib_ucontext, rxe_ucontext, ibuc),
>  };
>  
> diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
> index 23c5002b5134..e8be7f44e3be 100644
> --- a/drivers/infiniband/sw/rxe/rxe_verbs.h
> +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
> @@ -120,8 +120,8 @@ struct rxe_rq {
>  };
>  
>  struct rxe_srq {
> -	struct rxe_pool_entry	pelem;
>  	struct ib_srq		ibsrq;
> +	struct rxe_pool_entry	pelem;
>  	struct rxe_pd		*pd;
>  	struct rxe_rq		rq;
>  	u32			srq_num;
> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index 6777c30e796e..6c9de02cc7bf 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -2405,14 +2405,14 @@ struct ib_device_ops {
>  	int (*modify_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
>  	int (*query_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
>  	void (*destroy_ah)(struct ib_ah *ah, u32 flags);
> -	struct ib_srq *(*create_srq)(struct ib_pd *pd,
> -				     struct ib_srq_init_attr *srq_init_attr,
> -				     struct ib_udata *udata);
> +	int (*create_srq)(struct ib_srq *srq,
> +			  struct ib_srq_init_attr *srq_init_attr,
> +			  struct ib_udata *udata);
>  	int (*modify_srq)(struct ib_srq *srq, struct ib_srq_attr *srq_attr,
>  			  enum ib_srq_attr_mask srq_attr_mask,
>  			  struct ib_udata *udata);
>  	int (*query_srq)(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
> -	int (*destroy_srq)(struct ib_srq *srq);
> +	void (*destroy_srq)(struct ib_srq *srq);
>  	struct ib_qp *(*create_qp)(struct ib_pd *pd,
>  				   struct ib_qp_init_attr *qp_init_attr,
>  				   struct ib_udata *udata);
> @@ -2554,6 +2554,7 @@ struct ib_device_ops {
>  
>  	DECLARE_RDMA_OBJ_SIZE(ib_ah);
>  	DECLARE_RDMA_OBJ_SIZE(ib_pd);
> +	DECLARE_RDMA_OBJ_SIZE(ib_srq);
>  	DECLARE_RDMA_OBJ_SIZE(ib_ucontext);
>  };
>  
> 






[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux