diff options
| author | Bart Van Assche <bart.vanassche@wdc.com> | 2018-08-02 13:44:42 -0400 |
|---|---|---|
| committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-08-03 13:53:51 -0400 |
| commit | 1214fd7b497400d200e3f4e64e2338b303a20949 (patch) | |
| tree | 821a5ceab8732ec48ae182834d1684dcfdd7aeb0 | |
| parent | 09c2f95ad404bc6e9995f5bce04ae85d0fffc534 (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>
| -rw-r--r-- | drivers/scsi/sr.c | 29 |
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) | |||
| 523 | static int sr_block_open(struct block_device *bdev, fmode_t mode) | 523 | static 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 | |||
| 545 | out: | ||
| 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 | ||
| 592 | put: | ||
| 593 | scsi_autopm_put_device(sdev); | ||
| 594 | |||
| 582 | out: | 595 | out: |
| 583 | mutex_unlock(&sr_mutex); | 596 | mutex_unlock(&sr_mutex); |
| 584 | return ret; | 597 | return ret; |
