RDMA/bnxt_re: Remove the qp from list only if the qp destroy succeeds
Driver crashes when destroy_qp is re-tried because of an error
returned. This is because the qp entry was removed from the qp list during
the first call.
Remove qp from the list only if destroy_qp returns success.
The driver will still trigger a WARN_ON due to the memory leaking, but at
least it isn't corrupting memory too.
Fixes: 8dae419f9e
("RDMA/bnxt_re: Refactor queue pair creation code")
Link: https://lore.kernel.org/r/1598292876-26529-2-git-send-email-selvin.xavier@broadcom.com
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
934d0ac9a6
commit
097a9d23b7
|
@ -752,12 +752,6 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
|
||||||
gsi_sqp = rdev->gsi_ctx.gsi_sqp;
|
gsi_sqp = rdev->gsi_ctx.gsi_sqp;
|
||||||
gsi_sah = rdev->gsi_ctx.gsi_sah;
|
gsi_sah = rdev->gsi_ctx.gsi_sah;
|
||||||
|
|
||||||
/* remove from active qp list */
|
|
||||||
mutex_lock(&rdev->qp_lock);
|
|
||||||
list_del(&gsi_sqp->list);
|
|
||||||
mutex_unlock(&rdev->qp_lock);
|
|
||||||
atomic_dec(&rdev->qp_count);
|
|
||||||
|
|
||||||
ibdev_dbg(&rdev->ibdev, "Destroy the shadow AH\n");
|
ibdev_dbg(&rdev->ibdev, "Destroy the shadow AH\n");
|
||||||
bnxt_qplib_destroy_ah(&rdev->qplib_res,
|
bnxt_qplib_destroy_ah(&rdev->qplib_res,
|
||||||
&gsi_sah->qplib_ah,
|
&gsi_sah->qplib_ah,
|
||||||
|
@ -772,6 +766,12 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
|
||||||
}
|
}
|
||||||
bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);
|
bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);
|
||||||
|
|
||||||
|
/* remove from active qp list */
|
||||||
|
mutex_lock(&rdev->qp_lock);
|
||||||
|
list_del(&gsi_sqp->list);
|
||||||
|
mutex_unlock(&rdev->qp_lock);
|
||||||
|
atomic_dec(&rdev->qp_count);
|
||||||
|
|
||||||
kfree(rdev->gsi_ctx.sqp_tbl);
|
kfree(rdev->gsi_ctx.sqp_tbl);
|
||||||
kfree(gsi_sah);
|
kfree(gsi_sah);
|
||||||
kfree(gsi_sqp);
|
kfree(gsi_sqp);
|
||||||
|
@ -792,11 +792,6 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
mutex_lock(&rdev->qp_lock);
|
|
||||||
list_del(&qp->list);
|
|
||||||
mutex_unlock(&rdev->qp_lock);
|
|
||||||
atomic_dec(&rdev->qp_count);
|
|
||||||
|
|
||||||
bnxt_qplib_flush_cqn_wq(&qp->qplib_qp);
|
bnxt_qplib_flush_cqn_wq(&qp->qplib_qp);
|
||||||
|
|
||||||
rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
|
rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
|
||||||
|
@ -819,6 +814,11 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
|
||||||
goto sh_fail;
|
goto sh_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&rdev->qp_lock);
|
||||||
|
list_del(&qp->list);
|
||||||
|
mutex_unlock(&rdev->qp_lock);
|
||||||
|
atomic_dec(&rdev->qp_count);
|
||||||
|
|
||||||
ib_umem_release(qp->rumem);
|
ib_umem_release(qp->rumem);
|
||||||
ib_umem_release(qp->sumem);
|
ib_umem_release(qp->sumem);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue