From: Gleb C. <lna...@ya...> - 2023-07-19 08:38:00
|
Commit: e8a1a2f GitHub URL: https://github.com/SCST-project/scst/commit/e8a1a2f15ab1f2dce00d35accb3d5cc0b44f8e48 Author: Gleb Chesnokov Date: 2023-07-19T11:35:51+03:00 Log Message: ----------- qla2x00t-32gbit: 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: st...@vg... Signed-off-by: Quinn Tran <qu...@ma...> Signed-off-by: Nilesh Javali <nj...@ma...> Link: https://lore.kernel.org/r/202...@ma... Reviewed-by: Himanshu Madhani <him...@or...> Signed-off-by: Martin K. Petersen <mar...@or...> [ commit fc0cba0c7be8 upstream ] Modified Paths: -------------- qla2x00t-32gbit/qla_attr.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) =================================================================== diff --git a/qla2x00t-32gbit/qla_attr.c b/qla2x00t-32gbit/qla_attr.c index 16b6b5c..c9fc1d7 100644 --- a/qla2x00t-32gbit/qla_attr.c +++ b/qla2x00t-32gbit/qla_attr.c @@ -2821,6 +2821,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; @@ -2830,9 +2831,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; } /* @@ -2857,6 +2861,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 |