diff options
author | Paolo Valente <paolo.valente@linaro.org> | 2019-01-29 06:06:25 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-01-31 14:50:22 -0500 |
commit | 20cd32450bcbec37c6d881b84bdddd8ba047ab01 (patch) | |
tree | 24b89fc7bbb5c7b302c8a75d939e92400a3998b3 /block/bfq-iosched.c | |
parent | 22cb4e681523b35f1a0eba40c25ddc1b16898801 (diff) |
block, bfq: do not consider interactive queues in srt filtering
The speed at which a bfq_queue receives I/O is one of the parameters by
which bfq decides whether the queue is soft real-time (i.e., whether the
queue contains the I/O of a soft real-time application). In particular,
when a bfq_queue remains without outstanding I/O requests, bfq computes
the minimum time instant, named soft_rt_next_start, at which the next
request of the queue may arrive for the queue to be deemed as soft real
time.
Unfortunately this filtering may cause problems with a queue in
interactive weight raising. In fact, such a queue may be conveying the
I/O needed to load a soft real-time application. The latter will
actually exhibit a soft real-time I/O pattern after it finally starts
doing its job. But, if soft_rt_next_start is updated for an interactive
bfq_queue, and the queue has received a lot of service before remaining
with no outstanding request (likely to happen on a fast device), then
soft_rt_next_start is assigned such a high value that, for a very long
time, the queue is prevented from being possibly considered as soft real
time.
This commit removes the updating of soft_rt_next_start for bfq_queues in
interactive weight raising.
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 | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index cd307767a134..c7a4a15c7c19 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c | |||
@@ -3274,16 +3274,32 @@ void bfq_bfqq_expire(struct bfq_data *bfqd, | |||
3274 | * requests, then the request pattern is isochronous | 3274 | * requests, then the request pattern is isochronous |
3275 | * (see the comments on the function | 3275 | * (see the comments on the function |
3276 | * bfq_bfqq_softrt_next_start()). Thus we can compute | 3276 | * bfq_bfqq_softrt_next_start()). Thus we can compute |
3277 | * soft_rt_next_start. If, instead, the queue still | 3277 | * soft_rt_next_start. And we do it, unless bfqq is in |
3278 | * has outstanding requests, then we have to wait for | 3278 | * interactive weight raising. We do not do it in the |
3279 | * the completion of all the outstanding requests to | 3279 | * latter subcase, for the following reason. bfqq may |
3280 | * discover whether the request pattern is actually | 3280 | * be conveying the I/O needed to load a soft |
3281 | * isochronous. | 3281 | * real-time application. Such an application will |
3282 | * actually exhibit a soft real-time I/O pattern after | ||
3283 | * it finally starts doing its job. But, if | ||
3284 | * soft_rt_next_start is computed here for an | ||
3285 | * interactive bfqq, and bfqq had received a lot of | ||
3286 | * service before remaining with no outstanding | ||
3287 | * request (likely to happen on a fast device), then | ||
3288 | * soft_rt_next_start would be assigned such a high | ||
3289 | * value that, for a very long time, bfqq would be | ||
3290 | * prevented from being possibly considered as soft | ||
3291 | * real time. | ||
3292 | * | ||
3293 | * If, instead, the queue still has outstanding | ||
3294 | * requests, then we have to wait for the completion | ||
3295 | * of all the outstanding requests to discover whether | ||
3296 | * the request pattern is actually isochronous. | ||
3282 | */ | 3297 | */ |
3283 | if (bfqq->dispatched == 0) | 3298 | if (bfqq->dispatched == 0 && |
3299 | bfqq->wr_coeff != bfqd->bfq_wr_coeff) | ||
3284 | bfqq->soft_rt_next_start = | 3300 | bfqq->soft_rt_next_start = |
3285 | bfq_bfqq_softrt_next_start(bfqd, bfqq); | 3301 | bfq_bfqq_softrt_next_start(bfqd, bfqq); |
3286 | else { | 3302 | else if (bfqq->dispatched > 0) { |
3287 | /* | 3303 | /* |
3288 | * Schedule an update of soft_rt_next_start to when | 3304 | * Schedule an update of soft_rt_next_start to when |
3289 | * the task may be discovered to be isochronous. | 3305 | * the task may be discovered to be isochronous. |
@@ -4834,11 +4850,14 @@ static void bfq_completed_request(struct bfq_queue *bfqq, struct bfq_data *bfqd) | |||
4834 | * isochronous, and both requisites for this condition to hold | 4850 | * isochronous, and both requisites for this condition to hold |
4835 | * are now satisfied, then compute soft_rt_next_start (see the | 4851 | * are now satisfied, then compute soft_rt_next_start (see the |
4836 | * comments on the function bfq_bfqq_softrt_next_start()). We | 4852 | * comments on the function bfq_bfqq_softrt_next_start()). We |
4837 | * schedule this delayed check when bfqq expires, if it still | 4853 | * do not compute soft_rt_next_start if bfqq is in interactive |
4838 | * has in-flight requests. | 4854 | * weight raising (see the comments in bfq_bfqq_expire() for |
4855 | * an explanation). We schedule this delayed update when bfqq | ||
4856 | * expires, if it still has in-flight requests. | ||
4839 | */ | 4857 | */ |
4840 | if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && | 4858 | if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && |
4841 | RB_EMPTY_ROOT(&bfqq->sort_list)) | 4859 | RB_EMPTY_ROOT(&bfqq->sort_list) && |
4860 | bfqq->wr_coeff != bfqd->bfq_wr_coeff) | ||
4842 | bfqq->soft_rt_next_start = | 4861 | bfqq->soft_rt_next_start = |
4843 | bfq_bfqq_softrt_next_start(bfqd, bfqq); | 4862 | bfq_bfqq_softrt_next_start(bfqd, bfqq); |
4844 | 4863 | ||