diff options
Diffstat (limited to 'drivers/infiniband/sw/siw/siw_verbs.c')
-rw-r--r-- | drivers/infiniband/sw/siw/siw_verbs.c | 54 |
1 files changed, 23 insertions, 31 deletions
diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c index 3f175f220a22..1b36350601fa 100644 --- a/drivers/infiniband/sw/siw/siw_verbs.c +++ b/drivers/infiniband/sw/siw/siw_verbs.c @@ -285,16 +285,16 @@ siw_mmap_entry_insert(struct siw_ucontext *uctx, * * Create QP of requested size on given device. * - * @pd: Protection Domain + * @qp: Queue pait * @attrs: Initial QP attributes. * @udata: used to provide QP ID, SQ and RQ size back to user. */ -struct ib_qp *siw_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *attrs, - struct ib_udata *udata) +int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, + struct ib_udata *udata) { - struct siw_qp *qp = NULL; + struct ib_pd *pd = ibqp->pd; + struct siw_qp *qp = to_siw_qp(ibqp); struct ib_device *base_dev = pd->device; struct siw_device *sdev = to_siw_dev(base_dev); struct siw_ucontext *uctx = @@ -307,17 +307,16 @@ struct ib_qp *siw_create_qp(struct ib_pd *pd, siw_dbg(base_dev, "create new QP\n"); if (attrs->create_flags) - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; if (atomic_inc_return(&sdev->num_qp) > SIW_MAX_QP) { siw_dbg(base_dev, "too many QP's\n"); - rv = -ENOMEM; - goto err_out; + return -ENOMEM; } if (attrs->qp_type != IB_QPT_RC) { siw_dbg(base_dev, "only RC QP's supported\n"); rv = -EOPNOTSUPP; - goto err_out; + goto err_atomic; } if ((attrs->cap.max_send_wr > SIW_MAX_QP_WR) || (attrs->cap.max_recv_wr > SIW_MAX_QP_WR) || @@ -325,13 +324,13 @@ struct ib_qp *siw_create_qp(struct ib_pd *pd, (attrs->cap.max_recv_sge > SIW_MAX_SGE)) { siw_dbg(base_dev, "QP size error\n"); rv = -EINVAL; - goto err_out; + goto err_atomic; } if (attrs->cap.max_inline_data > SIW_MAX_INLINE) { siw_dbg(base_dev, "max inline send: %d > %d\n", attrs->cap.max_inline_data, (int)SIW_MAX_INLINE); rv = -EINVAL; - goto err_out; + goto err_atomic; } /* * NOTE: we allow for zero element SQ and RQ WQE's SGL's @@ -340,19 +339,15 @@ struct ib_qp *siw_create_qp(struct ib_pd *pd, if (attrs->cap.max_send_wr + attrs->cap.max_recv_wr == 0) { siw_dbg(base_dev, "QP must have send or receive queue\n"); rv = -EINVAL; - goto err_out; + goto err_atomic; } if (!attrs->send_cq || (!attrs->recv_cq && !attrs->srq)) { siw_dbg(base_dev, "send CQ or receive CQ invalid\n"); rv = -EINVAL; - goto err_out; - } - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - rv = -ENOMEM; - goto err_out; + goto err_atomic; } + init_rwsem(&qp->state_lock); spin_lock_init(&qp->sq_lock); spin_lock_init(&qp->rq_lock); @@ -360,7 +355,7 @@ struct ib_qp *siw_create_qp(struct ib_pd *pd, rv = siw_qp_add(sdev, qp); if (rv) - goto err_out; + goto err_atomic; num_sqe = attrs->cap.max_send_wr; num_rqe = attrs->cap.max_recv_wr; @@ -482,23 +477,20 @@ struct ib_qp *siw_create_qp(struct ib_pd *pd, list_add_tail(&qp->devq, &sdev->qp_list); spin_unlock_irqrestore(&sdev->lock, flags); - return &qp->base_qp; + return 0; err_out_xa: xa_erase(&sdev->qp_xa, qp_id(qp)); -err_out: - if (qp) { - if (uctx) { - rdma_user_mmap_entry_remove(qp->sq_entry); - rdma_user_mmap_entry_remove(qp->rq_entry); - } - vfree(qp->sendq); - vfree(qp->recvq); - kfree(qp); + if (uctx) { + rdma_user_mmap_entry_remove(qp->sq_entry); + rdma_user_mmap_entry_remove(qp->rq_entry); } - atomic_dec(&sdev->num_qp); + vfree(qp->sendq); + vfree(qp->recvq); - return ERR_PTR(rv); +err_atomic: + atomic_dec(&sdev->num_qp); + return rv; } /* |