diff --git a/kernel-rt/centos/kernel-rt.spec b/kernel-rt/centos/kernel-rt.spec index 41dc5c40..51251bfd 100644 --- a/kernel-rt/centos/kernel-rt.spec +++ b/kernel-rt/centos/kernel-rt.spec @@ -790,6 +790,8 @@ Patch10: 0011-scsi-smartpqi-Enable-sas_address-sysfs-for-SATA-dev.patch Patch11: 0012-workqueue-Affine-rescuer-threads-and-unbound-wqs.patch Patch12: 0013-rcu-Mark-accesses-to-rcu_state.n_force_qs.patch Patch13: 0014-rcu-Tighten-rcu_advance_cbs_nowake-checks.patch +Patch14: 0015-Revert-scsi-sd-Inline-sd_probe_part2.patch +Patch15: 0016-Revert-commit-f049cf1a7b.patch # END OF PATCH DEFINITIONS %endif diff --git a/kernel-rt/centos/patches/0015-Revert-scsi-sd-Inline-sd_probe_part2.patch b/kernel-rt/centos/patches/0015-Revert-scsi-sd-Inline-sd_probe_part2.patch new file mode 100644 index 00000000..b5fb9260 --- /dev/null +++ b/kernel-rt/centos/patches/0015-Revert-scsi-sd-Inline-sd_probe_part2.patch @@ -0,0 +1,167 @@ +From 42f1ccc21f873a27c125a4e1aa3cb70a2336aa14 Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Wed, 8 Dec 2021 17:49:56 -0800 +Subject: [PATCH] Revert "scsi: sd: Inline sd_probe_part2()" + +This reverts commit 82a54da641f3cacfa31db36fc58a5e903f804c22. + +Merge conflicts were encountered when reverting this commit, which +inlines sd_probe_part2() into sd_probe(). However, the inlined parts +of sd_probe_part2() have since been modified. To avoid a difference +in behaviour, the updated code was relocated to sd_probe_part2(). + +The inlined code has been modified as follows since the inlining +happened: +The following code was added + if (sdp->rpm_autosuspend) { + pm_runtime_set_autosuspend_delay(dev, + sdp->host->hostt->rpm_autosuspend_delay); + } +between the following line + blk_pm_runtime_init(sdp->request_queue, dev); +and the following line + device_add_disk(dev, gd, NULL); + +In addition, init_opal_dev() is now passed the pointer "sdkp" +instead of "sdp" as the first argument. This commit ensures that +these two changes were accounted for when reverting the inlining +of sd_probe_part2(). + +Signed-off-by: M. Vefa Bicakci +Signed-off-by: Jiping Ma +--- + drivers/scsi/sd.c | 111 ++++++++++++++++++++++++++-------------------- + 1 file changed, 63 insertions(+), 48 deletions(-) + +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 56e291708587..d1d27516fc6a 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -3364,6 +3364,68 @@ 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) ++{ ++ struct scsi_device *sdp; ++ struct gendisk *gd; ++ u32 index; ++ struct device *dev; ++ ++ sdp = sdkp->device; ++ gd = sdkp->disk; ++ index = sdkp->index; ++ dev = &sdp->sdev_gendev; ++ ++ gd->major = sd_major((index & 0xf0) >> 4); ++ gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); ++ ++ gd->fops = &sd_fops; ++ gd->private_data = &sdkp->driver; ++ gd->queue = sdkp->device->request_queue; ++ ++ /* defaults, until the device tells us otherwise */ ++ sdp->sector_size = 512; ++ sdkp->capacity = 0; ++ sdkp->media_present = 1; ++ sdkp->write_prot = 0; ++ sdkp->cache_override = 0; ++ sdkp->WCE = 0; ++ sdkp->RCD = 0; ++ sdkp->ATO = 0; ++ sdkp->first_scan = 1; ++ sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; ++ ++ sd_revalidate_disk(gd); ++ ++ gd->flags = GENHD_FL_EXT_DEVT; ++ if (sdp->removable) { ++ gd->flags |= GENHD_FL_REMOVABLE; ++ gd->events |= DISK_EVENT_MEDIA_CHANGE; ++ gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT; ++ } ++ ++ blk_pm_runtime_init(sdp->request_queue, dev); ++ if (sdp->rpm_autosuspend) { ++ pm_runtime_set_autosuspend_delay(dev, ++ sdp->host->hostt->rpm_autosuspend_delay); ++ } ++ device_add_disk(dev, gd, NULL); ++ if (sdkp->capacity) ++ sd_dif_config_host(sdkp); ++ ++ sd_revalidate_disk(gd); ++ ++ if (sdkp->security) { ++ sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit); ++ if (sdkp->opal_dev) ++ sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n"); ++ } ++ ++ sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", ++ sdp->removable ? "removable " : ""); ++ scsi_autopm_put_device(sdp); ++} ++ + /** + * sd_probe - called during driver initialization and whenever a + * new scsi device is attached to the system. It is called once +@@ -3455,54 +3517,7 @@ static int sd_probe(struct device *dev) + + dev_set_drvdata(dev, sdkp); + +- gd->major = sd_major((index & 0xf0) >> 4); +- gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); +- +- gd->fops = &sd_fops; +- gd->private_data = &sdkp->driver; +- gd->queue = sdkp->device->request_queue; +- +- /* defaults, until the device tells us otherwise */ +- sdp->sector_size = 512; +- sdkp->capacity = 0; +- sdkp->media_present = 1; +- sdkp->write_prot = 0; +- sdkp->cache_override = 0; +- sdkp->WCE = 0; +- sdkp->RCD = 0; +- sdkp->ATO = 0; +- sdkp->first_scan = 1; +- sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; +- +- sd_revalidate_disk(gd); +- +- gd->flags = GENHD_FL_EXT_DEVT; +- if (sdp->removable) { +- gd->flags |= GENHD_FL_REMOVABLE; +- gd->events |= DISK_EVENT_MEDIA_CHANGE; +- gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT; +- } +- +- blk_pm_runtime_init(sdp->request_queue, dev); +- if (sdp->rpm_autosuspend) { +- pm_runtime_set_autosuspend_delay(dev, +- sdp->host->hostt->rpm_autosuspend_delay); +- } +- device_add_disk(dev, gd, NULL); +- if (sdkp->capacity) +- sd_dif_config_host(sdkp); +- +- sd_revalidate_disk(gd); +- +- if (sdkp->security) { +- sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit); +- if (sdkp->opal_dev) +- sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n"); +- } +- +- sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", +- sdp->removable ? "removable " : ""); +- scsi_autopm_put_device(sdp); ++ sd_probe_part2(sdkp); + + return 0; + +-- +2.31.1 + diff --git a/kernel-rt/centos/patches/0016-Revert-commit-f049cf1a7b.patch b/kernel-rt/centos/patches/0016-Revert-commit-f049cf1a7b.patch new file mode 100644 index 00000000..55e6ccaa --- /dev/null +++ b/kernel-rt/centos/patches/0016-Revert-commit-f049cf1a7b.patch @@ -0,0 +1,135 @@ +From b5dad6e67f9704968ca7d4daf1715667cddafa3d Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Wed, 8 Dec 2021 18:34:59 -0800 +Subject: [PATCH 2/2] Revert commit f049cf1a7b + +commit f049cf1a7b "scsi: sd: Rely on the driver core for asynchronous +probing" + +This reverts commit f049cf1a7b6737c75884247c3f6383ef104d255a, +and it is a clean revert, there is not any conflict. + +Signed-off-by: M. Vefa Bicakci +Signed-off-by: Jiping Ma +--- + drivers/scsi/scsi.c | 12 +++++++++--- + drivers/scsi/scsi_pm.c | 6 +++++- + drivers/scsi/scsi_priv.h | 1 + + drivers/scsi/sd.c | 12 +++++++++--- + 4 files changed, 24 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c +index 24619c3bebd5..3080292a16cd 100644 +--- a/drivers/scsi/scsi.c ++++ b/drivers/scsi/scsi.c +@@ -86,10 +86,15 @@ 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); ++ + /* +- * Domain for asynchronous system resume operations. It is marked 'exclusive' +- * to avoid being included in the async_synchronize_full() that is invoked by +- * dpm_resume(). ++ * 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); +@@ -799,6 +804,7 @@ 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); +diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c +index 3717eea37ecb..b3d71b516213 100644 +--- a/drivers/scsi/scsi_pm.c ++++ b/drivers/scsi/scsi_pm.c +@@ -175,7 +175,11 @@ static int scsi_bus_resume_common(struct device *dev, + + static int scsi_bus_prepare(struct device *dev) + { +- if (scsi_is_host_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)) { + /* Wait until async scanning is finished */ + scsi_complete_async_scans(); + } +diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h +index 180636d54982..c43456f0870c 100644 +--- a/drivers/scsi/scsi_priv.h ++++ b/drivers/scsi/scsi_priv.h +@@ -172,6 +172,7 @@ 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 +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 2e22ee4501e7..e6c70475f084 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -616,7 +616,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, +@@ -3364,8 +3363,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; +@@ -3424,6 +3427,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); + } + + /** +@@ -3517,7 +3521,8 @@ static int sd_probe(struct 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; + +@@ -3554,6 +3559,7 @@ static int sd_remove(struct device *dev) + 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); +-- +2.31.1 + diff --git a/kernel-std/centos/kernel.spec b/kernel-std/centos/kernel.spec index 71099268..ee6def05 100644 --- a/kernel-std/centos/kernel.spec +++ b/kernel-std/centos/kernel.spec @@ -823,6 +823,8 @@ Patch10: 0011-scsi-smartpqi-Enable-sas_address-sysfs-for-SATA-dev.patch Patch11: 0012-workqueue-Affine-rescuer-threads-and-unbound-wqs.patch Patch12: 0013-rcu-Mark-accesses-to-rcu_state.n_force_qs.patch Patch13: 0014-rcu-Tighten-rcu_advance_cbs_nowake-checks.patch +Patch14: 0015-Revert-scsi-sd-Inline-sd_probe_part2.patch +Patch15: 0016-Revert-commit-f049cf1a7b.patch # END OF PATCH DEFINITIONS %endif diff --git a/kernel-std/centos/patches/0015-Revert-scsi-sd-Inline-sd_probe_part2.patch b/kernel-std/centos/patches/0015-Revert-scsi-sd-Inline-sd_probe_part2.patch new file mode 100644 index 00000000..b5fb9260 --- /dev/null +++ b/kernel-std/centos/patches/0015-Revert-scsi-sd-Inline-sd_probe_part2.patch @@ -0,0 +1,167 @@ +From 42f1ccc21f873a27c125a4e1aa3cb70a2336aa14 Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Wed, 8 Dec 2021 17:49:56 -0800 +Subject: [PATCH] Revert "scsi: sd: Inline sd_probe_part2()" + +This reverts commit 82a54da641f3cacfa31db36fc58a5e903f804c22. + +Merge conflicts were encountered when reverting this commit, which +inlines sd_probe_part2() into sd_probe(). However, the inlined parts +of sd_probe_part2() have since been modified. To avoid a difference +in behaviour, the updated code was relocated to sd_probe_part2(). + +The inlined code has been modified as follows since the inlining +happened: +The following code was added + if (sdp->rpm_autosuspend) { + pm_runtime_set_autosuspend_delay(dev, + sdp->host->hostt->rpm_autosuspend_delay); + } +between the following line + blk_pm_runtime_init(sdp->request_queue, dev); +and the following line + device_add_disk(dev, gd, NULL); + +In addition, init_opal_dev() is now passed the pointer "sdkp" +instead of "sdp" as the first argument. This commit ensures that +these two changes were accounted for when reverting the inlining +of sd_probe_part2(). + +Signed-off-by: M. Vefa Bicakci +Signed-off-by: Jiping Ma +--- + drivers/scsi/sd.c | 111 ++++++++++++++++++++++++++-------------------- + 1 file changed, 63 insertions(+), 48 deletions(-) + +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 56e291708587..d1d27516fc6a 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -3364,6 +3364,68 @@ 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) ++{ ++ struct scsi_device *sdp; ++ struct gendisk *gd; ++ u32 index; ++ struct device *dev; ++ ++ sdp = sdkp->device; ++ gd = sdkp->disk; ++ index = sdkp->index; ++ dev = &sdp->sdev_gendev; ++ ++ gd->major = sd_major((index & 0xf0) >> 4); ++ gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); ++ ++ gd->fops = &sd_fops; ++ gd->private_data = &sdkp->driver; ++ gd->queue = sdkp->device->request_queue; ++ ++ /* defaults, until the device tells us otherwise */ ++ sdp->sector_size = 512; ++ sdkp->capacity = 0; ++ sdkp->media_present = 1; ++ sdkp->write_prot = 0; ++ sdkp->cache_override = 0; ++ sdkp->WCE = 0; ++ sdkp->RCD = 0; ++ sdkp->ATO = 0; ++ sdkp->first_scan = 1; ++ sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; ++ ++ sd_revalidate_disk(gd); ++ ++ gd->flags = GENHD_FL_EXT_DEVT; ++ if (sdp->removable) { ++ gd->flags |= GENHD_FL_REMOVABLE; ++ gd->events |= DISK_EVENT_MEDIA_CHANGE; ++ gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT; ++ } ++ ++ blk_pm_runtime_init(sdp->request_queue, dev); ++ if (sdp->rpm_autosuspend) { ++ pm_runtime_set_autosuspend_delay(dev, ++ sdp->host->hostt->rpm_autosuspend_delay); ++ } ++ device_add_disk(dev, gd, NULL); ++ if (sdkp->capacity) ++ sd_dif_config_host(sdkp); ++ ++ sd_revalidate_disk(gd); ++ ++ if (sdkp->security) { ++ sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit); ++ if (sdkp->opal_dev) ++ sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n"); ++ } ++ ++ sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", ++ sdp->removable ? "removable " : ""); ++ scsi_autopm_put_device(sdp); ++} ++ + /** + * sd_probe - called during driver initialization and whenever a + * new scsi device is attached to the system. It is called once +@@ -3455,54 +3517,7 @@ static int sd_probe(struct device *dev) + + dev_set_drvdata(dev, sdkp); + +- gd->major = sd_major((index & 0xf0) >> 4); +- gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); +- +- gd->fops = &sd_fops; +- gd->private_data = &sdkp->driver; +- gd->queue = sdkp->device->request_queue; +- +- /* defaults, until the device tells us otherwise */ +- sdp->sector_size = 512; +- sdkp->capacity = 0; +- sdkp->media_present = 1; +- sdkp->write_prot = 0; +- sdkp->cache_override = 0; +- sdkp->WCE = 0; +- sdkp->RCD = 0; +- sdkp->ATO = 0; +- sdkp->first_scan = 1; +- sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; +- +- sd_revalidate_disk(gd); +- +- gd->flags = GENHD_FL_EXT_DEVT; +- if (sdp->removable) { +- gd->flags |= GENHD_FL_REMOVABLE; +- gd->events |= DISK_EVENT_MEDIA_CHANGE; +- gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT; +- } +- +- blk_pm_runtime_init(sdp->request_queue, dev); +- if (sdp->rpm_autosuspend) { +- pm_runtime_set_autosuspend_delay(dev, +- sdp->host->hostt->rpm_autosuspend_delay); +- } +- device_add_disk(dev, gd, NULL); +- if (sdkp->capacity) +- sd_dif_config_host(sdkp); +- +- sd_revalidate_disk(gd); +- +- if (sdkp->security) { +- sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit); +- if (sdkp->opal_dev) +- sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n"); +- } +- +- sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", +- sdp->removable ? "removable " : ""); +- scsi_autopm_put_device(sdp); ++ sd_probe_part2(sdkp); + + return 0; + +-- +2.31.1 + diff --git a/kernel-std/centos/patches/0016-Revert-commit-f049cf1a7b.patch b/kernel-std/centos/patches/0016-Revert-commit-f049cf1a7b.patch new file mode 100644 index 00000000..55e6ccaa --- /dev/null +++ b/kernel-std/centos/patches/0016-Revert-commit-f049cf1a7b.patch @@ -0,0 +1,135 @@ +From b5dad6e67f9704968ca7d4daf1715667cddafa3d Mon Sep 17 00:00:00 2001 +From: Jiping Ma +Date: Wed, 8 Dec 2021 18:34:59 -0800 +Subject: [PATCH 2/2] Revert commit f049cf1a7b + +commit f049cf1a7b "scsi: sd: Rely on the driver core for asynchronous +probing" + +This reverts commit f049cf1a7b6737c75884247c3f6383ef104d255a, +and it is a clean revert, there is not any conflict. + +Signed-off-by: M. Vefa Bicakci +Signed-off-by: Jiping Ma +--- + drivers/scsi/scsi.c | 12 +++++++++--- + drivers/scsi/scsi_pm.c | 6 +++++- + drivers/scsi/scsi_priv.h | 1 + + drivers/scsi/sd.c | 12 +++++++++--- + 4 files changed, 24 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c +index 24619c3bebd5..3080292a16cd 100644 +--- a/drivers/scsi/scsi.c ++++ b/drivers/scsi/scsi.c +@@ -86,10 +86,15 @@ 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); ++ + /* +- * Domain for asynchronous system resume operations. It is marked 'exclusive' +- * to avoid being included in the async_synchronize_full() that is invoked by +- * dpm_resume(). ++ * 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); +@@ -799,6 +804,7 @@ 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); +diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c +index 3717eea37ecb..b3d71b516213 100644 +--- a/drivers/scsi/scsi_pm.c ++++ b/drivers/scsi/scsi_pm.c +@@ -175,7 +175,11 @@ static int scsi_bus_resume_common(struct device *dev, + + static int scsi_bus_prepare(struct device *dev) + { +- if (scsi_is_host_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)) { + /* Wait until async scanning is finished */ + scsi_complete_async_scans(); + } +diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h +index 180636d54982..c43456f0870c 100644 +--- a/drivers/scsi/scsi_priv.h ++++ b/drivers/scsi/scsi_priv.h +@@ -172,6 +172,7 @@ 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 +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 2e22ee4501e7..e6c70475f084 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -616,7 +616,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, +@@ -3364,8 +3363,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; +@@ -3424,6 +3427,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); + } + + /** +@@ -3517,7 +3521,8 @@ static int sd_probe(struct 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; + +@@ -3554,6 +3559,7 @@ static int sd_remove(struct device *dev) + 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); +-- +2.31.1 +