blk-mq: fix potential io hang by wrong 'wake_batch'
authorYu Kuai <yukuai3@huawei.com>
Sat, 10 Jun 2023 02:30:43 +0000 (10:30 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Jul 2023 14:20:55 +0000 (16:20 +0200)
commit931bd6758bcc0f3d27d0492456798afae028e52f
treee8404c4dcabce4ada87dfba4b6905b0cf2ba92db
parentc2a0eb3b2017bd1ab8bc68f9296619036a3d06df
blk-mq: fix potential io hang by wrong 'wake_batch'

[ Upstream commit 4f1731df60f9033669f024d06ae26a6301260b55 ]

In __blk_mq_tag_busy/idle(), updating 'active_queues' and calculating
'wake_batch' is not atomic:

t1: t2:
_blk_mq_tag_busy blk_mq_tag_busy
inc active_queues
// assume 1->2
inc active_queues
// 2 -> 3
blk_mq_update_wake_batch
// calculate based on 3
blk_mq_update_wake_batch
/* calculate based on 2, while active_queues is actually 3. */

Fix this problem by protecting them wih 'tags->lock', this is not a hot
path, so performance should not be concerned. And now that all writers
are inside the lock, switch 'actives_queues' from atomic to unsigned
int.

Fixes: 180dccb0dba4 ("blk-mq: fix tag_get wait task can't be awakened")
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20230610023043.2559121-1-yukuai1@huaweicloud.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
block/blk-mq-debugfs.c
block/blk-mq-tag.c
block/blk-mq.h
include/linux/blk-mq.h