All upstream scsi_device_put() calls happen from thread context. Hence simplify scsi_device_put() by always calling the release function synchronously. This patch prepares for constifying the SCSI host template by removing an assignment that clears the module pointer in the SCSI host template. scsi_device_dev_release_usercontext() was introduced in 2006 via commit 65110b216895 ("[SCSI] fix wrong context bugs in SCSI"). Cc: Christoph Hellwig <hch@xxxxxx> Cc: Ming Lei <ming.lei@xxxxxxxxxx> Cc: Hannes Reinecke <hare@xxxxxxx> Cc: John Garry <john.garry@xxxxxxxxxx> Cc: Mike Christie <michael.christie@xxxxxxxxxx> Cc: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxx> Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx> --- drivers/scsi/scsi.c | 2 ++ drivers/scsi/scsi_sysfs.c | 22 ++-------------------- include/scsi/scsi_device.h | 1 - 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 9feb0323bc44..1426b9b03612 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -588,6 +588,8 @@ void scsi_device_put(struct scsi_device *sdev) { struct module *mod = sdev->host->hostt->module; + might_sleep(); + put_device(&sdev->sdev_gendev); module_put(mod); } diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index c8b178983585..c76f5757b863 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -441,20 +441,15 @@ static void scsi_device_cls_release(struct device *class_dev) put_device(&sdev->sdev_gendev); } -static void scsi_device_dev_release_usercontext(struct work_struct *work) +static void scsi_device_dev_release(struct device *dev) { - struct scsi_device *sdev; + struct scsi_device *sdev = to_scsi_device(dev); struct device *parent; struct list_head *this, *tmp; struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL; struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL; struct scsi_vpd *vpd_pgb0 = NULL, *vpd_pgb1 = NULL, *vpd_pgb2 = NULL; unsigned long flags; - struct module *mod; - - sdev = container_of(work, struct scsi_device, ew.work); - - mod = sdev->host->hostt->module; parent = sdev->sdev_gendev.parent; @@ -516,19 +511,6 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) if (parent) put_device(parent); - module_put(mod); -} - -static void scsi_device_dev_release(struct device *dev) -{ - struct scsi_device *sdp = to_scsi_device(dev); - - /* Set module pointer as NULL in case of module unloading */ - if (!try_module_get(sdp->host->hostt->module)) - sdp->host->hostt->module = NULL; - - execute_in_process_context(scsi_device_dev_release_usercontext, - &sdp->ew); } static struct class sdev_class = { diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index c36656d8ac6c..24bdbf7999ab 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -236,7 +236,6 @@ struct scsi_device { struct device sdev_gendev, sdev_dev; - struct execute_work ew; /* used to get process context on put */ struct work_struct requeue_work; struct scsi_device_handler *handler;