aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/core_priv.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/core/core_priv.h')
-rw-r--r--drivers/infiniband/core/core_priv.h28
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 647cca4e0240..fa2e0bbaf8c7 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -322,13 +322,14 @@ _ib_create_qp(struct ib_device *dev, struct ib_pd *pd,
struct ib_uqp_object *uobj, const char *caller)
{
struct ib_qp *qp;
+ int ret;
if (!dev->ops.create_qp)
return ERR_PTR(-EOPNOTSUPP);
- qp = dev->ops.create_qp(pd, attr, udata);
- if (IS_ERR(qp))
- return qp;
+ qp = rdma_zalloc_drv_obj_numa(dev, ib_qp);
+ if (!qp)
+ return ERR_PTR(-ENOMEM);
qp->device = dev;
qp->pd = pd;
@@ -337,14 +338,10 @@ _ib_create_qp(struct ib_device *dev, struct ib_pd *pd,
qp->qp_type = attr->qp_type;
qp->rwq_ind_tbl = attr->rwq_ind_tbl;
- qp->send_cq = attr->send_cq;
- qp->recv_cq = attr->recv_cq;
qp->srq = attr->srq;
- qp->rwq_ind_tbl = attr->rwq_ind_tbl;
qp->event_handler = attr->event_handler;
qp->port = attr->port_num;
- atomic_set(&qp->usecnt, 0);
spin_lock_init(&qp->mr_lock);
INIT_LIST_HEAD(&qp->rdma_mrs);
INIT_LIST_HEAD(&qp->sig_mrs);
@@ -352,8 +349,25 @@ _ib_create_qp(struct ib_device *dev, struct ib_pd *pd,
rdma_restrack_new(&qp->res, RDMA_RESTRACK_QP);
WARN_ONCE(!udata && !caller, "Missing kernel QP owner");
rdma_restrack_set_name(&qp->res, udata ? NULL : caller);
+ ret = dev->ops.create_qp(qp, attr, udata);
+ if (ret)
+ goto err_create;
+
+ /*
+ * TODO: The mlx4 internally overwrites send_cq and recv_cq.
+ * Unfortunately, it is not an easy task to fix that driver.
+ */
+ qp->send_cq = attr->send_cq;
+ qp->recv_cq = attr->recv_cq;
+
rdma_restrack_add(&qp->res);
return qp;
+
+err_create:
+ rdma_restrack_put(&qp->res);
+ kfree(qp);
+ return ERR_PTR(ret);
+
}
struct rdma_dev_addr;