block, bfq: avoid delayed merge of async queues
Since commit430a67f9d6
("block, bfq: merge bursts of newly-created queues"), BFQ may schedule a merge between a newly created sync bfq_queue, say Q2, and the last sync bfq_queue created, say Q1. To this goal, BFQ stores the address of Q1 in the field bic->stable_merge_bfqq of the bic associated with Q2. So, when the time for the possible merge arrives, BFQ knows which bfq_queue to merge Q2 with. In particular, BFQ checks for possible merges on request arrivals. Yet the same bic may also be associated with an async bfq_queue, say Q3. So, if a request for Q3 arrives, then the above check may happen to be executed while the bfq_queue at hand is Q3, instead of Q2. In this case, Q1 happens to be merged with an async bfq_queue. This is not only a conceptual mistake, because async queues are to be kept out of queue merging, but also a bug that leads to inconsistent states. This commits simply filters async queues out of delayed merges. Fixes:430a67f9d6
("block, bfq: merge bursts of newly-created queues") Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com> Signed-off-by: Paolo Valente <paolo.valente@linaro.org> Link: https://lore.kernel.org/r/20210619140948.98712-6-paolo.valente@linaro.org Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Родитель
7812472f97
Коммит
bd3664b362
|
@ -2718,7 +2718,13 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
||||||
* costly and complicated.
|
* costly and complicated.
|
||||||
*/
|
*/
|
||||||
if (unlikely(!bfqd->nonrot_with_queueing)) {
|
if (unlikely(!bfqd->nonrot_with_queueing)) {
|
||||||
if (bic->stable_merge_bfqq &&
|
/*
|
||||||
|
* Make sure also that bfqq is sync, because
|
||||||
|
* bic->stable_merge_bfqq may point to some queue (for
|
||||||
|
* stable merging) also if bic is associated with a
|
||||||
|
* sync queue, but this bfqq is async
|
||||||
|
*/
|
||||||
|
if (bfq_bfqq_sync(bfqq) && bic->stable_merge_bfqq &&
|
||||||
!bfq_bfqq_just_created(bfqq) &&
|
!bfq_bfqq_just_created(bfqq) &&
|
||||||
time_is_before_jiffies(bfqq->split_time +
|
time_is_before_jiffies(bfqq->split_time +
|
||||||
msecs_to_jiffies(bfq_late_stable_merging)) &&
|
msecs_to_jiffies(bfq_late_stable_merging)) &&
|
||||||
|
|
Загрузка…
Ссылка в новой задаче