summaryrefslogtreecommitdiffstats
path: root/block/bfq-iosched.c
diff options
context:
space:
mode:
authorPaolo Valente <paolo.valente@linaro.org>2018-06-25 15:55:36 -0400
committerJens Axboe <axboe@kernel.dk>2018-07-09 11:07:52 -0400
commit9fae8dd59ff3d9c19570cbddf12e87d7bb66c8a2 (patch)
tree9a92db835315bb2cac28e4b3489b824a92e93157 /block/bfq-iosched.c
parent4420b095cc474759f6fbdb6351648c7ff9833a54 (diff)
block, bfq: fix service being wrongly set to zero in case of preemption
If - a bfq_queue Q preempts another queue, because one request of Q arrives in time, - but, after this preemption, Q is not the queue that is set in service, then Q->entity.service is set to 0 when Q is eventually set in service. But Q should have continued receiving service with its old budget (which is why preemption has occurred) and its old service. This commit addresses this issue by resetting service on queue real expiration. Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com> Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name> 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.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 4fd4f1996498..d579cc8e0db6 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -1382,18 +1382,30 @@ static bool bfq_bfqq_update_budg_for_activation(struct bfq_data *bfqd,
1382 * remain unchanged after such an expiration, and the 1382 * remain unchanged after such an expiration, and the
1383 * following statement therefore assigns to 1383 * following statement therefore assigns to
1384 * entity->budget the remaining budget on such an 1384 * entity->budget the remaining budget on such an
1385 * expiration. For clarity, entity->service is not 1385 * expiration.
1386 * updated on expiration in any case, and, in normal
1387 * operation, is reset only when bfqq is selected for
1388 * service (see bfq_get_next_queue).
1389 */ 1386 */
1390 entity->budget = min_t(unsigned long, 1387 entity->budget = min_t(unsigned long,
1391 bfq_bfqq_budget_left(bfqq), 1388 bfq_bfqq_budget_left(bfqq),
1392 bfqq->max_budget); 1389 bfqq->max_budget);
1393 1390
1391 /*
1392 * At this point, we have used entity->service to get
1393 * the budget left (needed for updating
1394 * entity->budget). Thus we finally can, and have to,
1395 * reset entity->service. The latter must be reset
1396 * because bfqq would otherwise be charged again for
1397 * the service it has received during its previous
1398 * service slot(s).
1399 */
1400 entity->service = 0;
1401
1394 return true; 1402 return true;
1395 } 1403 }
1396 1404
1405 /*
1406 * We can finally complete expiration, by setting service to 0.
1407 */
1408 entity->service = 0;
1397 entity->budget = max_t(unsigned long, bfqq->max_budget, 1409 entity->budget = max_t(unsigned long, bfqq->max_budget,
1398 bfq_serv_to_charge(bfqq->next_rq, bfqq)); 1410 bfq_serv_to_charge(bfqq->next_rq, bfqq));
1399 bfq_clear_bfqq_non_blocking_wait_rq(bfqq); 1411 bfq_clear_bfqq_non_blocking_wait_rq(bfqq);
@@ -3271,11 +3283,21 @@ void bfq_bfqq_expire(struct bfq_data *bfqd,
3271 ref = bfqq->ref; 3283 ref = bfqq->ref;
3272 __bfq_bfqq_expire(bfqd, bfqq); 3284 __bfq_bfqq_expire(bfqd, bfqq);
3273 3285
3286 if (ref == 1) /* bfqq is gone, no more actions on it */
3287 return;
3288
3274 /* mark bfqq as waiting a request only if a bic still points to it */ 3289 /* mark bfqq as waiting a request only if a bic still points to it */
3275 if (ref > 1 && !bfq_bfqq_busy(bfqq) && 3290 if (!bfq_bfqq_busy(bfqq) &&
3276 reason != BFQQE_BUDGET_TIMEOUT && 3291 reason != BFQQE_BUDGET_TIMEOUT &&
3277 reason != BFQQE_BUDGET_EXHAUSTED) 3292 reason != BFQQE_BUDGET_EXHAUSTED) {
3278 bfq_mark_bfqq_non_blocking_wait_rq(bfqq); 3293 bfq_mark_bfqq_non_blocking_wait_rq(bfqq);
3294 /*
3295 * Not setting service to 0, because, if the next rq
3296 * arrives in time, the queue will go on receiving
3297 * service with this same budget (as if it never expired)
3298 */
3299 } else
3300 entity->service = 0;
3279} 3301}
3280 3302
3281/* 3303/*