Commit 118b0c86 authored by Arun Easi's avatar Arun Easi Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Fix losing target when it reappears during delete

FC target disappeared during port perturbation tests due to a race that
tramples target state.  Fix the issue by adding state checks before
proceeding.

Link: https://lore.kernel.org/r/20220616053508.27186-8-njavali@marvell.com


Fixes: 44c57f20 ("scsi: qla2xxx: Changes to support FCP2 Target")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarArun Easi <aeasi@marvell.com>
Signed-off-by: default avatarNilesh Javali <njavali@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 58d1c124
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -2714,8 +2714,12 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
	if (!fcport)
		return;

	/* Now that the rport has been deleted, set the fcport state to
	   FCS_DEVICE_DEAD */

	/*
	 * Now that the rport has been deleted, set the fcport state to
	 * FCS_DEVICE_DEAD, if the fcport is still lost.
	 */
	if (fcport->scan_state != QLA_FCPORT_FOUND)
		qla2x00_set_fcport_state(fcport, FCS_DEVICE_DEAD);

	/*
@@ -2723,8 +2727,11 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
	 * all local references.
	 */
	spin_lock_irqsave(host->host_lock, flags);
	/* Confirm port has not reappeared before clearing pointers. */
	if (rport->port_state != FC_PORTSTATE_ONLINE) {
		fcport->rport = fcport->drport = NULL;
		*((fc_port_t **)rport->dd_data) = NULL;
	}
	spin_unlock_irqrestore(host->host_lock, flags);

	if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
@@ -2757,9 +2764,12 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
	/*
	 * At this point all fcport's software-states are cleared.  Perform any
	 * final cleanup of firmware resources (PCBs and XCBs).
	 *
	 * Attempt to cleanup only lost devices.
	 */
	if (fcport->loop_id != FC_NO_LOOP_ID) {
		if (IS_FWI2_CAPABLE(fcport->vha->hw)) {
		if (IS_FWI2_CAPABLE(fcport->vha->hw) &&
		    fcport->scan_state != QLA_FCPORT_FOUND) {
			if (fcport->loop_id != FC_NO_LOOP_ID)
				fcport->logout_on_delete = 1;

@@ -2769,7 +2779,7 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
				       __LINE__);
				qlt_schedule_sess_for_deletion(fcport);
			}
		} else {
		} else if (!IS_FWI2_CAPABLE(fcport->vha->hw)) {
			qla2x00_port_logout(fcport->vha, fcport);
		}
	}