s390/dcssblk: fix possible deadlock in remove vs. per-device attributes
authorGerald Schaefer <gerald.schaefer@de.ibm.com>
Fri, 8 Apr 2016 11:23:52 +0000 (13:23 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 15 Apr 2016 16:01:44 +0000 (18:01 +0200)
commit1378a683443753923eb22d01ce322e92a383ba8a
tree5ba6d2cf4fb1dc1f83cf4a7946ddedfb163cbfe2
parent4f375903ccbff78e1da02133e51e37a097cd3313
s390/dcssblk: fix possible deadlock in remove vs. per-device attributes

dcssblk_remove_store() holds the dcssblk_devices_sem semaphore while
calling device_unregister(), which in turn tries to acquire the kernfs
kn->dev_map rwsem for the device sysfs subtree. The same rwsem is also
acquired when using the per-device sysfs attributes in the device sub-tree,
and the attribute handlers then also acquire the dcssblk_devices_sem.

This can lead to a deadlock when removing a DCSS while concurrently
reading from / writing to one of its sysfs attributes. The following
lockdep warning hinted towards the issue (CPU0 = dcssblk_remove_store,
CPU1 = dcssblk_shared_store):

[   76.496047]  Possible unsafe locking scenario:

[   76.496054]        CPU0                    CPU1
[   76.496059]        ----                    ----
[   76.496087]   lock(&dcssblk_devices_sem);
[   76.496090]                                lock(s_active#175);
[   76.496106]                                lock(&dcssblk_devices_sem);
[   76.496110]   lock(s_active#175);
[   76.496115]
 *** DEADLOCK ***

Fix this by releasing the dcssblk_devices_sem semaphore, which only
protects internal DCSS data, before calling device_unregister().

Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/block/dcssblk.c