|
@@ -754,6 +754,12 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
|
|
|
struct ib_qp *qp;
|
|
|
int ret;
|
|
|
|
|
|
+ if (qp_init_attr->rwq_ind_tbl &&
|
|
|
+ (qp_init_attr->recv_cq ||
|
|
|
+ qp_init_attr->srq || qp_init_attr->cap.max_recv_wr ||
|
|
|
+ qp_init_attr->cap.max_recv_sge))
|
|
|
+ return ERR_PTR(-EINVAL);
|
|
|
+
|
|
|
/*
|
|
|
* If the callers is using the RDMA API calculate the resources
|
|
|
* needed for the RDMA READ/WRITE operations.
|
|
@@ -771,6 +777,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
|
|
|
qp->real_qp = qp;
|
|
|
qp->uobject = NULL;
|
|
|
qp->qp_type = qp_init_attr->qp_type;
|
|
|
+ qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl;
|
|
|
|
|
|
atomic_set(&qp->usecnt, 0);
|
|
|
qp->mrs_used = 0;
|
|
@@ -788,7 +795,8 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
|
|
|
qp->srq = NULL;
|
|
|
} else {
|
|
|
qp->recv_cq = qp_init_attr->recv_cq;
|
|
|
- atomic_inc(&qp_init_attr->recv_cq->usecnt);
|
|
|
+ if (qp_init_attr->recv_cq)
|
|
|
+ atomic_inc(&qp_init_attr->recv_cq->usecnt);
|
|
|
qp->srq = qp_init_attr->srq;
|
|
|
if (qp->srq)
|
|
|
atomic_inc(&qp_init_attr->srq->usecnt);
|
|
@@ -799,7 +807,10 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
|
|
|
qp->xrcd = NULL;
|
|
|
|
|
|
atomic_inc(&pd->usecnt);
|
|
|
- atomic_inc(&qp_init_attr->send_cq->usecnt);
|
|
|
+ if (qp_init_attr->send_cq)
|
|
|
+ atomic_inc(&qp_init_attr->send_cq->usecnt);
|
|
|
+ if (qp_init_attr->rwq_ind_tbl)
|
|
|
+ atomic_inc(&qp->rwq_ind_tbl->usecnt);
|
|
|
|
|
|
if (qp_init_attr->cap.max_rdma_ctxs) {
|
|
|
ret = rdma_rw_init_mrs(qp, qp_init_attr);
|
|
@@ -1279,6 +1290,7 @@ int ib_destroy_qp(struct ib_qp *qp)
|
|
|
struct ib_pd *pd;
|
|
|
struct ib_cq *scq, *rcq;
|
|
|
struct ib_srq *srq;
|
|
|
+ struct ib_rwq_ind_table *ind_tbl;
|
|
|
int ret;
|
|
|
|
|
|
WARN_ON_ONCE(qp->mrs_used > 0);
|
|
@@ -1293,6 +1305,7 @@ int ib_destroy_qp(struct ib_qp *qp)
|
|
|
scq = qp->send_cq;
|
|
|
rcq = qp->recv_cq;
|
|
|
srq = qp->srq;
|
|
|
+ ind_tbl = qp->rwq_ind_tbl;
|
|
|
|
|
|
if (!qp->uobject)
|
|
|
rdma_rw_cleanup_mrs(qp);
|
|
@@ -1307,6 +1320,8 @@ int ib_destroy_qp(struct ib_qp *qp)
|
|
|
atomic_dec(&rcq->usecnt);
|
|
|
if (srq)
|
|
|
atomic_dec(&srq->usecnt);
|
|
|
+ if (ind_tbl)
|
|
|
+ atomic_dec(&ind_tbl->usecnt);
|
|
|
}
|
|
|
|
|
|
return ret;
|