diff options
author | Leon Romanovsky <leonro@mellanox.com> | 2019-05-28 14:37:29 +0300 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2019-06-11 16:39:49 -0400 |
commit | e39afe3d6dbd908d8fd189571a3c1561088a86c2 (patch) | |
tree | 6d724b8695661749d1153f3544266020715bec39 /drivers/infiniband/core/cq.c | |
parent | a52c8e2469c30cf7ac453d624aed9c168b23d1af (diff) | |
download | lwn-e39afe3d6dbd908d8fd189571a3c1561088a86c2.tar.gz lwn-e39afe3d6dbd908d8fd189571a3c1561088a86c2.zip |
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: Leon Romanovsky <leonro@mellanox.com>
Acked-by: Gal Pressman <galpress@amazon.com>
Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Tested-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/core/cq.c')
-rw-r--r-- | drivers/infiniband/core/cq.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/drivers/infiniband/core/cq.c b/drivers/infiniband/core/cq.c index 6ee62600a812..3b9412c69565 100644 --- a/drivers/infiniband/core/cq.c +++ b/drivers/infiniband/core/cq.c @@ -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); |