blob: b38bf34562c44274a20dd1fb7a953f7626b319d3 [file]
From 181490d5321806e537dc5386db5ea640b826bf78 Mon Sep 17 00:00:00 2001
From: Yu Kuai <yukuai3@huawei.com>
Date: Fri, 13 May 2022 10:35:06 +0800
Subject: block, bfq: protect 'bfqd->queued' by 'bfqd->lock'
From: Yu Kuai <yukuai3@huawei.com>
commit 181490d5321806e537dc5386db5ea640b826bf78 upstream.
If bfq_schedule_dispatch() is called from bfq_idle_slice_timer_body(),
then 'bfqd->queued' is read without holding 'bfqd->lock'. This is
wrong since it can be wrote concurrently.
Fix the problem by holding 'bfqd->lock' in such case.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Link: https://lore.kernel.org/r/20220513023507.2625717-2-yukuai3@huawei.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Cc: Khazhy Kumykov <khazhy@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
block/bfq-iosched.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -421,6 +421,8 @@ static struct bfq_io_cq *bfq_bic_lookup(
*/
void bfq_schedule_dispatch(struct bfq_data *bfqd)
{
+ lockdep_assert_held(&bfqd->lock);
+
if (bfqd->queued != 0) {
bfq_log(bfqd, "schedule dispatch");
blk_mq_run_hw_queues(bfqd->queue, true);
@@ -6269,8 +6271,8 @@ bfq_idle_slice_timer_body(struct bfq_dat
bfq_bfqq_expire(bfqd, bfqq, true, reason);
schedule_dispatch:
- spin_unlock_irqrestore(&bfqd->lock, flags);
bfq_schedule_dispatch(bfqd);
+ spin_unlock_irqrestore(&bfqd->lock, flags);
}
/*