@@ -85,19 +85,6 @@ unsigned int scsi_logging_level;
EXPORT_SYMBOL(scsi_logging_level);
#endif
-/* sd, scsi core and power management need to coordinate flushing async actions */
-ASYNC_DOMAIN(scsi_sd_probe_domain);
-EXPORT_SYMBOL(scsi_sd_probe_domain);
-
-/*
- * Separate domain (from scsi_sd_probe_domain) to maximize the benefit of
- * asynchronous system resume operations. It is marked 'exclusive' to avoid
- * being included in the async_synchronize_full() that is invoked by
- * dpm_resume()
- */
-ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain);
-EXPORT_SYMBOL(scsi_sd_pm_domain);
-
/**
* scsi_put_command - Free a scsi command block
* @cmd: command block to free
@@ -839,7 +826,6 @@ static void __exit exit_scsi(void)
scsi_exit_devinfo();
scsi_exit_procfs();
scsi_exit_queue();
- async_unregister_domain(&scsi_sd_probe_domain);
}
subsys_initcall(init_scsi);
@@ -54,9 +54,6 @@ static int scsi_dev_type_suspend(struct device *dev,
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int err;
- /* flush pending in-flight resume operations, suspend is synchronous */
- async_synchronize_full_domain(&scsi_sd_pm_domain);
-
err = scsi_device_quiesce(to_scsi_device(dev));
if (err == 0) {
err = cb(dev, pm);
@@ -149,18 +146,7 @@ static int scsi_bus_resume_common(struct device *dev,
if (scsi_is_sdev_device(dev) && pm_runtime_suspended(dev))
blk_set_runtime_active(to_scsi_device(dev)->request_queue);
- if (fn) {
- async_schedule_domain(fn, dev, &scsi_sd_pm_domain);
-
- /*
- * If a user has disabled async probing a likely reason
- * is due to a storage enclosure that does not inject
- * staggered spin-ups. For safety, make resume
- * synchronous as well in that case.
- */
- if (strncmp(scsi_scan_type, "async", 5) != 0)
- async_synchronize_full_domain(&scsi_sd_pm_domain);
- } else {
+ if (!fn) {
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
@@ -170,11 +156,7 @@ static int scsi_bus_resume_common(struct device *dev,
static int scsi_bus_prepare(struct device *dev)
{
- if (scsi_is_sdev_device(dev)) {
- /* sd probing uses async_schedule. Wait until it finishes. */
- async_synchronize_full_domain(&scsi_sd_probe_domain);
-
- } else if (scsi_is_host_device(dev)) {
+ if (scsi_is_host_device(dev)) {
/* Wait until async scanning is finished */
scsi_complete_async_scans();
}
@@ -175,9 +175,6 @@ static inline int scsi_autopm_get_host(struct Scsi_Host *h) { return 0; }
static inline void scsi_autopm_put_host(struct Scsi_Host *h) {}
#endif /* CONFIG_PM */
-extern struct async_domain scsi_sd_pm_domain;
-extern struct async_domain scsi_sd_probe_domain;
-
/* scsi_dh.c */
#ifdef CONFIG_SCSI_DH
void scsi_dh_add_device(struct scsi_device *sdev);
@@ -559,6 +559,7 @@ static struct scsi_driver sd_template = {
.name = "sd",
.owner = THIS_MODULE,
.probe = sd_probe,
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
.remove = sd_remove,
.shutdown = sd_shutdown,
.pm = &sd_pm_ops,
@@ -3231,12 +3232,8 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
return 0;
}
-/*
- * The asynchronous part of sd_probe
- */
-static void sd_probe_async(void *data, async_cookie_t cookie)
+static void sd_probe_part2(struct scsi_disk *sdkp)
{
- struct scsi_disk *sdkp = data;
struct scsi_device *sdp;
struct gendisk *gd;
u32 index;
@@ -3290,7 +3287,6 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
sdp->removable ? "removable " : "");
scsi_autopm_put_device(sdp);
- put_device(&sdkp->dev);
}
/**
@@ -3382,8 +3378,7 @@ static int sd_probe(struct device *dev)
get_device(dev);
dev_set_drvdata(dev, sdkp);
- get_device(&sdkp->dev); /* prevent release before async_schedule */
- async_schedule_domain(sd_probe_async, sdkp, &scsi_sd_probe_domain);
+ sd_probe_part2(sdkp);
return 0;
@@ -3418,8 +3413,6 @@ static int sd_remove(struct device *dev)
devt = disk_devt(sdkp->disk);
scsi_autopm_get_device(sdkp->device);
- async_synchronize_full_domain(&scsi_sd_pm_domain);
- async_synchronize_full_domain(&scsi_sd_probe_domain);
device_del(&sdkp->dev);
del_gendisk(sdkp->disk);
sd_shutdown(dev);
As explained during the LSF/MM session about increasing SCSI disk probing concurrency, the problems with the current probing approach are as follows: - The driver core is unaware of asynchronous SCSI LUN probing. wait_for_device_probe() waits for all asynchronous probes except asynchronous SCSI disk probes. - There is unnecessary serialization between sd_probe() and sd_remove(). This can lead to a deadlock. Hence this patch that modifies the sd driver such that it uses the driver core framework for asynchronous probing. The async domains and get_device()/put_device() pairs that became superfluous due to this change are removed. See also commit 3c31b52f96f7 ("scsi: async sd resume"). Signed-off-by: Bart Van Assche <bvanassche@acm.org> Cc: Lee Duncan <lduncan@suse.com> Cc: Hannes Reinecke <hare@suse.com> Cc: Luis R. Rodriguez <mcgrof@suse.com> Cc: Johannes Thumshirn <jthumshirn@suse.de> Cc: Christoph Hellwig <hch@lst.de> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Dan Williams <dan.j.williams@intel.com> --- drivers/scsi/scsi.c | 14 -------------- drivers/scsi/scsi_pm.c | 22 ++-------------------- drivers/scsi/scsi_priv.h | 3 --- drivers/scsi/sd.c | 13 +++---------- 4 files changed, 5 insertions(+), 47 deletions(-)