Commit b0810b03 authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

RDMA/core: Consolidate ib_create_srq flows

The uverbs layer largely duplicate the code in ib_create_srq(), with the
slight difference that it passes in a udata. Move all the code together
into ib_create_srq_user() and provide an inline for kernel users, similar
to other create calls.

Link: https://lore.kernel.org/r/20200506082444.14502-6-leon@kernel.org


Signed-off-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent dbd67252
Loading
Loading
Loading
Loading
+6 −34
Original line number Diff line number Diff line
@@ -3444,38 +3444,15 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
	attr.attr.srq_limit = cmd->srq_limit;

	INIT_LIST_HEAD(&obj->uevent.event_list);
	obj->uevent.uobject.user_handle = cmd->user_handle;

	srq = rdma_zalloc_drv_obj(ib_dev, ib_srq);
	if (!srq) {
		ret = -ENOMEM;
		goto err_put;
	}

	srq->device        = pd->device;
	srq->pd            = pd;
	srq->srq_type	   = cmd->srq_type;
	srq->uobject       = obj;
	srq->event_handler = attr.event_handler;

	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);
	}

	if (cmd->srq_type == IB_SRQT_XRC) {
		srq->ext.xrc.xrcd = attr.ext.xrc.xrcd;
		atomic_inc(&attr.ext.xrc.xrcd->usecnt);
	srq = ib_create_srq_user(pd, &attr, obj, udata);
	if (IS_ERR(srq)) {
		ret = PTR_ERR(srq);
		goto err_put_pd;
	}

	atomic_inc(&pd->usecnt);
	atomic_set(&srq->usecnt, 0);

	obj->uevent.uobject.object = srq;
	obj->uevent.uobject.user_handle = cmd->user_handle;

	memset(&resp, 0, sizeof resp);
	resp.srq_handle = obj->uevent.uobject.id;
@@ -3501,13 +3478,8 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,

err_copy:
	ib_destroy_srq_user(srq, uverbs_get_cleared_udata(attrs));
	/* It was released in ib_destroy_srq_user */
	srq = NULL;
err_free:
	kfree(srq);
err_put:
err_put_pd:
	uobj_put_obj_read(pd);

err_put_cq:
	if (ib_srq_has_cq(cmd->srq_type))
		rdma_lookup_put_uobject(&attr.ext.cq->uobject->uevent.uobject,
+22 −7
Original line number Diff line number Diff line
@@ -981,15 +981,29 @@ EXPORT_SYMBOL(rdma_destroy_ah_user);

/* Shared receive queues */

struct ib_srq *ib_create_srq(struct ib_pd *pd,
			     struct ib_srq_init_attr *srq_init_attr)
/**
 * ib_create_srq_user - Creates a SRQ associated with the specified protection
 *   domain.
 * @pd: The protection domain associated with the SRQ.
 * @srq_init_attr: A list of initial attributes required to create the
 *   SRQ.  If SRQ creation succeeds, then the attributes are updated to
 *   the actual capabilities of the created SRQ.
 * @uobject - uobject pointer if this is not a kernel SRQ
 * @udata - udata pointer if this is not a kernel SRQ
 *
 * srq_attr->max_wr and srq_attr->max_sge are read the determine the
 * requested size of the SRQ, and set to the actual values allocated
 * on return.  If ib_create_srq() succeeds, then max_wr and max_sge
 * will always be at least as large as the requested values.
 */
struct ib_srq *ib_create_srq_user(struct ib_pd *pd,
				  struct ib_srq_init_attr *srq_init_attr,
				  struct ib_usrq_object *uobject,
				  struct ib_udata *udata)
{
	struct ib_srq *srq;
	int ret;

	if (!pd->device->ops.create_srq)
		return ERR_PTR(-EOPNOTSUPP);

	srq = rdma_zalloc_drv_obj(pd->device, ib_srq);
	if (!srq)
		return ERR_PTR(-ENOMEM);
@@ -999,6 +1013,7 @@ struct ib_srq *ib_create_srq(struct ib_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;
	srq->uobject = uobject;

	if (ib_srq_has_cq(srq->srq_type)) {
		srq->ext.cq = srq_init_attr->ext.cq;
@@ -1010,7 +1025,7 @@ struct ib_srq *ib_create_srq(struct ib_pd *pd,
	}
	atomic_inc(&pd->usecnt);

	ret = pd->device->ops.create_srq(srq, srq_init_attr, NULL);
	ret = pd->device->ops.create_srq(srq, srq_init_attr, udata);
	if (ret) {
		atomic_dec(&srq->pd->usecnt);
		if (srq->srq_type == IB_SRQT_XRC)
@@ -1023,7 +1038,7 @@ struct ib_srq *ib_create_srq(struct ib_pd *pd,

	return srq;
}
EXPORT_SYMBOL(ib_create_srq);
EXPORT_SYMBOL(ib_create_srq_user);

int ib_modify_srq(struct ib_srq *srq,
		  struct ib_srq_attr *srq_attr,
+12 −15
Original line number Diff line number Diff line
@@ -3559,21 +3559,18 @@ static inline int rdma_destroy_ah(struct ib_ah *ah, u32 flags)
	return rdma_destroy_ah_user(ah, flags, NULL);
}

/**
 * ib_create_srq - Creates a SRQ associated with the specified protection
 *   domain.
 * @pd: The protection domain associated with the SRQ.
 * @srq_init_attr: A list of initial attributes required to create the
 *   SRQ.  If SRQ creation succeeds, then the attributes are updated to
 *   the actual capabilities of the created SRQ.
 *
 * srq_attr->max_wr and srq_attr->max_sge are read the determine the
 * requested size of the SRQ, and set to the actual values allocated
 * on return.  If ib_create_srq() succeeds, then max_wr and max_sge
 * will always be at least as large as the requested values.
 */
struct ib_srq *ib_create_srq(struct ib_pd *pd,
			     struct ib_srq_init_attr *srq_init_attr);
struct ib_srq *ib_create_srq_user(struct ib_pd *pd,
				  struct ib_srq_init_attr *srq_init_attr,
				  struct ib_usrq_object *uobject,
				  struct ib_udata *udata);
static inline struct ib_srq *
ib_create_srq(struct ib_pd *pd, struct ib_srq_init_attr *srq_init_attr)
{
	if (!pd->device->ops.create_srq)
		return ERR_PTR(-EOPNOTSUPP);

	return ib_create_srq_user(pd, srq_init_attr, NULL, NULL);
}

/**
 * ib_modify_srq - Modifies the attributes for the specified SRQ.