]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.34/block-bfq-fix-in-service-queue-check-for-queue-mergi.patch
Linux 4.19.34
[thirdparty/kernel/stable-queue.git] / releases / 4.19.34 / block-bfq-fix-in-service-queue-check-for-queue-mergi.patch
CommitLineData
ba172962
SL
1From 14a5279754eea932b7719e108e8c0835f6aa2a54 Mon Sep 17 00:00:00 2001
2From: Paolo Valente <paolo.valente@linaro.org>
3Date: Tue, 29 Jan 2019 12:06:38 +0100
4Subject: block, bfq: fix in-service-queue check for queue merging
5
6[ Upstream commit 058fdecc6de7cdecbf4c59b851e80eb2d6c5295f ]
7
8When a new I/O request arrives for a bfq_queue, say Q, bfq checks
9whether that request is close to
10(a) the head request of some other queue waiting to be served, or
11(b) the last request dispatched for the in-service queue (in case Q
12itself is not the in-service queue)
13
14If a queue, say Q2, is found for which the above condition holds, then
15bfq merges Q and Q2, to hopefully get a more sequential I/O in the
16resulting merged queue, and thus a possibly higher throughput.
17
18Case (b) is checked by comparing the new request for Q with the last
19request dispatched, assuming that the latter necessarily belonged to the
20in-service queue. Unfortunately, this assumption is no longer always
21correct, since commit d0edc2473be9 ("block, bfq: inject other-queue I/O
22into seeky idle queues on NCQ flash").
23
24When the assumption does not hold, queues that must not be merged may be
25merged, causing unexpected loss of control on per-queue service
26guarantees.
27
28This commit solves this problem by adding an extra field, which stores
29the actual last request dispatched for the in-service queue, and by
30using this new field to correctly check case (b).
31
32Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
33Signed-off-by: Jens Axboe <axboe@kernel.dk>
34Signed-off-by: Sasha Levin <sashal@kernel.org>
35---
36 block/bfq-iosched.c | 5 ++++-
37 block/bfq-iosched.h | 3 +++
38 2 files changed, 7 insertions(+), 1 deletion(-)
39
40diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
41index 653100fb719e..c5e2c5a01182 100644
42--- a/block/bfq-iosched.c
43+++ b/block/bfq-iosched.c
44@@ -2215,7 +2215,8 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
45
46 if (in_service_bfqq && in_service_bfqq != bfqq &&
47 likely(in_service_bfqq != &bfqd->oom_bfqq) &&
48- bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) &&
49+ bfq_rq_close_to_sector(io_struct, request,
50+ bfqd->in_serv_last_pos) &&
51 bfqq->entity.parent == in_service_bfqq->entity.parent &&
52 bfq_may_be_close_cooperator(bfqq, in_service_bfqq)) {
53 new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq);
54@@ -2755,6 +2756,8 @@ update_rate_and_reset:
55 bfq_update_rate_reset(bfqd, rq);
56 update_last_values:
57 bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
58+ if (RQ_BFQQ(rq) == bfqd->in_service_queue)
59+ bfqd->in_serv_last_pos = bfqd->last_position;
60 bfqd->last_dispatch = now_ns;
61 }
62
63diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
64index a8a2e5aca4d4..d5e9e60cb1a5 100644
65--- a/block/bfq-iosched.h
66+++ b/block/bfq-iosched.h
67@@ -469,6 +469,9 @@ struct bfq_data {
68 /* on-disk position of the last served request */
69 sector_t last_position;
70
71+ /* position of the last served request for the in-service queue */
72+ sector_t in_serv_last_pos;
73+
74 /* time of last request completion (ns) */
75 u64 last_completion;
76
77--
782.19.1
79