Commit a9017e23 authored by Yishai Hadas's avatar Yishai Hadas Committed by Doug Ledford

IB/core: Extend create QP to get indirection table

Extend create QP to get Receive Work Queue (WQ) indirection table.

QP can be created with external Receive Work Queue indirection table,
in that case it is ready to receive immediately.
Signed-off-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarMatan Barak <matanb@mellanox.com>
Reviewed-by: default avatarSagi Grimberg <sagi@grimberg.me>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent c5f90929
...@@ -754,6 +754,12 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, ...@@ -754,6 +754,12 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
struct ib_qp *qp; struct ib_qp *qp;
int ret; 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 * If the callers is using the RDMA API calculate the resources
* needed for the RDMA READ/WRITE operations. * needed for the RDMA READ/WRITE operations.
...@@ -771,6 +777,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, ...@@ -771,6 +777,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->real_qp = qp; qp->real_qp = qp;
qp->uobject = NULL; qp->uobject = NULL;
qp->qp_type = qp_init_attr->qp_type; qp->qp_type = qp_init_attr->qp_type;
qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl;
atomic_set(&qp->usecnt, 0); atomic_set(&qp->usecnt, 0);
qp->mrs_used = 0; qp->mrs_used = 0;
...@@ -788,6 +795,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, ...@@ -788,6 +795,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->srq = NULL; qp->srq = NULL;
} else { } else {
qp->recv_cq = qp_init_attr->recv_cq; qp->recv_cq = qp_init_attr->recv_cq;
if (qp_init_attr->recv_cq)
atomic_inc(&qp_init_attr->recv_cq->usecnt); atomic_inc(&qp_init_attr->recv_cq->usecnt);
qp->srq = qp_init_attr->srq; qp->srq = qp_init_attr->srq;
if (qp->srq) if (qp->srq)
...@@ -799,7 +807,10 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, ...@@ -799,7 +807,10 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->xrcd = NULL; qp->xrcd = NULL;
atomic_inc(&pd->usecnt); atomic_inc(&pd->usecnt);
if (qp_init_attr->send_cq)
atomic_inc(&qp_init_attr->send_cq->usecnt); 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) { if (qp_init_attr->cap.max_rdma_ctxs) {
ret = rdma_rw_init_mrs(qp, qp_init_attr); ret = rdma_rw_init_mrs(qp, qp_init_attr);
...@@ -1279,6 +1290,7 @@ int ib_destroy_qp(struct ib_qp *qp) ...@@ -1279,6 +1290,7 @@ int ib_destroy_qp(struct ib_qp *qp)
struct ib_pd *pd; struct ib_pd *pd;
struct ib_cq *scq, *rcq; struct ib_cq *scq, *rcq;
struct ib_srq *srq; struct ib_srq *srq;
struct ib_rwq_ind_table *ind_tbl;
int ret; int ret;
WARN_ON_ONCE(qp->mrs_used > 0); WARN_ON_ONCE(qp->mrs_used > 0);
...@@ -1293,6 +1305,7 @@ int ib_destroy_qp(struct ib_qp *qp) ...@@ -1293,6 +1305,7 @@ int ib_destroy_qp(struct ib_qp *qp)
scq = qp->send_cq; scq = qp->send_cq;
rcq = qp->recv_cq; rcq = qp->recv_cq;
srq = qp->srq; srq = qp->srq;
ind_tbl = qp->rwq_ind_tbl;
if (!qp->uobject) if (!qp->uobject)
rdma_rw_cleanup_mrs(qp); rdma_rw_cleanup_mrs(qp);
...@@ -1307,6 +1320,8 @@ int ib_destroy_qp(struct ib_qp *qp) ...@@ -1307,6 +1320,8 @@ int ib_destroy_qp(struct ib_qp *qp)
atomic_dec(&rcq->usecnt); atomic_dec(&rcq->usecnt);
if (srq) if (srq)
atomic_dec(&srq->usecnt); atomic_dec(&srq->usecnt);
if (ind_tbl)
atomic_dec(&ind_tbl->usecnt);
} }
return ret; return ret;
......
...@@ -1017,6 +1017,7 @@ struct ib_qp_init_attr { ...@@ -1017,6 +1017,7 @@ struct ib_qp_init_attr {
* Only needed for special QP types, or when using the RW API. * Only needed for special QP types, or when using the RW API.
*/ */
u8 port_num; u8 port_num;
struct ib_rwq_ind_table *rwq_ind_tbl;
}; };
struct ib_qp_open_attr { struct ib_qp_open_attr {
...@@ -1511,6 +1512,7 @@ struct ib_qp { ...@@ -1511,6 +1512,7 @@ struct ib_qp {
void *qp_context; void *qp_context;
u32 qp_num; u32 qp_num;
enum ib_qp_type qp_type; enum ib_qp_type qp_type;
struct ib_rwq_ind_table *rwq_ind_tbl;
}; };
struct ib_mr { struct ib_mr {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment