From: Bob Pearson <rpearsonhpe@gmail.com>
Date: Wed, 20 Apr 2022 20:40:40 -0500
Subject: RDMA/rxe: Enforce IBA C11-17
Patch-mainline: v5.19-rc1
Git-commit: 4703b4f0d94a5f887297713a2f6c2916a1ef08fd
References: jsc#PED-1111
Add a counter to keep track of the number of WQs connected to a CQ and
return an error if destroy_cq() is called while the counter is non zero.
Link: https://lore.kernel.org/r/20220421014042.26985-8-rpearsonhpe@gmail.com
Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
drivers/infiniband/sw/rxe/rxe_qp.c | 10 ++++++++++
drivers/infiniband/sw/rxe/rxe_verbs.c | 6 ++++++
drivers/infiniband/sw/rxe/rxe_verbs.h | 1 +
3 files changed, 17 insertions(+)
--- a/drivers/infiniband/sw/rxe/rxe_qp.c
+++ b/drivers/infiniband/sw/rxe/rxe_qp.c
@@ -322,6 +322,9 @@ int rxe_qp_from_init(struct rxe_dev *rxe
qp->scq = scq;
qp->srq = srq;
+ atomic_inc(&rcq->num_wq);
+ atomic_inc(&scq->num_wq);
+
rxe_qp_init_misc(rxe, qp, init);
err = rxe_qp_init_req(rxe, qp, init, udata, uresp);
@@ -341,6 +344,9 @@ err2:
rxe_queue_cleanup(qp->sq.queue);
qp->sq.queue = NULL;
err1:
+ atomic_dec(&rcq->num_wq);
+ atomic_dec(&scq->num_wq);
+
qp->pd = NULL;
qp->rcq = NULL;
qp->scq = NULL;
@@ -798,10 +804,14 @@ static void rxe_qp_do_cleanup(struct wor
if (qp->rq.queue)
rxe_queue_cleanup(qp->rq.queue);
+ atomic_dec(&qp->scq->num_wq);
if (qp->scq)
rxe_put(qp->scq);
+
+ atomic_dec(&qp->rcq->num_wq);
if (qp->rcq)
rxe_put(qp->rcq);
+
if (qp->pd)
rxe_put(qp->pd);
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -795,6 +795,12 @@ static int rxe_destroy_cq(struct ib_cq *
{
struct rxe_cq *cq = to_rcq(ibcq);
+ /* See IBA C11-17: The CI shall return an error if this Verb is
+ * invoked while a Work Queue is still associated with the CQ.
+ */
+ if (atomic_read(&cq->num_wq))
+ return -EINVAL;
+
rxe_cq_disable(cq);
rxe_put(cq);
--- a/drivers/infiniband/sw/rxe/rxe_verbs.h
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
@@ -67,6 +67,7 @@ struct rxe_cq {
bool is_dying;
bool is_user;
struct tasklet_struct comp_task;
+ atomic_t num_wq;
};
enum wqe_state {