summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sr.c
diff options
context:
space:
mode:
authorBart Van Assche <bart.vanassche@wdc.com>2018-08-02 13:44:42 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2018-08-03 13:53:51 -0400
commit1214fd7b497400d200e3f4e64e2338b303a20949 (patch)
tree821a5ceab8732ec48ae182834d1684dcfdd7aeb0 /drivers/scsi/sr.c
parent09c2f95ad404bc6e9995f5bce04ae85d0fffc534 (diff)
scsi: sr: Avoid that opening a CD-ROM hangs with runtime power management enabled
Surround scsi_execute() calls with scsi_autopm_get_device() and scsi_autopm_put_device(). Note: removing sr_mutex protection from the scsi_cd_get() and scsi_cd_put() calls is safe because the purpose of sr_mutex is to serialize cdrom_*() calls. This patch avoids that complaints similar to the following appear in the kernel log if runtime power management is enabled: INFO: task systemd-udevd:650 blocked for more than 120 seconds. Not tainted 4.18.0-rc7-dbg+ #1 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. systemd-udevd D28176 650 513 0x00000104 Call Trace: __schedule+0x444/0xfe0 schedule+0x4e/0xe0 schedule_preempt_disabled+0x18/0x30 __mutex_lock+0x41c/0xc70 mutex_lock_nested+0x1b/0x20 __blkdev_get+0x106/0x970 blkdev_get+0x22c/0x5a0 blkdev_open+0xe9/0x100 do_dentry_open.isra.19+0x33e/0x570 vfs_open+0x7c/0xd0 path_openat+0x6e3/0x1120 do_filp_open+0x11c/0x1c0 do_sys_open+0x208/0x2d0 __x64_sys_openat+0x59/0x70 do_syscall_64+0x77/0x230 entry_SYSCALL_64_after_hwframe+0x49/0xbe Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com> Cc: Maurizio Lombardi <mlombard@redhat.com> Cc: Johannes Thumshirn <jthumshirn@suse.de> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: <stable@vger.kernel.org> Tested-by: Johannes Thumshirn <jthumshirn@suse.de> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r--drivers/scsi/sr.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 3f3cb72e0c0c..d0389b20574d 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -523,18 +523,26 @@ static int sr_init_command(struct scsi_cmnd *SCpnt)
523static int sr_block_open(struct block_device *bdev, fmode_t mode) 523static int sr_block_open(struct block_device *bdev, fmode_t mode)
524{ 524{
525 struct scsi_cd *cd; 525 struct scsi_cd *cd;
526 struct scsi_device *sdev;
526 int ret = -ENXIO; 527 int ret = -ENXIO;
527 528
529 cd = scsi_cd_get(bdev->bd_disk);
530 if (!cd)
531 goto out;
532
533 sdev = cd->device;
534 scsi_autopm_get_device(sdev);
528 check_disk_change(bdev); 535 check_disk_change(bdev);
529 536
530 mutex_lock(&sr_mutex); 537 mutex_lock(&sr_mutex);
531 cd = scsi_cd_get(bdev->bd_disk); 538 ret = cdrom_open(&cd->cdi, bdev, mode);
532 if (cd) {
533 ret = cdrom_open(&cd->cdi, bdev, mode);
534 if (ret)
535 scsi_cd_put(cd);
536 }
537 mutex_unlock(&sr_mutex); 539 mutex_unlock(&sr_mutex);
540
541 scsi_autopm_put_device(sdev);
542 if (ret)
543 scsi_cd_put(cd);
544
545out:
538 return ret; 546 return ret;
539} 547}
540 548
@@ -562,6 +570,8 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
562 if (ret) 570 if (ret)
563 goto out; 571 goto out;
564 572
573 scsi_autopm_get_device(sdev);
574
565 /* 575 /*
566 * Send SCSI addressing ioctls directly to mid level, send other 576 * Send SCSI addressing ioctls directly to mid level, send other
567 * ioctls to cdrom/block level. 577 * ioctls to cdrom/block level.
@@ -570,15 +580,18 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
570 case SCSI_IOCTL_GET_IDLUN: 580 case SCSI_IOCTL_GET_IDLUN:
571 case SCSI_IOCTL_GET_BUS_NUMBER: 581 case SCSI_IOCTL_GET_BUS_NUMBER:
572 ret = scsi_ioctl(sdev, cmd, argp); 582 ret = scsi_ioctl(sdev, cmd, argp);
573 goto out; 583 goto put;
574 } 584 }
575 585
576 ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); 586 ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg);
577 if (ret != -ENOSYS) 587 if (ret != -ENOSYS)
578 goto out; 588 goto put;
579 589
580 ret = scsi_ioctl(sdev, cmd, argp); 590 ret = scsi_ioctl(sdev, cmd, argp);
581 591
592put:
593 scsi_autopm_put_device(sdev);
594
582out: 595out:
583 mutex_unlock(&sr_mutex); 596 mutex_unlock(&sr_mutex);
584 return ret; 597 return ret;