diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2008-08-14 00:37:01 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-08-16 11:24:12 -0400 |
commit | c795c1e4b68a74536f0fb18744d0e381ceb1f37e (patch) | |
tree | 5078b0f569d05c3a5a8108da139e83baf716854f /drivers | |
parent | 19851f136ab37d7ac6f7c865329d13db54712ec0 (diff) |
[SCSI] qla2xxx: Explicitly tear-down vports during PCI remove_one().
During internal testing, we've seen issues (hangs) with the
'deferred' vport tear-down-processing typically accompanied with
the fc_remove_host() call. This is due to the current
implementation's back-end vport handling being performed by the
physical-HA's DPC thread where premature shutdown could lead to
latent vport requests without a processor.
This should also address a problem reported by Gal Rosen
(http://marc.info/?l=linux-scsi&m=121731664417358&w=2) where the
driver would attempt to awaken a previously torn-down DPC thread
from interrupt context by implicitly calling wake_up_process()
rather than the driver's qla2xxx_wake_dpc() helper. Rather, than
reshuffle the remove_one() device-removal code, during unload,
depend on the driver's timer to wake-up the DPC process, by
limiting wake-ups based on an 'unloading' flag.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 13 |
3 files changed, 12 insertions, 4 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6da31ba94404..94a720eabfd8 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2237,6 +2237,7 @@ typedef struct scsi_qla_host { | |||
2237 | #define REGISTER_FDMI_NEEDED 26 | 2237 | #define REGISTER_FDMI_NEEDED 26 |
2238 | #define FCPORT_UPDATE_NEEDED 27 | 2238 | #define FCPORT_UPDATE_NEEDED 27 |
2239 | #define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */ | 2239 | #define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */ |
2240 | #define UNLOADING 29 | ||
2240 | 2241 | ||
2241 | uint32_t device_flags; | 2242 | uint32_t device_flags; |
2242 | #define DFLG_LOCAL_DEVICES BIT_0 | 2243 | #define DFLG_LOCAL_DEVICES BIT_0 |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index bc90d6b8d0a0..813bc7784c0a 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -2686,7 +2686,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *ha, | |||
2686 | set_bit(VP_IDX_ACQUIRED, &vha->vp_flags); | 2686 | set_bit(VP_IDX_ACQUIRED, &vha->vp_flags); |
2687 | set_bit(VP_DPC_NEEDED, &ha->dpc_flags); | 2687 | set_bit(VP_DPC_NEEDED, &ha->dpc_flags); |
2688 | 2688 | ||
2689 | wake_up_process(ha->dpc_thread); | 2689 | qla2xxx_wake_dpc(ha); |
2690 | } | 2690 | } |
2691 | } | 2691 | } |
2692 | 2692 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index e0880ad243be..26afe44265c7 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1775,10 +1775,15 @@ probe_out: | |||
1775 | static void | 1775 | static void |
1776 | qla2x00_remove_one(struct pci_dev *pdev) | 1776 | qla2x00_remove_one(struct pci_dev *pdev) |
1777 | { | 1777 | { |
1778 | scsi_qla_host_t *ha; | 1778 | scsi_qla_host_t *ha, *vha, *temp; |
1779 | 1779 | ||
1780 | ha = pci_get_drvdata(pdev); | 1780 | ha = pci_get_drvdata(pdev); |
1781 | 1781 | ||
1782 | list_for_each_entry_safe(vha, temp, &ha->vp_list, vp_list) | ||
1783 | fc_vport_terminate(vha->fc_vport); | ||
1784 | |||
1785 | set_bit(UNLOADING, &ha->dpc_flags); | ||
1786 | |||
1782 | qla2x00_dfs_remove(ha); | 1787 | qla2x00_dfs_remove(ha); |
1783 | 1788 | ||
1784 | qla84xx_put_chip(ha); | 1789 | qla84xx_put_chip(ha); |
@@ -2450,8 +2455,10 @@ qla2x00_do_dpc(void *data) | |||
2450 | void | 2455 | void |
2451 | qla2xxx_wake_dpc(scsi_qla_host_t *ha) | 2456 | qla2xxx_wake_dpc(scsi_qla_host_t *ha) |
2452 | { | 2457 | { |
2453 | if (ha->dpc_thread) | 2458 | struct task_struct *t = ha->dpc_thread; |
2454 | wake_up_process(ha->dpc_thread); | 2459 | |
2460 | if (!test_bit(UNLOADING, &ha->dpc_flags) && t) | ||
2461 | wake_up_process(t); | ||
2455 | } | 2462 | } |
2456 | 2463 | ||
2457 | /* | 2464 | /* |