提交 576682fa 编写于 作者: P Paolo Valente 提交者: Jens Axboe

block, bfq: make reparent_leaf_entity actually work only on leaf entities

bfq_reparent_leaf_entity() reparents the input leaf entity (a leaf
entity represents just a bfq_queue in an entity tree). Yet, the input
entity is guaranteed to always be a leaf entity only in two-level
entity trees. In this respect, because of the error fixed by
commit 14afc593 ("block, bfq: fix overwrite of bfq_group pointer
in bfq_find_set_group()"), all (wrongly collapsed) entity trees happened
to actually have only two levels. After the latter commit, this does not
hold any longer.

This commit fixes this problem by modifying
bfq_reparent_leaf_entity(), so that it searches an active leaf entity
down the path that stems from the input entity. Such a leaf entity is
guaranteed to exist when bfq_reparent_leaf_entity() is invoked.

Tested-by: cki-project@redhat.com
Signed-off-by: NPaolo Valente <paolo.valente@linaro.org>
Signed-off-by: NJens Axboe <axboe@kernel.dk>
上级 c8997736
...@@ -815,39 +815,53 @@ static void bfq_flush_idle_tree(struct bfq_service_tree *st) ...@@ -815,39 +815,53 @@ static void bfq_flush_idle_tree(struct bfq_service_tree *st)
/** /**
* bfq_reparent_leaf_entity - move leaf entity to the root_group. * bfq_reparent_leaf_entity - move leaf entity to the root_group.
* @bfqd: the device data structure with the root group. * @bfqd: the device data structure with the root group.
* @entity: the entity to move. * @entity: the entity to move, if entity is a leaf; or the parent entity
* of an active leaf entity to move, if entity is not a leaf.
*/ */
static void bfq_reparent_leaf_entity(struct bfq_data *bfqd, static void bfq_reparent_leaf_entity(struct bfq_data *bfqd,
struct bfq_entity *entity) struct bfq_entity *entity,
int ioprio_class)
{ {
struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); struct bfq_queue *bfqq;
struct bfq_entity *child_entity = entity;
while (child_entity->my_sched_data) { /* leaf not reached yet */
struct bfq_sched_data *child_sd = child_entity->my_sched_data;
struct bfq_service_tree *child_st = child_sd->service_tree +
ioprio_class;
struct rb_root *child_active = &child_st->active;
child_entity = bfq_entity_of(rb_first(child_active));
if (!child_entity)
child_entity = child_sd->in_service_entity;
}
bfqq = bfq_entity_to_bfqq(child_entity);
bfq_bfqq_move(bfqd, bfqq, bfqd->root_group); bfq_bfqq_move(bfqd, bfqq, bfqd->root_group);
} }
/** /**
* bfq_reparent_active_entities - move to the root group all active * bfq_reparent_active_queues - move to the root group all active queues.
* entities.
* @bfqd: the device data structure with the root group. * @bfqd: the device data structure with the root group.
* @bfqg: the group to move from. * @bfqg: the group to move from.
* @st: the service tree with the entities. * @st: the service tree to start the search from.
*/ */
static void bfq_reparent_active_entities(struct bfq_data *bfqd, static void bfq_reparent_active_queues(struct bfq_data *bfqd,
struct bfq_group *bfqg, struct bfq_group *bfqg,
struct bfq_service_tree *st) struct bfq_service_tree *st,
int ioprio_class)
{ {
struct rb_root *active = &st->active; struct rb_root *active = &st->active;
struct bfq_entity *entity = NULL; struct bfq_entity *entity;
if (!RB_EMPTY_ROOT(&st->active))
entity = bfq_entity_of(rb_first(active));
for (; entity ; entity = bfq_entity_of(rb_first(active))) while ((entity = bfq_entity_of(rb_first(active))))
bfq_reparent_leaf_entity(bfqd, entity); bfq_reparent_leaf_entity(bfqd, entity, ioprio_class);
if (bfqg->sched_data.in_service_entity) if (bfqg->sched_data.in_service_entity)
bfq_reparent_leaf_entity(bfqd, bfq_reparent_leaf_entity(bfqd,
bfqg->sched_data.in_service_entity); bfqg->sched_data.in_service_entity,
ioprio_class);
} }
/** /**
...@@ -898,7 +912,7 @@ static void bfq_pd_offline(struct blkg_policy_data *pd) ...@@ -898,7 +912,7 @@ static void bfq_pd_offline(struct blkg_policy_data *pd)
* There is no need to put the sync queues, as the * There is no need to put the sync queues, as the
* scheduler has taken no reference. * scheduler has taken no reference.
*/ */
bfq_reparent_active_entities(bfqd, bfqg, st); bfq_reparent_active_queues(bfqd, bfqg, st, i);
} }
__bfq_deactivate_entity(entity, false); __bfq_deactivate_entity(entity, false);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册