summary refs log tree commit diff
path: root/block
diff options
context:
space:
mode:
authorYu Kuai <yukuai3@huawei.com>2022-05-13 10:35:06 +0800
committerJens Axboe <axboe@kernel.dk>2022-05-16 11:39:20 -0600
commit181490d5321806e537dc5386db5ea640b826bf78 (patch)
tree863c51bbcc79a13cda5dbfda4106050ed2bf3a36 /block
parenta3e7689bfaae031177ebbb257d5a704b47236044 (diff)
downloadlinux-181490d5321806e537dc5386db5ea640b826bf78.tar.gz
block, bfq: protect 'bfqd->queued' by 'bfqd->lock'
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>
Diffstat (limited to 'block')
-rw-r--r--block/bfq-iosched.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index e47c75f1fa0f..62180dda6bf9 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -456,6 +456,8 @@ static struct bfq_io_cq *bfq_bic_lookup(struct request_queue *q)
  */
 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);
@@ -6892,8 +6894,8 @@ bfq_idle_slice_timer_body(struct bfq_data *bfqd, struct bfq_queue *bfqq)
 	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);
 }
 
 /*