Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e39afe3d authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Doug Ledford
Browse files

RDMA: Convert CQ allocations to be under core responsibility



Ensure that CQ is allocated and freed by IB/core and not by drivers.

Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Acked-by: default avatarGal Pressman <galpress@amazon.com>
Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Tested-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent a52c8e24
Loading
Loading
Loading
Loading
+17 −11
Original line number Diff line number Diff line
@@ -147,23 +147,26 @@ struct ib_cq *__ib_alloc_cq_user(struct ib_device *dev, void *private,
	struct ib_cq *cq;
	int ret = -ENOMEM;

	cq = dev->ops.create_cq(dev, &cq_attr, NULL);
	if (IS_ERR(cq))
		return cq;
	cq = rdma_zalloc_drv_obj(dev, ib_cq);
	if (!cq)
		return ERR_PTR(ret);

	cq->device = dev;
	cq->uobject = NULL;
	cq->event_handler = NULL;
	cq->cq_context = private;
	cq->poll_ctx = poll_ctx;
	atomic_set(&cq->usecnt, 0);

	cq->wc = kmalloc_array(IB_POLL_BATCH, sizeof(*cq->wc), GFP_KERNEL);
	if (!cq->wc)
		goto out_destroy_cq;
		goto out_free_cq;

	cq->res.type = RDMA_RESTRACK_CQ;
	rdma_restrack_set_task(&cq->res, caller);

	ret = dev->ops.create_cq(cq, &cq_attr, NULL);
	if (ret)
		goto out_free_wc;

	rdma_restrack_kadd(&cq->res);

	switch (cq->poll_ctx) {
@@ -186,16 +189,18 @@ struct ib_cq *__ib_alloc_cq_user(struct ib_device *dev, void *private,
		break;
	default:
		ret = -EINVAL;
		goto out_free_wc;
		goto out_destroy_cq;
	}

	return cq;

out_free_wc:
	kfree(cq->wc);
	rdma_restrack_del(&cq->res);
out_destroy_cq:
	rdma_restrack_del(&cq->res);
	cq->device->ops.destroy_cq(cq, udata);
out_free_wc:
	kfree(cq->wc);
out_free_cq:
	kfree(cq);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL(__ib_alloc_cq_user);
@@ -224,8 +229,9 @@ void ib_free_cq_user(struct ib_cq *cq, struct ib_udata *udata)
		WARN_ON_ONCE(1);
	}

	kfree(cq->wc);
	rdma_restrack_del(&cq->res);
	cq->device->ops.destroy_cq(cq, udata);
	kfree(cq->wc);
	kfree(cq);
}
EXPORT_SYMBOL(ib_free_cq_user);
+1 −0
Original line number Diff line number Diff line
@@ -2431,6 +2431,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
	SET_DEVICE_OP(dev_ops, unmap_fmr);

	SET_OBJ_SIZE(dev_ops, ib_ah);
	SET_OBJ_SIZE(dev_ops, ib_cq);
	SET_OBJ_SIZE(dev_ops, ib_pd);
	SET_OBJ_SIZE(dev_ops, ib_srq);
	SET_OBJ_SIZE(dev_ops, ib_ucontext);
+10 −5
Original line number Diff line number Diff line
@@ -1010,12 +1010,11 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
	attr.comp_vector = cmd->comp_vector;
	attr.flags = cmd->flags;

	cq = ib_dev->ops.create_cq(ib_dev, &attr, &attrs->driver_udata);
	if (IS_ERR(cq)) {
		ret = PTR_ERR(cq);
	cq = rdma_zalloc_drv_obj(ib_dev, ib_cq);
	if (!cq) {
		ret = -ENOMEM;
		goto err_file;
	}

	cq->device        = ib_dev;
	cq->uobject       = &obj->uobject;
	cq->comp_handler  = ib_uverbs_comp_handler;
@@ -1023,6 +1022,10 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
	cq->cq_context    = ev_file ? &ev_file->ev_queue : NULL;
	atomic_set(&cq->usecnt, 0);

	ret = ib_dev->ops.create_cq(cq, &attr, &attrs->driver_udata);
	if (ret)
		goto err_free;

	obj->uobject.object = cq;
	memset(&resp, 0, sizeof resp);
	resp.base.cq_handle = obj->uobject.id;
@@ -1043,7 +1046,9 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,

err_cb:
	ib_destroy_cq(cq);

	cq = NULL;
err_free:
	kfree(cq);
err_file:
	if (ev_file)
		ib_uverbs_release_ucq(attrs->ufile, ev_file, obj);
+13 −6
Original line number Diff line number Diff line
@@ -111,9 +111,9 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
	INIT_LIST_HEAD(&obj->comp_list);
	INIT_LIST_HEAD(&obj->async_list);

	cq = ib_dev->ops.create_cq(ib_dev, &attr, &attrs->driver_udata);
	if (IS_ERR(cq)) {
		ret = PTR_ERR(cq);
	cq = rdma_zalloc_drv_obj(ib_dev, ib_cq);
	if (!cq) {
		ret = -ENOMEM;
		goto err_event_file;
	}

@@ -122,10 +122,15 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
	cq->comp_handler  = ib_uverbs_comp_handler;
	cq->event_handler = ib_uverbs_cq_event_handler;
	cq->cq_context    = ev_file ? &ev_file->ev_queue : NULL;
	obj->uobject.object = cq;
	obj->uobject.user_handle = user_handle;
	atomic_set(&cq->usecnt, 0);
	cq->res.type = RDMA_RESTRACK_CQ;

	ret = ib_dev->ops.create_cq(cq, &attr, &attrs->driver_udata);
	if (ret)
		goto err_free;

	obj->uobject.object = cq;
	obj->uobject.user_handle = user_handle;
	rdma_restrack_uadd(&cq->res);

	ret = uverbs_copy_to(attrs, UVERBS_ATTR_CREATE_CQ_RESP_CQE, &cq->cqe,
@@ -136,7 +141,9 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
	return 0;
err_cq:
	ib_destroy_cq(cq);

	cq = NULL;
err_free:
	kfree(cq);
err_event_file:
	if (ev_file)
		uverbs_uobject_put(ev_file_uobj);
+20 −12
Original line number Diff line number Diff line
@@ -1916,10 +1916,12 @@ struct ib_cq *__ib_create_cq(struct ib_device *device,
			     const char *caller)
{
	struct ib_cq *cq;
	int ret;

	cq = device->ops.create_cq(device, cq_attr, NULL);
	cq = rdma_zalloc_drv_obj(device, ib_cq);
	if (!cq)
		return ERR_PTR(-ENOMEM);

	if (!IS_ERR(cq)) {
	cq->device = device;
	cq->uobject = NULL;
	cq->comp_handler = comp_handler;
@@ -1928,9 +1930,14 @@ struct ib_cq *__ib_create_cq(struct ib_device *device,
	atomic_set(&cq->usecnt, 0);
	cq->res.type = RDMA_RESTRACK_CQ;
	rdma_restrack_set_task(&cq->res, caller);
		rdma_restrack_kadd(&cq->res);

	ret = device->ops.create_cq(cq, cq_attr, NULL);
	if (ret) {
		kfree(cq);
		return ERR_PTR(ret);
	}

	rdma_restrack_kadd(&cq->res);
	return cq;
}
EXPORT_SYMBOL(__ib_create_cq);
@@ -1950,6 +1957,7 @@ int ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata)

	rdma_restrack_del(&cq->res);
	cq->device->ops.destroy_cq(cq, udata);
	kfree(cq);
	return 0;
}
EXPORT_SYMBOL(ib_destroy_cq_user);
Loading