diff options
author | Yu Kuai <yukuai3@huawei.com> | 2023-06-10 10:30:43 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-07-19 16:35:09 +0200 |
commit | 3cace7e4ac7aed6eb80f29a5924e30d437b3b7d6 (patch) | |
tree | 27a6bf74cebb3f777d380a07bfc117578839f28e /include | |
parent | cef10b632e83e177d4bde64a51ff43b5920b038f (diff) | |
download | linux-stable-3cace7e4ac7aed6eb80f29a5924e30d437b3b7d6.tar.gz linux-stable-3cace7e4ac7aed6eb80f29a5924e30d437b3b7d6.tar.bz2 linux-stable-3cace7e4ac7aed6eb80f29a5924e30d437b3b7d6.zip |
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>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/blk-mq.h | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 06caacd77ed6..710d12247264 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -746,8 +746,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q, struct blk_mq_tags { unsigned int nr_tags; unsigned int nr_reserved_tags; - - atomic_t active_queues; + unsigned int active_queues; struct sbitmap_queue bitmap_tags; struct sbitmap_queue breserved_tags; |