From 5897b844b7f90d0159b878c279e680ca59e0c75e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 1 May 2019 12:14:11 -0400 Subject: scsi: sd: add a SPDX tag to sd.c sd.c is the only sd file missing licensing information. Add a GPLv2 tag for the default kernel license. Signed-off-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ebc80354714c..f3564e406160 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sd.c Copyright (C) 1992 Drew Eckhardt * Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale -- cgit v1.2.3 From f049cf1a7b6737c75884247c3f6383ef104d255a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 30 Apr 2019 14:39:18 -0700 Subject: scsi: sd: Rely on the driver core for asynchronous probing As explained during the 2018 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 domain and get_device()/put_device() pairs that became superfluous due to this change are removed. This patch does not affect the time needed for loading the scsi_debug kernel module with parameters delay=0 and max_luns=256. This patch depends on commit ef0ff68351be ("driver core: Probe devices asynchronously instead of the driver") that went upstream in kernel version v5.1-rc1. Cc: Lee Duncan Cc: Hannes Reinecke Cc: Luis Chamberlain Cc: Johannes Thumshirn Cc: Christoph Hellwig Cc: Pavel Machek Cc: Dan Williams Signed-off-by: Bart Van Assche Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- 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, 7 insertions(+), 24 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 49821f138ae0..8128165a46fa 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -86,15 +86,10 @@ 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() + * 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(). */ ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain); EXPORT_SYMBOL(scsi_sd_pm_domain); @@ -821,7 +816,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); diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index 3a5dfbb81622..cbdf61c1d667 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c @@ -176,11 +176,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(); } diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 5f21547b2ad2..cc2859d76d81 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -175,7 +175,6 @@ 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 f3564e406160..2ba7eef4105a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -568,6 +568,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, @@ -3253,12 +3254,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; @@ -3313,7 +3310,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); } /** @@ -3405,8 +3401,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; @@ -3442,7 +3437,6 @@ 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); -- cgit v1.2.3 From 82a54da641f3cacfa31db36fc58a5e903f804c22 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 30 Apr 2019 14:39:19 -0700 Subject: scsi: sd: Inline sd_probe_part2() Make sd_probe() easier to read by inlining sd_probe_part2(). This patch does not change any functionality. [mkp: applied by hand] Cc: Lee Duncan Cc: Hannes Reinecke Cc: Luis Chamberlain Cc: Johannes Thumshirn Cc: Christoph Hellwig Cc: Pavel Machek Signed-off-by: Bart Van Assche Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 103 +++++++++++++++++++++++------------------------------- 1 file changed, 44 insertions(+), 59 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 2ba7eef4105a..b2fef449590f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3254,64 +3254,6 @@ 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); - 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(sdp, &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 @@ -3401,7 +3343,50 @@ static int sd_probe(struct device *dev) get_device(dev); dev_set_drvdata(dev, sdkp); - sd_probe_part2(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); + 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(sdp, &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); return 0; -- cgit v1.2.3