aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2019-04-29 11:21:53 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2019-04-29 17:13:12 -0400
commit395b9bca6b81489c59d1182183aeac65b1a47c3d (patch)
treec007f07b823325bb2a7d32036e2f7f332f0b97cd /drivers/scsi/sd.c
parentscsi: sd: Revert "Inline sd_probe_part2()" (diff)
downloadlinux-dev-395b9bca6b81489c59d1182183aeac65b1a47c3d.tar.xz
linux-dev-395b9bca6b81489c59d1182183aeac65b1a47c3d.zip
scsi: sd: Revert "Rely on the driver core for asynchronous probing"
Hibernation hangs as follows due to commit 21e6ba3f0e02 when using SATA: Call Trace: __schedule+0x464/0xe70 schedule+0x4e/0xd0 blk_queue_enter+0x5fe/0x7e0 generic_make_request+0x313/0x950 submit_bio+0x9b/0x250 submit_bio_wait+0xc9/0x110 hib_submit_io+0x17d/0x1c0 write_page+0x61/0xa0 swap_write_page+0x4b/0x1f0 swsusp_write+0x2f9/0x3d0 hibernate.cold.10+0x108/0x231 state_store+0xf7/0x100 kobj_attr_store+0x37/0x50 sysfs_kf_write+0x87/0xa0 kernfs_fop_write+0x186/0x240 __vfs_write+0x4d/0x90 vfs_write+0xfa/0x260 ksys_write+0xb9/0x1a0 __x64_sys_write+0x43/0x50 do_syscall_64+0x71/0x210 entry_SYSCALL_64_after_hwframe+0x49/0xbe Hence revert commit 21e6ba3f0e02. Cc: Pavel Machek <pavel@ucw.cz> Reported-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Bart Van Assche <bvanassche@acm.org> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index f29c0ca8a5f1..2b2bc4b49d78 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -567,7 +567,6 @@ 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,
@@ -3285,8 +3284,12 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
return 0;
}
-static void sd_probe_part2(struct scsi_disk *sdkp)
+/*
+ * The asynchronous part of sd_probe
+ */
+static void sd_probe_async(void *data, async_cookie_t cookie)
{
+ struct scsi_disk *sdkp = data;
struct scsi_device *sdp;
struct gendisk *gd;
u32 index;
@@ -3340,6 +3343,7 @@ static void sd_probe_part2(struct scsi_disk *sdkp)
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
sdp->removable ? "removable " : "");
scsi_autopm_put_device(sdp);
+ put_device(&sdkp->dev);
}
/**
@@ -3431,7 +3435,8 @@ static int sd_probe(struct device *dev)
get_device(dev);
dev_set_drvdata(dev, sdkp);
- sd_probe_part2(sdkp);
+ get_device(&sdkp->dev); /* prevent release before async_schedule */
+ async_schedule_domain(sd_probe_async, sdkp, &scsi_sd_probe_domain);
return 0;
@@ -3466,6 +3471,8 @@ 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);