hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICTXO8 ------------------ When dm remove races with resume, DMF_SUSPENDED may be set by __dm_destroy(), without actually quiescing the request queue. Then in __dm_resume(), it will call dm_start_queue() for request-based devices. This results in blk_mq_unquiesce_queue() being invoked with q->quiesce_depth == 0, triggering: WARNING: at block/blk-mq.c blk_mq_unquiesce_queue+0xa0/0xc0 Call Trace: <TASK> dm_start_queue+0x16/0x20 [dm_mod] __dm_resume+0xac/0xb0 [dm_mod] dm_resume+0x12d/0x150 [dm_mod] do_resume+0x2c2/0x420 [dm_mod] dev_suspend+0x30/0x130 [dm_mod] ctl_ioctl+0x402/0x570 [dm_mod] dm_ctl_ioctl+0x23/0x30 [dm_mod] Fix it by adding check of DMF_FREEING in dm_resume(). If the mapped device is being destroyed, simply bail out early and skip resume. This prevents unbalanced start/stop of the queue during the remove/resume race. Fixes: e70feb8b3e68 ("blk-mq: support concurrent queue quiesce/unquiesce") Signed-off-by: Zheng Qixing <zhengqixing@huawei.com> --- drivers/md/dm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 766a0f5f6c46..6b16f64be9bd 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2874,6 +2874,9 @@ int dm_resume(struct mapped_device *md) if (!dm_suspended_md(md)) goto out; + if (test_bit(DMF_FREEING, &md->flags)) + goto out; + if (dm_suspended_internally_md(md)) { /* already internally suspended, wait for internal resume */ mutex_unlock(&md->suspend_lock); -- 2.39.2