Commit c795c1e4 authored by Andrew Vasquez's avatar Andrew Vasquez Committed by James Bottomley

[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: default avatarAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 19851f13
...@@ -2237,6 +2237,7 @@ typedef struct scsi_qla_host { ...@@ -2237,6 +2237,7 @@ typedef struct scsi_qla_host {
#define REGISTER_FDMI_NEEDED 26 #define REGISTER_FDMI_NEEDED 26
#define FCPORT_UPDATE_NEEDED 27 #define FCPORT_UPDATE_NEEDED 27
#define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */ #define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */
#define UNLOADING 29
uint32_t device_flags; uint32_t device_flags;
#define DFLG_LOCAL_DEVICES BIT_0 #define DFLG_LOCAL_DEVICES BIT_0
......
...@@ -2686,7 +2686,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *ha, ...@@ -2686,7 +2686,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *ha,
set_bit(VP_IDX_ACQUIRED, &vha->vp_flags); set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
set_bit(VP_DPC_NEEDED, &ha->dpc_flags); set_bit(VP_DPC_NEEDED, &ha->dpc_flags);
wake_up_process(ha->dpc_thread); qla2xxx_wake_dpc(ha);
} }
} }
......
...@@ -1775,10 +1775,15 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1775,10 +1775,15 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
static void static void
qla2x00_remove_one(struct pci_dev *pdev) qla2x00_remove_one(struct pci_dev *pdev)
{ {
scsi_qla_host_t *ha; scsi_qla_host_t *ha, *vha, *temp;
ha = pci_get_drvdata(pdev); ha = pci_get_drvdata(pdev);
list_for_each_entry_safe(vha, temp, &ha->vp_list, vp_list)
fc_vport_terminate(vha->fc_vport);
set_bit(UNLOADING, &ha->dpc_flags);
qla2x00_dfs_remove(ha); qla2x00_dfs_remove(ha);
qla84xx_put_chip(ha); qla84xx_put_chip(ha);
...@@ -2450,8 +2455,10 @@ qla2x00_do_dpc(void *data) ...@@ -2450,8 +2455,10 @@ qla2x00_do_dpc(void *data)
void void
qla2xxx_wake_dpc(scsi_qla_host_t *ha) qla2xxx_wake_dpc(scsi_qla_host_t *ha)
{ {
if (ha->dpc_thread) struct task_struct *t = ha->dpc_thread;
wake_up_process(ha->dpc_thread);
if (!test_bit(UNLOADING, &ha->dpc_flags) && t)
wake_up_process(t);
} }
/* /*
......
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