diff options
| author | Davide Sapienza <sapienza.dav@gmail.com> | 2018-05-31 10:45:08 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2018-05-31 10:54:41 -0400 |
| commit | f6c3ca0e58446e8de6c6f1a2a73f037fb900c372 (patch) | |
| tree | 4bb57aa40714ad8cdeff7eebe0ecd26a08d13662 /block | |
| parent | d450542e3ce0efd030316b7846cc7231300b2bc9 (diff) | |
block, bfq: prevent soft_rt_next_start from being stuck at infinity
BFQ can deem a bfq_queue as soft real-time only if the queue
- periodically becomes completely idle, i.e., empty and with
no still-outstanding I/O request;
- after becoming idle, gets new I/O only after a special reference
time soft_rt_next_start.
In this respect, after commit "block, bfq: consider also past I/O in
soft real-time detection", the value of soft_rt_next_start can never
decrease. This causes a problem with the following special updating
case for soft_rt_next_start: to prevent queues that are not completely
idle to be wrongly detected as soft real-time (when they become
non-empty again), soft_rt_next_start is temporarily set to infinity
for empty queues with still outstanding I/O requests. But, if such an
update is actually performed, then, because of the above commit,
soft_rt_next_start will be stuck at infinity forever, and the queue
will have no more chance to be considered soft real-time.
On slow systems, this problem does cause actual soft real-time
applications to be occasionally not detected as such.
This commit addresses this issue by eliminating the pushing of
soft_rt_next_start to infinity, and by changing the way non-empty
queues are prevented from being wrongly detected as soft
real-time. Simply, a queue that becomes non-empty again can now be
detected as soft real-time only if it has no outstanding I/O request.
Signed-off-by: Davide Sapienza <sapienza.dav@gmail.com>
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
| -rw-r--r-- | block/bfq-iosched.c | 29 |
1 files changed, 2 insertions, 27 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 128b3be49463..495b9ddb3355 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c | |||
| @@ -1363,15 +1363,6 @@ static bool bfq_bfqq_update_budg_for_activation(struct bfq_data *bfqd, | |||
| 1363 | } | 1363 | } |
| 1364 | 1364 | ||
| 1365 | /* | 1365 | /* |
| 1366 | * Return the farthest future time instant according to jiffies | ||
| 1367 | * macros. | ||
| 1368 | */ | ||
| 1369 | static unsigned long bfq_greatest_from_now(void) | ||
| 1370 | { | ||
| 1371 | return jiffies + MAX_JIFFY_OFFSET; | ||
| 1372 | } | ||
| 1373 | |||
| 1374 | /* | ||
| 1375 | * Return the farthest past time instant according to jiffies | 1366 | * Return the farthest past time instant according to jiffies |
| 1376 | * macros. | 1367 | * macros. |
| 1377 | */ | 1368 | */ |
| @@ -1515,7 +1506,8 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd, | |||
| 1515 | in_burst = bfq_bfqq_in_large_burst(bfqq); | 1506 | in_burst = bfq_bfqq_in_large_burst(bfqq); |
| 1516 | soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && | 1507 | soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && |
| 1517 | !in_burst && | 1508 | !in_burst && |
| 1518 | time_is_before_jiffies(bfqq->soft_rt_next_start); | 1509 | time_is_before_jiffies(bfqq->soft_rt_next_start) && |
| 1510 | bfqq->dispatched == 0; | ||
| 1519 | *interactive = !in_burst && idle_for_long_time; | 1511 | *interactive = !in_burst && idle_for_long_time; |
| 1520 | wr_or_deserves_wr = bfqd->low_latency && | 1512 | wr_or_deserves_wr = bfqd->low_latency && |
| 1521 | (bfqq->wr_coeff > 1 || | 1513 | (bfqq->wr_coeff > 1 || |
| @@ -3222,23 +3214,6 @@ void bfq_bfqq_expire(struct bfq_data *bfqd, | |||
| 3222 | bfq_bfqq_softrt_next_start(bfqd, bfqq); | 3214 | bfq_bfqq_softrt_next_start(bfqd, bfqq); |
| 3223 | else { | 3215 | else { |
| 3224 | /* | 3216 | /* |
| 3225 | * The application is still waiting for the | ||
| 3226 | * completion of one or more requests: | ||
| 3227 | * prevent it from possibly being incorrectly | ||
| 3228 | * deemed as soft real-time by setting its | ||
| 3229 | * soft_rt_next_start to infinity. In fact, | ||
| 3230 | * without this assignment, the application | ||
| 3231 | * would be incorrectly deemed as soft | ||
| 3232 | * real-time if: | ||
| 3233 | * 1) it issued a new request before the | ||
| 3234 | * completion of all its in-flight | ||
| 3235 | * requests, and | ||
| 3236 | * 2) at that time, its soft_rt_next_start | ||
| 3237 | * happened to be in the past. | ||
| 3238 | */ | ||
| 3239 | bfqq->soft_rt_next_start = | ||
| 3240 | bfq_greatest_from_now(); | ||
| 3241 | /* | ||
| 3242 | * Schedule an update of soft_rt_next_start to when | 3217 | * Schedule an update of soft_rt_next_start to when |
| 3243 | * the task may be discovered to be isochronous. | 3218 | * the task may be discovered to be isochronous. |
| 3244 | */ | 3219 | */ |
