aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2008-08-14 00:37:01 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-08-16 11:24:12 -0400
commitc795c1e4b68a74536f0fb18744d0e381ceb1f37e (patch)
tree5078b0f569d05c3a5a8108da139e83baf716854f
parent19851f136ab37d7ac6f7c865329d13db54712ec0 (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>
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c13
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:
1775static void 1775static void
1776qla2x00_remove_one(struct pci_dev *pdev) 1776qla2x00_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)
2450void 2455void
2451qla2xxx_wake_dpc(scsi_qla_host_t *ha) 2456qla2xxx_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/*