rdma/qedr: Fix crash due to redundant release of device's qp memory
authorPrabhakar Kushwaha <pkushwaha@marvell.com>
Tue, 19 Oct 2021 08:22:12 +0000 (11:22 +0300)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 19 Oct 2021 23:17:44 +0000 (20:17 -0300)
Device's QP memory should only be allocated and released by IB layer.
This patch removes the redundant release of the device's qp memory and
uses completion APIs to make sure that .destroy_qp() only return, when qp
reference becomes 0.

Fixes: 514aee660df4 ("RDMA: Globally allocate and release QP memory")
Link: https://lore.kernel.org/r/20211019082212.7052-1-pkushwaha@marvell.com
Acked-by: Michal Kalderon <michal.kalderon@marvell.com>
Signed-off-by: Ariel Elior <aelior@marvell.com>
Signed-off-by: Shai Malin <smalin@marvell.com>
Signed-off-by: Alok Prasad <palok@marvell.com>
Signed-off-by: Prabhakar Kushwaha <pkushwaha@marvell.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/qedr/qedr.h
drivers/infiniband/hw/qedr/qedr_iw_cm.c
drivers/infiniband/hw/qedr/verbs.c

index 3cb4feb..8def88c 100644 (file)
@@ -455,6 +455,7 @@ struct qedr_qp {
        /* synchronization objects used with iwarp ep */
        struct kref refcnt;
        struct completion iwarp_cm_comp;
+       struct completion qp_rel_comp;
        unsigned long iwarp_cm_flags; /* enum iwarp_cm_flags */
 };
 
index 1715fbe..a51fc68 100644 (file)
@@ -83,7 +83,7 @@ static void qedr_iw_free_qp(struct kref *ref)
 {
        struct qedr_qp *qp = container_of(ref, struct qedr_qp, refcnt);
 
-       kfree(qp);
+       complete(&qp->qp_rel_comp);
 }
 
 static void
index 3fbf172..dcb3653 100644 (file)
@@ -1357,6 +1357,7 @@ static void qedr_set_common_qp_params(struct qedr_dev *dev,
        if (rdma_protocol_iwarp(&dev->ibdev, 1)) {
                kref_init(&qp->refcnt);
                init_completion(&qp->iwarp_cm_comp);
+               init_completion(&qp->qp_rel_comp);
        }
 
        qp->pd = pd;
@@ -2857,8 +2858,10 @@ int qedr_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
 
        qedr_free_qp_resources(dev, qp, udata);
 
-       if (rdma_protocol_iwarp(&dev->ibdev, 1))
+       if (rdma_protocol_iwarp(&dev->ibdev, 1)) {
                qedr_iw_qp_rem_ref(&qp->ibqp);
+               wait_for_completion(&qp->qp_rel_comp);
+       }
 
        return 0;
 }