Commit 856e152a authored by Martin Wilck's avatar Martin Wilck Committed by Martin K. Petersen

scsi: qla2xxx: set UNLOADING before waiting for session deletion

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@suse.com
Fixes: 45235022 ("scsi: qla2xxx: Fix driver unload by shutting down chip")
Reviewed-by: default avatarArun Easi <aeasi@marvell.com>
Reviewed-by: default avatarDaniel Wagner <dwagner@suse.de>
Reviewed-by: default avatarRoman Bolshakov <r.bolshakov@yadro.com>
Reviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarMartin Wilck <mwilck@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 6cbb7aed
......@@ -3732,6 +3732,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) ||
IS_QLA28XX(ha)) {
if (ha->flags.fw_started)
......@@ -3750,15 +3757,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,
......@@ -6628,13 +6626,6 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work)
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");
......@@ -6645,9 +6636,14 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work)
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment