diff options
author | Paolo Valente <paolo.valente@linaro.org> | 2019-01-29 06:06:31 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-01-31 14:50:23 -0500 |
commit | ac8b0cb415f3aa9162009d39624501d37031533b (patch) | |
tree | 7535aac3227f576c0625be34b15d1bbcedeb9d31 /block/bfq-iosched.c | |
parent | 05c2f5c30b3ca2346a5bb7c74b0c9515d8f4fbd2 (diff) |
block, bfq: do not plug I/O of in-service queue when harmful
If the in-service bfq_queue is sync and remains temporarily idle, then
I/O dispatching (from other queues) may be plugged. It may be dome for
two reasons: either to boost throughput, or to preserve the bandwidth
share of the in-service queue. In the first case, if the I/O of the
in-service queue, when it finally arrives, consists only of one small
I/O request, then it makes sense to plug even the I/O of the in-service
queue. In fact, serving such a small request immediately is likely to
lower throughput instead of boosting it, whereas waiting a little bit is
likely to let that request grow, thanks to request merging, and become
more profitable in terms of throughput (this is likely to happen exactly
because the I/O of the queue has been detected to boost throughput).
On the opposite end, if I/O dispatching is being plugged only to
preserve the bandwidth of the in-service queue, then it would be better
not to plug also the I/O of the in-service queue, because such a
plugging is likely to cause only loss of bandwidth for the queue.
Unfortunately, no distinction is made between the two cases, and the I/O
of the in-service queue is always plugged in case just a small I/O
request arrives. This commit draws this missing distinction and does not
perform harmful plugging.
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/bfq-iosched.c')
-rw-r--r-- | block/bfq-iosched.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 2756f4b1432b..a6fe60114ade 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c | |||
@@ -4599,28 +4599,31 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, | |||
4599 | bool budget_timeout = bfq_bfqq_budget_timeout(bfqq); | 4599 | bool budget_timeout = bfq_bfqq_budget_timeout(bfqq); |
4600 | 4600 | ||
4601 | /* | 4601 | /* |
4602 | * There is just this request queued: if the request | 4602 | * There is just this request queued: if |
4603 | * is small and the queue is not to be expired, then | 4603 | * - the request is small, and |
4604 | * just exit. | 4604 | * - we are idling to boost throughput, and |
4605 | * - the queue is not to be expired, | ||
4606 | * then just exit. | ||
4605 | * | 4607 | * |
4606 | * In this way, if the device is being idled to wait | 4608 | * In this way, if the device is being idled to wait |
4607 | * for a new request from the in-service queue, we | 4609 | * for a new request from the in-service queue, we |
4608 | * avoid unplugging the device and committing the | 4610 | * avoid unplugging the device and committing the |
4609 | * device to serve just a small request. On the | 4611 | * device to serve just a small request. In contrast |
4610 | * contrary, we wait for the block layer to decide | 4612 | * we wait for the block layer to decide when to |
4611 | * when to unplug the device: hopefully, new requests | 4613 | * unplug the device: hopefully, new requests will be |
4612 | * will be merged to this one quickly, then the device | 4614 | * merged to this one quickly, then the device will be |
4613 | * will be unplugged and larger requests will be | 4615 | * unplugged and larger requests will be dispatched. |
4614 | * dispatched. | ||
4615 | */ | 4616 | */ |
4616 | if (small_req && !budget_timeout) | 4617 | if (small_req && idling_boosts_thr_without_issues(bfqd, bfqq) && |
4618 | !budget_timeout) | ||
4617 | return; | 4619 | return; |
4618 | 4620 | ||
4619 | /* | 4621 | /* |
4620 | * A large enough request arrived, or the queue is to | 4622 | * A large enough request arrived, or idling is being |
4621 | * be expired: in both cases disk idling is to be | 4623 | * performed to preserve service guarantees, or |
4622 | * stopped, so clear wait_request flag and reset | 4624 | * finally the queue is to be expired: in all these |
4623 | * timer. | 4625 | * cases disk idling is to be stopped, so clear |
4626 | * wait_request flag and reset timer. | ||
4624 | */ | 4627 | */ |
4625 | bfq_clear_bfqq_wait_request(bfqq); | 4628 | bfq_clear_bfqq_wait_request(bfqq); |
4626 | hrtimer_try_to_cancel(&bfqd->idle_slice_timer); | 4629 | hrtimer_try_to_cancel(&bfqd->idle_slice_timer); |