Commit e27ff551 authored by Yu Kuai's avatar Yu Kuai Committed by Yongqiang Liu
Browse files

block, bfq: make bfq_has_work() more accurate

mainline inclusion
from mainline-v5.19-rc1
commit ddc25c86
category: bugfix
bugzilla: 186769, https://gitee.com/openeuler/kernel/issues/I5FYJY


CVE: NA

--------------------------------

bfq_has_work() is using busy_queues currently, which is not accurate
because bfq_queue is busy doesn't represent that it has requests. Since
bfqd aready has a counter 'queued' to record how many requests are in
bfq, use it instead of busy_queues.

Noted that bfq_has_work() can be called with 'bfqd->lock' held, thus the
lock can't be held in bfq_has_work() to protect 'bfqd->queued'.

Signed-off-by: default avatarYu Kuai <yukuai3@huawei.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20220513023507.2625717-3-yukuai3@huawei.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
Reviewed-by: default avatarJason Yan <yanaijie@huawei.com>
Signed-off-by: default avatarYongqiang Liu <liuyongqiang13@huawei.com>
parent ea93e21d
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -1685,7 +1685,11 @@ static void bfq_add_request(struct request *rq)

	bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq));
	bfqq->queued[rq_is_sync(rq)]++;
	bfqd->queued++;
	/*
	 * Updating of 'bfqd->queued' is protected by 'bfqd->lock', however, it
	 * may be read without holding the lock in bfq_has_work().
	 */
	WRITE_ONCE(bfqd->queued, bfqd->queued + 1);

	elv_rb_add(&bfqq->sort_list, rq);

@@ -1803,7 +1807,11 @@ static void bfq_remove_request(struct request_queue *q,
	if (rq->queuelist.prev != &rq->queuelist)
		list_del_init(&rq->queuelist);
	bfqq->queued[sync]--;
	bfqd->queued--;
	/*
	 * Updating of 'bfqd->queued' is protected by 'bfqd->lock', however, it
	 * may be read without holding the lock in bfq_has_work().
	 */
	WRITE_ONCE(bfqd->queued, bfqd->queued - 1);
	elv_rb_del(&bfqq->sort_list, rq);

	elv_rqhash_del(q, rq);
@@ -3989,11 +3997,11 @@ static bool bfq_has_work(struct blk_mq_hw_ctx *hctx)
	struct bfq_data *bfqd = hctx->queue->elevator->elevator_data;

	/*
	 * Avoiding lock: a race on bfqd->busy_queues should cause at
	 * Avoiding lock: a race on bfqd->queued should cause at
	 * most a call to dispatch for nothing
	 */
	return !list_empty_careful(&bfqd->dispatch) ||
		bfqd->busy_queues > 0;
		READ_ONCE(bfqd->queued);
}

static struct request *__bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)