提交 b9978769 编写于 作者: A Andrew Vasquez 提交者: James Bottomley

[SCSI] qla2xxx: Ensure the timer and DPC routines complete prior to midlayer tear-down.

Since the routines can/will use resources such as devices and
rports that aren't valid after midlayer tear-down, correct this
potential race, by stopping the offending during the early stages
of the remove() callback.
Signed-off-by: NAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: NJames Bottomley <James.Bottomley@HansenPartnership.com>
上级 e612d465
...@@ -1890,6 +1890,16 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1890,6 +1890,16 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->max_queues = 0; ha->max_queues = 0;
probe_failed: probe_failed:
if (base_vha->timer_active)
qla2x00_stop_timer(base_vha);
base_vha->flags.online = 0;
if (ha->dpc_thread) {
struct task_struct *t = ha->dpc_thread;
ha->dpc_thread = NULL;
kthread_stop(t);
}
qla2x00_free_device(base_vha); qla2x00_free_device(base_vha);
scsi_host_put(base_vha->host); scsi_host_put(base_vha->host);
...@@ -1923,10 +1933,30 @@ qla2x00_remove_one(struct pci_dev *pdev) ...@@ -1923,10 +1933,30 @@ qla2x00_remove_one(struct pci_dev *pdev)
set_bit(UNLOADING, &base_vha->dpc_flags); set_bit(UNLOADING, &base_vha->dpc_flags);
qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
qla2x00_dfs_remove(base_vha); qla2x00_dfs_remove(base_vha);
qla84xx_put_chip(base_vha); qla84xx_put_chip(base_vha);
/* Disable timer */
if (base_vha->timer_active)
qla2x00_stop_timer(base_vha);
base_vha->flags.online = 0;
/* Kill the kernel thread for this host */
if (ha->dpc_thread) {
struct task_struct *t = ha->dpc_thread;
/*
* qla2xxx_wake_dpc checks for ->dpc_thread
* so we need to zero it out.
*/
ha->dpc_thread = NULL;
kthread_stop(t);
}
qla2x00_free_sysfs_attr(base_vha); qla2x00_free_sysfs_attr(base_vha);
fc_remove_host(base_vha->host); fc_remove_host(base_vha->host);
...@@ -1955,25 +1985,6 @@ static void ...@@ -1955,25 +1985,6 @@ static void
qla2x00_free_device(scsi_qla_host_t *vha) qla2x00_free_device(scsi_qla_host_t *vha)
{ {
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
/* Disable timer */
if (vha->timer_active)
qla2x00_stop_timer(vha);
vha->flags.online = 0;
/* Kill the kernel thread for this host */
if (ha->dpc_thread) {
struct task_struct *t = ha->dpc_thread;
/*
* qla2xxx_wake_dpc checks for ->dpc_thread
* so we need to zero it out.
*/
ha->dpc_thread = NULL;
kthread_stop(t);
}
if (ha->flags.fce_enabled) if (ha->flags.fce_enabled)
qla2x00_disable_fce_trace(vha, NULL, NULL); qla2x00_disable_fce_trace(vha, NULL, NULL);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册