linux/drivers/ide
Maurizio Lombardi 2bbea6e117 cdrom: do not call check_disk_change() inside cdrom_open()
when mounting an ISO filesystem sometimes (very rarely)
the system hangs because of a race condition between two tasks.

PID: 6766   TASK: ffff88007b2a6dd0  CPU: 0   COMMAND: "mount"
 #0 [ffff880078447ae0] __schedule at ffffffff8168d605
 #1 [ffff880078447b48] schedule_preempt_disabled at ffffffff8168ed49
 #2 [ffff880078447b58] __mutex_lock_slowpath at ffffffff8168c995
 #3 [ffff880078447bb8] mutex_lock at ffffffff8168bdef
 #4 [ffff880078447bd0] sr_block_ioctl at ffffffffa00b6818 [sr_mod]
 #5 [ffff880078447c10] blkdev_ioctl at ffffffff812fea50
 #6 [ffff880078447c70] ioctl_by_bdev at ffffffff8123a8b3
 #7 [ffff880078447c90] isofs_fill_super at ffffffffa04fb1e1 [isofs]
 #8 [ffff880078447da8] mount_bdev at ffffffff81202570
 #9 [ffff880078447e18] isofs_mount at ffffffffa04f9828 [isofs]
#10 [ffff880078447e28] mount_fs at ffffffff81202d09
#11 [ffff880078447e70] vfs_kern_mount at ffffffff8121ea8f
#12 [ffff880078447ea8] do_mount at ffffffff81220fee
#13 [ffff880078447f28] sys_mount at ffffffff812218d6
#14 [ffff880078447f80] system_call_fastpath at ffffffff81698c49
    RIP: 00007fd9ea914e9a  RSP: 00007ffd5d9bf648  RFLAGS: 00010246
    RAX: 00000000000000a5  RBX: ffffffff81698c49  RCX: 0000000000000010
    RDX: 00007fd9ec2bc210  RSI: 00007fd9ec2bc290  RDI: 00007fd9ec2bcf30
    RBP: 0000000000000000   R8: 0000000000000000   R9: 0000000000000010
    R10: 00000000c0ed0001  R11: 0000000000000206  R12: 00007fd9ec2bc040
    R13: 00007fd9eb6b2380  R14: 00007fd9ec2bc210  R15: 00007fd9ec2bcf30
    ORIG_RAX: 00000000000000a5  CS: 0033  SS: 002b

This task was trying to mount the cdrom.  It allocated and configured a
super_block struct and owned the write-lock for the super_block->s_umount
rwsem. While exclusively owning the s_umount lock, it called
sr_block_ioctl and waited to acquire the global sr_mutex lock.

PID: 6785   TASK: ffff880078720fb0  CPU: 0   COMMAND: "systemd-udevd"
 #0 [ffff880078417898] __schedule at ffffffff8168d605
 #1 [ffff880078417900] schedule at ffffffff8168dc59
 #2 [ffff880078417910] rwsem_down_read_failed at ffffffff8168f605
 #3 [ffff880078417980] call_rwsem_down_read_failed at ffffffff81328838
 #4 [ffff8800784179d0] down_read at ffffffff8168cde0
 #5 [ffff8800784179e8] get_super at ffffffff81201cc7
 #6 [ffff880078417a10] __invalidate_device at ffffffff8123a8de
 #7 [ffff880078417a40] flush_disk at ffffffff8123a94b
 #8 [ffff880078417a88] check_disk_change at ffffffff8123ab50
 #9 [ffff880078417ab0] cdrom_open at ffffffffa00a29e1 [cdrom]
#10 [ffff880078417b68] sr_block_open at ffffffffa00b6f9b [sr_mod]
#11 [ffff880078417b98] __blkdev_get at ffffffff8123ba86
#12 [ffff880078417bf0] blkdev_get at ffffffff8123bd65
#13 [ffff880078417c78] blkdev_open at ffffffff8123bf9b
#14 [ffff880078417c90] do_dentry_open at ffffffff811fc7f7
#15 [ffff880078417cd8] vfs_open at ffffffff811fc9cf
#16 [ffff880078417d00] do_last at ffffffff8120d53d
#17 [ffff880078417db0] path_openat at ffffffff8120e6b2
#18 [ffff880078417e48] do_filp_open at ffffffff8121082b
#19 [ffff880078417f18] do_sys_open at ffffffff811fdd33
#20 [ffff880078417f70] sys_open at ffffffff811fde4e
#21 [ffff880078417f80] system_call_fastpath at ffffffff81698c49
    RIP: 00007f29438b0c20  RSP: 00007ffc76624b78  RFLAGS: 00010246
    RAX: 0000000000000002  RBX: ffffffff81698c49  RCX: 0000000000000000
    RDX: 00007f2944a5fa70  RSI: 00000000000a0800  RDI: 00007f2944a5fa70
    RBP: 00007f2944a5f540   R8: 0000000000000000   R9: 0000000000000020
    R10: 00007f2943614c40  R11: 0000000000000246  R12: ffffffff811fde4e
    R13: ffff880078417f78  R14: 000000000000000c  R15: 00007f2944a4b010
    ORIG_RAX: 0000000000000002  CS: 0033  SS: 002b

This task tried to open the cdrom device, the sr_block_open function
acquired the global sr_mutex lock. The call to check_disk_change()
then saw an event flag indicating a possible media change and tried
to flush any cached data for the device.
As part of the flush, it tried to acquire the super_block->s_umount
lock associated with the cdrom device.
This was the same super_block as created and locked by the previous task.

The first task acquires the s_umount lock and then the sr_mutex_lock;
the second task acquires the sr_mutex_lock and then the s_umount lock.

This patch fixes the issue by moving check_disk_change() out of
cdrom_open() and let the caller take care of it.

Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-03-09 08:06:35 -07:00
..
aec62xx.c
ali14xx.c
alim15x3.c
amd74xx.c
atiixp.c
au1xxx-ide.c
buddha.c
cmd64x.c
cmd640.c cmd640: add __init attribute 2016-07-26 15:25:30 -07:00
cs5520.c
cs5530.c
cs5535.c
cs5536.c
cy82c693.c
delkin_cb.c
dtc2278.c
falconide.c
gayle.c
hpt366.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
ht6560b.c
icside.c ide: icside: remove incorrect initconst annotation 2016-03-20 16:59:27 -04:00
ide_platform.c
ide-4drives.c
ide-acpi.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-atapi.c ide: ide-atapi: fix compile error with defining macro DEBUG 2017-11-10 19:56:25 -07:00
ide-cd_ioctl.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-cd_verbose.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-cd.c cdrom: do not call check_disk_change() inside cdrom_open() 2018-03-09 08:06:35 -07:00
ide-cd.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-cs.c
ide-devsets.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-disk_ioctl.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-disk_proc.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-disk.c block: Use blk_queue_flag_*() in drivers instead of queue_flag_*() 2018-03-08 14:13:48 -07:00
ide-disk.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-dma-sff.c
ide-dma.c block: introduce new block status code type 2017-06-09 09:27:32 -06:00
ide-eh.c block: introduce new block status code type 2017-06-09 09:27:32 -06:00
ide-floppy_ioctl.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-floppy_proc.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-floppy.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-floppy.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-gd.c block: convert to device_add_disk() 2016-06-27 12:26:08 -07:00
ide-gd.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-generic.c Revert "ide: Fix interface autodetection in legacy IDE driver (trial #2)" 2017-01-09 15:27:59 -05:00
ide-io-std.c
ide-io.c ide: Convert timers to use timer_setup() 2017-11-06 12:50:03 -08:00
ide-ioctls.c block: Make most scsi_req_init() calls implicit 2017-06-20 19:27:14 -06:00
ide-iops.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
ide-legacy.c
ide-lib.c
ide-park.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-pci-generic.c
ide-pio-blacklist.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-pm.c Merge branch 'for-4.15/block' of git://git.kernel.dk/linux-block 2017-11-14 15:32:19 -08:00
ide-pnp.c PNP: ide: constify pnp_device_id 2017-08-16 11:25:16 -07:00
ide-probe.c block: Use blk_queue_flag_*() in drivers instead of queue_flag_*() 2018-03-08 14:13:48 -07:00
ide-proc.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
ide-scan-pci.c ide: fix IRQ assignment for PCI bus order probing 2017-10-03 14:03:31 -05:00
ide-sysfs.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ide-tape.c block: Make most scsi_req_init() calls implicit 2017-06-20 19:27:14 -06:00
ide-taskfile.c ide: remove duplicated assignment to 'cursg' 2018-01-29 15:01:09 -05:00
ide-timings.c ide: avoid warning for timings calculation 2017-07-21 04:37:22 +01:00
ide-xfer-mode.c
ide.c treewide: Fix function prototypes for module_param_call() 2017-10-31 15:30:37 +01:00
it821x.c ide: constify ide_dma_ops structures 2016-01-18 14:12:33 -05:00
it8172.c
it8213.c
jmicron.c
Kconfig block: fix CDROM dependency on BLK_DEV 2017-11-02 08:26:55 -06:00
macide.c
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ns87415.c
opti621.c
palm_bk3710.c ide: palm_bk3710: add __initdata to palm_bk3710_port_info 2017-02-27 20:43:26 -05:00
pdc202xx_new.c PCI: Remove includes of asm/pci-bridge.h 2016-02-05 16:29:28 -06:00
pdc202xx_old.c
piix.c
pmac.c ide: pmac: Convert to using %pOF instead of full_name 2017-09-01 16:42:51 +10:00
q40ide.c
qd65xx.c
qd65xx.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
rapide.c
rz1000.c
sc1200.c
serverworks.c
setup-pci.c ide: pci: free PCI BARs on initialization failure 2017-10-03 14:02:57 -05:00
sgiioc4.c
siimage.c block: introduce new block status code type 2017-06-09 09:27:32 -06:00
sis5513.c block: split scsi_request out of struct request 2017-01-27 15:08:35 -07:00
sl82c105.c sl82c105: deprecate pci_get_bus_and_slot() 2018-01-11 17:29:04 -06:00
slc90e66.c
tc86c001.c
triflex.c
trm290.c ide: constify ide_dma_ops structures 2016-01-18 14:12:33 -05:00
tx4938ide.c
tx4939ide.c
umc8672.c
via82cxxx.c