block: remove deadlock in disk_clear_events
authorDerek Basehore <dbasehore@chromium.org>
Tue, 18 Dec 2012 20:27:18 +0000 (12:27 -0800)
committerJens Axboe <axboe@kernel.dk>
Wed, 19 Dec 2012 19:36:05 +0000 (20:36 +0100)
commitaea24a8bbc81c8b404e4e293fb37aefaf388d35d
treefc12abcaacf7c5af4c0557d68da3fad9e5879906
parent74779e22261172ea728b989310f6ecc991b57d62
block: remove deadlock in disk_clear_events

In disk_clear_events, do not put work on system_nrt_freezable_wq.
Instead, put it on system_nrt_wq.

There is a race between probing a usb and suspending the device.  Since
probing a usb calls disk_clear_events, which puts work on a frozen
workqueue, probing cannot finish after the workqueue is frozen.  However,
suspending cannot finish until the usb probe is finished, so we get a
deadlock, causing the system to reboot.

The way to reproduce this bug is to wake up from suspend with a usb
storage device plugged in, or plugging in a usb storage device right
before suspend.  The window of time is on the order of time it takes to
probe the usb device.  As long as the workqueues are frozen before the
call to add_disk within sd_probe_async finishes, there will be a deadlock
(which calls blkdev_get, sd_open, check_disk_change, then
disk_clear_events).  This is not difficult to reproduce after figuring out
the timings.

[akpm@linux-foundation.org: fix up comment]
Signed-off-by: Derek Basehore <dbasehore@chromium.org>
Reviewed-by: Mandeep Singh Baines <msb@chromium.org>
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/genhd.c