From 89ca743fc6a629f6c92b2c55e3091336c5974a8c Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Fri, 10 Aug 2007 08:40:54 +0000 Subject: [PATCH] Fixes a race, when an event comes on the driver unload, so DPC thread will try to use already half destroyed data. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@158 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t/qla_os.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/qla2x00t/qla_os.c b/qla2x00t/qla_os.c index f63edacae..ca9263b43 100644 --- a/qla2x00t/qla_os.c +++ b/qla2x00t/qla_os.c @@ -1657,6 +1657,21 @@ probe_out: } EXPORT_SYMBOL_GPL(qla2x00_probe_one); +static void +qla2x00_stop_dpc_thread(scsi_qla_host_t *ha) +{ + 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); + } +} + void qla2x00_remove_one(struct pci_dev *pdev) { scsi_qla_host_t *ha; @@ -1668,6 +1683,10 @@ void qla2x00_remove_one(struct pci_dev *pdev) if (qla_target.tgt_host_action != NULL) qla_target.tgt_host_action(ha, DISABLE_TARGET_MODE); #endif + + /* Necessary to prevent races with it */ + qla2x00_stop_dpc_thread(ha); + qla2x00_free_sysfs_attr(ha); fc_remove_host(ha->host); @@ -1694,16 +1713,7 @@ qla2x00_free_device(scsi_qla_host_t *ha) qla2x00_stop_timer(ha); /* 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_stop_dpc_thread(ha); /* Stop currently executing firmware. */ qla2x00_stop_firmware(ha);