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>
This commit is contained in:
parent
a3e7689bfa
commit
181490d532
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue