Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 77e44273 authored by Selvin Xavier's avatar Selvin Xavier Committed by Greg Kroah-Hartman
Browse files

RDMA/bnxt_re: Remove the qp from list only if the qp destroy succeeds

commit 097a9d23b7250355b182c5fd47dd4c55b22b1c33 upstream.

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: 8dae419f9ec7 ("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: default avatarSelvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a616aa25
Loading
Loading
Loading
Loading
+11 −11
Original line number Original line Diff line number Diff line
@@ -771,12 +771,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);

	dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n");
	dev_dbg(rdev_to_dev(rdev), "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,
@@ -791,6 +785,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);
@@ -811,11 +811,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);
@@ -838,6 +833,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);