bcache: acquire bch_register_lock later in cached_dev_detach_finish()
authorColy Li <colyli@suse.de>
Fri, 28 Jun 2019 11:59:47 +0000 (19:59 +0800)
committerJens Axboe <axboe@kernel.dk>
Fri, 28 Jun 2019 13:39:16 +0000 (07:39 -0600)
Now there is variable bcache_is_reboot to prevent device register or
unregister during reboot, it is unncessary to still hold mutex lock
bch_register_lock before stopping writeback_rate_update kworker and
writeback kthread. And if the stopping kworker or kthread holding
bch_register_lock inside their routine (we used to have such problem
in writeback thread, thanks to Junhui Wang fixed it), it is very easy
to introduce deadlock during reboot/shutdown procedure.

Therefore in this patch, the location to acquire bch_register_lock is
moved to the location before calling calc_cached_dev_sectors(). Which
is later then original location in cached_dev_detach_finish().

Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/md/bcache/super.c

index a88238ad5da15a37c714b4f932eb11ae769542b8..40d857e690f948cc9e5272248686923bdf28ec60 100644 (file)
@@ -1018,7 +1018,6 @@ static void cached_dev_detach_finish(struct work_struct *w)
        BUG_ON(!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags));
        BUG_ON(refcount_read(&dc->count));
 
-       mutex_lock(&bch_register_lock);
 
        if (test_and_clear_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags))
                cancel_writeback_rate_update_dwork(dc);
@@ -1034,6 +1033,8 @@ static void cached_dev_detach_finish(struct work_struct *w)
        bch_write_bdev_super(dc, &cl);
        closure_sync(&cl);
 
+       mutex_lock(&bch_register_lock);
+
        calc_cached_dev_sectors(dc->disk.c);
        bcache_device_detach(&dc->disk);
        list_move(&dc->list, &uncached_devices);