diff options
author | Paolo Valente <paolo.valente@linaro.org> | 2017-07-03 04:00:10 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-07-03 18:50:00 -0400 |
commit | 431b17f9d5453533cba7d73e7e40428e4f90b35d (patch) | |
tree | e42cf25bcbfbc315f6b4fc3660dce0890cfdbbe2 /block/bfq-iosched.c | |
parent | 7a69f9c60b49699579f5bfb71f928cceba0afe1a (diff) |
block, bfq: don't change ioprio class for a bfq_queue on a service tree
On each deactivation or re-scheduling (after being served) of a
bfq_queue, BFQ invokes the function __bfq_entity_update_weight_prio(),
to perform pending updates of ioprio, weight and ioprio class for the
bfq_queue. BFQ also invokes this function on I/O-request dispatches,
to raise or lower weights more quickly when needed, thereby improving
latency. However, the entity representing the bfq_queue may be on the
active (sub)tree of a service tree when this happens, and, although
with a very low probability, the bfq_queue may happen to also have a
pending change of its ioprio class. If both conditions hold when
__bfq_entity_update_weight_prio() is invoked, then the entity moves to
a sort of hybrid state: the new service tree for the entity, as
returned by bfq_entity_service_tree(), differs from service tree on
which the entity still is. The functions that handle activations and
deactivations of entities do not cope with such a hybrid state (and
would need to become more complex to cope).
This commit addresses this issue by just making
__bfq_entity_update_weight_prio() not perform also a possible pending
change of ioprio class, when invoked on an I/O-request dispatch for a
bfq_queue. Such a change is thus postponed to when
__bfq_entity_update_weight_prio() is invoked on deactivation or
re-scheduling of the bfq_queue.
Reported-by: Marco Piazza <mpiazza@gmail.com>
Reported-by: Laurentiu Nicola <lnicola@dend.ro>
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
Tested-by: Marco Piazza <mpiazza@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/bfq-iosched.c')
-rw-r--r-- | block/bfq-iosched.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 12bbc6b8657d..60a6835265fc 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c | |||
@@ -3483,11 +3483,17 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) | |||
3483 | } | 3483 | } |
3484 | } | 3484 | } |
3485 | } | 3485 | } |
3486 | /* Update weight both if it must be raised and if it must be lowered */ | 3486 | /* |
3487 | * To improve latency (for this or other queues), immediately | ||
3488 | * update weight both if it must be raised and if it must be | ||
3489 | * lowered. Since, entity may be on some active tree here, and | ||
3490 | * might have a pending change of its ioprio class, invoke | ||
3491 | * next function with the last parameter unset (see the | ||
3492 | * comments on the function). | ||
3493 | */ | ||
3487 | if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1)) | 3494 | if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1)) |
3488 | __bfq_entity_update_weight_prio( | 3495 | __bfq_entity_update_weight_prio(bfq_entity_service_tree(entity), |
3489 | bfq_entity_service_tree(entity), | 3496 | entity, false); |
3490 | entity); | ||
3491 | } | 3497 | } |
3492 | 3498 | ||
3493 | /* | 3499 | /* |