mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
scsi: qla2xxx: Wait for io return on terminate rport
System crash due to use after free. Current code allows terminate_rport_io to exit before making sure all IOs has returned. For FCP-2 device, IO's can hang on in HW because driver has not tear down the session in FW at first sign of cable pull. When dev_loss_tmo timer pops, terminate_rport_io is called and upper layer is about to free various resources. Terminate_rport_io trigger qla to do the final cleanup, but the cleanup might not be fast enough where it leave qla still holding on to the same resource. Wait for IO's to return to upper layer before resources are freed. Cc: stable@vger.kernel.org Signed-off-by: Quinn Tran <qutran@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Link: https://lore.kernel.org/r/20230428075339.32551-7-njavali@marvell.com Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
b843adde8d
commit
fc0cba0c7b
@ -2750,6 +2750,7 @@ static void
|
||||
qla2x00_terminate_rport_io(struct fc_rport *rport)
|
||||
{
|
||||
fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
|
||||
scsi_qla_host_t *vha;
|
||||
|
||||
if (!fcport)
|
||||
return;
|
||||
@ -2759,9 +2760,12 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
|
||||
|
||||
if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
|
||||
return;
|
||||
vha = fcport->vha;
|
||||
|
||||
if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
|
||||
qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
|
||||
qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24,
|
||||
0, WAIT_TARGET);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@ -2786,6 +2790,15 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
|
||||
qla2x00_port_logout(fcport->vha, fcport);
|
||||
}
|
||||
}
|
||||
|
||||
/* check for any straggling io left behind */
|
||||
if (qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, 0, WAIT_TARGET)) {
|
||||
ql_log(ql_log_warn, vha, 0x300b,
|
||||
"IO not return. Resetting. \n");
|
||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||
qla2xxx_wake_dpc(vha);
|
||||
qla2x00_wait_for_chip_reset(vha);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
Loading…
Reference in New Issue
Block a user