* [PATCH] scsi: wait in scsi_remove_host till async scan ends
@ 2012-04-24 13:10 Tomas Henzl
0 siblings, 0 replies; only message in thread
From: Tomas Henzl @ 2012-04-24 13:10 UTC (permalink / raw)
To: 'linux-scsi@vger.kernel.org'
When a driver is rmmoded while a async scan is in progress, the lld is removed, and accessing
the host_template will causes a BUG : BUG: unable to handle kernel paging request at ffffffffa01874b8
This patch waits in the scsi_remove_host until the async scan ends. The scan thread checks for the host
state and the thread can end faster when the SHOST_CANCEL state is set.
Another possibility - locking the lld with try_module_get before the scan starts does have problems
with 'rmmod --wait' (BUG again), the reason is that in scsi_device_get we don't check the return value
of try_module_get. When this gets fixed, this code could be replaced with a try_module_get approach.
(This was added 85b6c720b0931101c8bcc3a5abdc2b8514b0fb4b [SCSI] sd: fix cache flushing on module removal (and individual device removal)
Signed-off-by: Tomas Henzl <thenzl@redhat.com>
---
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 351dc0b..269b23f 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -33,6 +33,7 @@
#include <linux/transport_class.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/delay.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
@@ -172,6 +173,12 @@ void scsi_remove_host(struct Scsi_Host *shost)
scsi_forget_host(shost);
mutex_unlock(&shost->scan_mutex);
scsi_proc_host_rm(shost);
+
+ while (shost->async_scan)
+ msleep(10);
+ /* the above while block needs to wait for a host_lock
+ * this is now provided by the next code block
+ */
spin_lock_irqsave(shost->host_lock, flags);
if (scsi_host_set_state(shost, SHOST_DEL))
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 29c4c04..02a36b2 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1743,10 +1743,9 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
data = kmalloc(sizeof(*data), GFP_KERNEL);
if (!data)
- goto err;
- data->shost = scsi_host_get(shost);
- if (!data->shost)
- goto err;
+ return NULL;
+
+ data->shost = shost;
init_completion(&data->prev_finished);
mutex_lock(&shost->scan_mutex);
@@ -1762,10 +1761,6 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
spin_unlock(&async_scan_lock);
return data;
-
- err:
- kfree(data);
- return NULL;
}
/**
@@ -1800,9 +1795,6 @@ static void scsi_finish_async_scan(struct async_scan_data *data)
scsi_sysfs_add_devices(shost);
- spin_lock_irqsave(shost->host_lock, flags);
- shost->async_scan = 0;
- spin_unlock_irqrestore(shost->host_lock, flags);
mutex_unlock(&shost->scan_mutex);
@@ -1816,7 +1808,11 @@ static void scsi_finish_async_scan(struct async_scan_data *data)
spin_unlock(&async_scan_lock);
scsi_autopm_put_host(shost);
- scsi_host_put(shost);
+
+ spin_lock_irqsave(shost->host_lock, flags);
+ shost->async_scan = 0;
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
kfree(data);
}
@@ -1827,8 +1823,14 @@ static void do_scsi_scan_host(struct Scsi_Host *shost)
if (shost->hostt->scan_start)
shost->hostt->scan_start(shost);
- while (!shost->hostt->scan_finished(shost, jiffies - start))
+ while (!shost->hostt->scan_finished(shost, jiffies - start)) {
msleep(10);
+ if (!scsi_host_scan_allowed(shost)) {
+ printk (KERN_INFO "scsi: host not in proper "
+ "state, async scan aborted ...\n");
+ break;
+ }
+ }
} else {
scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
SCAN_WILD_CARD, 0);
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2012-04-24 13:10 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-24 13:10 [PATCH] scsi: wait in scsi_remove_host till async scan ends Tomas Henzl
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).