Commit b71cbcf7 authored by Daniel Wagner's avatar Daniel Wagner Committed by Keith Busch
Browse files

nvme-fc: don't hold rport lock when putting ctrl



nvme_fc_ctrl_put can acquire the rport lock when freeing the
ctrl object:

nvme_fc_ctrl_put
  nvme_fc_ctrl_free
    spin_lock_irqsave(rport->lock)

Thus we can't hold the rport lock when calling nvme_fc_ctrl_put.

Justin suggested use the safe list iterator variant because
nvme_fc_ctrl_put will also modify the rport->list.

Cc: Justin Tee <justin.tee@broadcom.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDaniel Wagner <wagi@kernel.org>
Signed-off-by: default avatarKeith Busch <kbusch@kernel.org>
parent 78723fe3
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -1468,14 +1468,14 @@ nvme_fc_match_disconn_ls(struct nvme_fc_rport *rport,
{
	struct fcnvme_ls_disconnect_assoc_rqst *rqst =
					&lsop->rqstbuf->rq_dis_assoc;
	struct nvme_fc_ctrl *ctrl, *ret = NULL;
	struct nvme_fc_ctrl *ctrl, *tmp, *ret = NULL;
	struct nvmefc_ls_rcv_op *oldls = NULL;
	u64 association_id = be64_to_cpu(rqst->associd.association_id);
	unsigned long flags;

	spin_lock_irqsave(&rport->lock, flags);

	list_for_each_entry(ctrl, &rport->ctrl_list, ctrl_list) {
	list_for_each_entry_safe(ctrl, tmp, &rport->ctrl_list, ctrl_list) {
		if (!nvme_fc_ctrl_get(ctrl))
			continue;
		spin_lock(&ctrl->lock);
@@ -1488,7 +1488,9 @@ nvme_fc_match_disconn_ls(struct nvme_fc_rport *rport,
		if (ret)
			/* leave the ctrl get reference */
			break;
		spin_unlock_irqrestore(&rport->lock, flags);
		nvme_fc_ctrl_put(ctrl);
		spin_lock_irqsave(&rport->lock, flags);
	}

	spin_unlock_irqrestore(&rport->lock, flags);