[PATCH 4.19 15/37] scsi: qla2xxx: set UNLOADING before waiting for session deletion
From: Greg Kroah-Hartman
Date: Mon May 04 2020 - 14:02:50 EST
From: Martin Wilck <mwilck@xxxxxxxx>
commit 856e152a3c08bf7987cbd41900741d83d9cddc8e upstream.
The purpose of the UNLOADING flag is to avoid port login procedures to
continue when a controller is in the process of shutting down. It makes
sense to set this flag before starting session teardown.
Furthermore, use atomic test_and_set_bit() to avoid the shutdown being run
multiple times in parallel. In qla2x00_disable_board_on_pci_error(), the
test for UNLOADING is postponed until after the check for an already
disabled PCI board.
Link: https://lore.kernel.org/r/20200421204621.19228-2-mwilck@xxxxxxxx
Fixes: 45235022da99 ("scsi: qla2xxx: Fix driver unload by shutting down chip")
Reviewed-by: Arun Easi <aeasi@xxxxxxxxxxx>
Reviewed-by: Daniel Wagner <dwagner@xxxxxxx>
Reviewed-by: Roman Bolshakov <r.bolshakov@xxxxxxxxx>
Reviewed-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx>
Signed-off-by: Martin Wilck <mwilck@xxxxxxxx>
Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
drivers/scsi/qla2xxx/qla_os.c | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3654,6 +3654,13 @@ qla2x00_remove_one(struct pci_dev *pdev)
}
qla2x00_wait_for_hba_ready(base_vha);
+ /*
+ * if UNLOADING flag is already set, then continue unload,
+ * where it was set first.
+ */
+ if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags))
+ return;
+
if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) {
if (ha->flags.fw_started)
qla2x00_abort_isp_cleanup(base_vha);
@@ -3671,15 +3678,6 @@ qla2x00_remove_one(struct pci_dev *pdev)
qla2x00_wait_for_sess_deletion(base_vha);
- /*
- * if UNLOAD flag is already set, then continue unload,
- * where it was set first.
- */
- if (test_bit(UNLOADING, &base_vha->dpc_flags))
- return;
-
- set_bit(UNLOADING, &base_vha->dpc_flags);
-
qla_nvme_delete(base_vha);
dma_free_coherent(&ha->pdev->dev,
@@ -5845,13 +5843,6 @@ qla2x00_disable_board_on_pci_error(struc
struct pci_dev *pdev = ha->pdev;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
- /*
- * if UNLOAD flag is already set, then continue unload,
- * where it was set first.
- */
- if (test_bit(UNLOADING, &base_vha->dpc_flags))
- return;
-
ql_log(ql_log_warn, base_vha, 0x015b,
"Disabling adapter.\n");
@@ -5862,9 +5853,14 @@ qla2x00_disable_board_on_pci_error(struc
return;
}
- qla2x00_wait_for_sess_deletion(base_vha);
+ /*
+ * if UNLOADING flag is already set, then continue unload,
+ * where it was set first.
+ */
+ if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags))
+ return;
- set_bit(UNLOADING, &base_vha->dpc_flags);
+ qla2x00_wait_for_sess_deletion(base_vha);
qla2x00_delete_all_vps(ha, base_vha);