162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Hierarchical Budget Worst-case Fair Weighted Fair Queueing
462306a36Sopenharmony_ci * (B-WF2Q+): hierarchical scheduling algorithm by which the BFQ I/O
562306a36Sopenharmony_ci * scheduler schedules generic entities. The latter can represent
662306a36Sopenharmony_ci * either single bfq queues (associated with processes) or groups of
762306a36Sopenharmony_ci * bfq queues (associated with cgroups).
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci#include "bfq-iosched.h"
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/**
1262306a36Sopenharmony_ci * bfq_gt - compare two timestamps.
1362306a36Sopenharmony_ci * @a: first ts.
1462306a36Sopenharmony_ci * @b: second ts.
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci * Return @a > @b, dealing with wrapping correctly.
1762306a36Sopenharmony_ci */
1862306a36Sopenharmony_cistatic int bfq_gt(u64 a, u64 b)
1962306a36Sopenharmony_ci{
2062306a36Sopenharmony_ci	return (s64)(a - b) > 0;
2162306a36Sopenharmony_ci}
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistatic struct bfq_entity *bfq_root_active_entity(struct rb_root *tree)
2462306a36Sopenharmony_ci{
2562306a36Sopenharmony_ci	struct rb_node *node = tree->rb_node;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	return rb_entry(node, struct bfq_entity, rb_node);
2862306a36Sopenharmony_ci}
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistatic unsigned int bfq_class_idx(struct bfq_entity *entity)
3162306a36Sopenharmony_ci{
3262306a36Sopenharmony_ci	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	return bfqq ? bfqq->ioprio_class - 1 :
3562306a36Sopenharmony_ci		BFQ_DEFAULT_GRP_CLASS - 1;
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ciunsigned int bfq_tot_busy_queues(struct bfq_data *bfqd)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	return bfqd->busy_queues[0] + bfqd->busy_queues[1] +
4162306a36Sopenharmony_ci		bfqd->busy_queues[2];
4262306a36Sopenharmony_ci}
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistatic struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
4562306a36Sopenharmony_ci						 bool expiration);
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic bool bfq_update_parent_budget(struct bfq_entity *next_in_service);
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/**
5062306a36Sopenharmony_ci * bfq_update_next_in_service - update sd->next_in_service
5162306a36Sopenharmony_ci * @sd: sched_data for which to perform the update.
5262306a36Sopenharmony_ci * @new_entity: if not NULL, pointer to the entity whose activation,
5362306a36Sopenharmony_ci *		requeueing or repositioning triggered the invocation of
5462306a36Sopenharmony_ci *		this function.
5562306a36Sopenharmony_ci * @expiration: id true, this function is being invoked after the
5662306a36Sopenharmony_ci *             expiration of the in-service entity
5762306a36Sopenharmony_ci *
5862306a36Sopenharmony_ci * This function is called to update sd->next_in_service, which, in
5962306a36Sopenharmony_ci * its turn, may change as a consequence of the insertion or
6062306a36Sopenharmony_ci * extraction of an entity into/from one of the active trees of
6162306a36Sopenharmony_ci * sd. These insertions/extractions occur as a consequence of
6262306a36Sopenharmony_ci * activations/deactivations of entities, with some activations being
6362306a36Sopenharmony_ci * 'true' activations, and other activations being requeueings (i.e.,
6462306a36Sopenharmony_ci * implementing the second, requeueing phase of the mechanism used to
6562306a36Sopenharmony_ci * reposition an entity in its active tree; see comments on
6662306a36Sopenharmony_ci * __bfq_activate_entity and __bfq_requeue_entity for details). In
6762306a36Sopenharmony_ci * both the last two activation sub-cases, new_entity points to the
6862306a36Sopenharmony_ci * just activated or requeued entity.
6962306a36Sopenharmony_ci *
7062306a36Sopenharmony_ci * Returns true if sd->next_in_service changes in such a way that
7162306a36Sopenharmony_ci * entity->parent may become the next_in_service for its parent
7262306a36Sopenharmony_ci * entity.
7362306a36Sopenharmony_ci */
7462306a36Sopenharmony_cistatic bool bfq_update_next_in_service(struct bfq_sched_data *sd,
7562306a36Sopenharmony_ci				       struct bfq_entity *new_entity,
7662306a36Sopenharmony_ci				       bool expiration)
7762306a36Sopenharmony_ci{
7862306a36Sopenharmony_ci	struct bfq_entity *next_in_service = sd->next_in_service;
7962306a36Sopenharmony_ci	bool parent_sched_may_change = false;
8062306a36Sopenharmony_ci	bool change_without_lookup = false;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	/*
8362306a36Sopenharmony_ci	 * If this update is triggered by the activation, requeueing
8462306a36Sopenharmony_ci	 * or repositioning of an entity that does not coincide with
8562306a36Sopenharmony_ci	 * sd->next_in_service, then a full lookup in the active tree
8662306a36Sopenharmony_ci	 * can be avoided. In fact, it is enough to check whether the
8762306a36Sopenharmony_ci	 * just-modified entity has the same priority as
8862306a36Sopenharmony_ci	 * sd->next_in_service, is eligible and has a lower virtual
8962306a36Sopenharmony_ci	 * finish time than sd->next_in_service. If this compound
9062306a36Sopenharmony_ci	 * condition holds, then the new entity becomes the new
9162306a36Sopenharmony_ci	 * next_in_service. Otherwise no change is needed.
9262306a36Sopenharmony_ci	 */
9362306a36Sopenharmony_ci	if (new_entity && new_entity != sd->next_in_service) {
9462306a36Sopenharmony_ci		/*
9562306a36Sopenharmony_ci		 * Flag used to decide whether to replace
9662306a36Sopenharmony_ci		 * sd->next_in_service with new_entity. Tentatively
9762306a36Sopenharmony_ci		 * set to true, and left as true if
9862306a36Sopenharmony_ci		 * sd->next_in_service is NULL.
9962306a36Sopenharmony_ci		 */
10062306a36Sopenharmony_ci		change_without_lookup = true;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci		/*
10362306a36Sopenharmony_ci		 * If there is already a next_in_service candidate
10462306a36Sopenharmony_ci		 * entity, then compare timestamps to decide whether
10562306a36Sopenharmony_ci		 * to replace sd->service_tree with new_entity.
10662306a36Sopenharmony_ci		 */
10762306a36Sopenharmony_ci		if (next_in_service) {
10862306a36Sopenharmony_ci			unsigned int new_entity_class_idx =
10962306a36Sopenharmony_ci				bfq_class_idx(new_entity);
11062306a36Sopenharmony_ci			struct bfq_service_tree *st =
11162306a36Sopenharmony_ci				sd->service_tree + new_entity_class_idx;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci			change_without_lookup =
11462306a36Sopenharmony_ci				(new_entity_class_idx ==
11562306a36Sopenharmony_ci				 bfq_class_idx(next_in_service)
11662306a36Sopenharmony_ci				 &&
11762306a36Sopenharmony_ci				 !bfq_gt(new_entity->start, st->vtime)
11862306a36Sopenharmony_ci				 &&
11962306a36Sopenharmony_ci				 bfq_gt(next_in_service->finish,
12062306a36Sopenharmony_ci					new_entity->finish));
12162306a36Sopenharmony_ci		}
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci		if (change_without_lookup)
12462306a36Sopenharmony_ci			next_in_service = new_entity;
12562306a36Sopenharmony_ci	}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	if (!change_without_lookup) /* lookup needed */
12862306a36Sopenharmony_ci		next_in_service = bfq_lookup_next_entity(sd, expiration);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	if (next_in_service) {
13162306a36Sopenharmony_ci		bool new_budget_triggers_change =
13262306a36Sopenharmony_ci			bfq_update_parent_budget(next_in_service);
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci		parent_sched_may_change = !sd->next_in_service ||
13562306a36Sopenharmony_ci			new_budget_triggers_change;
13662306a36Sopenharmony_ci	}
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	sd->next_in_service = next_in_service;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	return parent_sched_may_change;
14162306a36Sopenharmony_ci}
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#ifdef CONFIG_BFQ_GROUP_IOSCHED
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/*
14662306a36Sopenharmony_ci * Returns true if this budget changes may let next_in_service->parent
14762306a36Sopenharmony_ci * become the next_in_service entity for its parent entity.
14862306a36Sopenharmony_ci */
14962306a36Sopenharmony_cistatic bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
15062306a36Sopenharmony_ci{
15162306a36Sopenharmony_ci	struct bfq_entity *bfqg_entity;
15262306a36Sopenharmony_ci	struct bfq_group *bfqg;
15362306a36Sopenharmony_ci	struct bfq_sched_data *group_sd;
15462306a36Sopenharmony_ci	bool ret = false;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	group_sd = next_in_service->sched_data;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	bfqg = container_of(group_sd, struct bfq_group, sched_data);
15962306a36Sopenharmony_ci	/*
16062306a36Sopenharmony_ci	 * bfq_group's my_entity field is not NULL only if the group
16162306a36Sopenharmony_ci	 * is not the root group. We must not touch the root entity
16262306a36Sopenharmony_ci	 * as it must never become an in-service entity.
16362306a36Sopenharmony_ci	 */
16462306a36Sopenharmony_ci	bfqg_entity = bfqg->my_entity;
16562306a36Sopenharmony_ci	if (bfqg_entity) {
16662306a36Sopenharmony_ci		if (bfqg_entity->budget > next_in_service->budget)
16762306a36Sopenharmony_ci			ret = true;
16862306a36Sopenharmony_ci		bfqg_entity->budget = next_in_service->budget;
16962306a36Sopenharmony_ci	}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	return ret;
17262306a36Sopenharmony_ci}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci/*
17562306a36Sopenharmony_ci * This function tells whether entity stops being a candidate for next
17662306a36Sopenharmony_ci * service, according to the restrictive definition of the field
17762306a36Sopenharmony_ci * next_in_service. In particular, this function is invoked for an
17862306a36Sopenharmony_ci * entity that is about to be set in service.
17962306a36Sopenharmony_ci *
18062306a36Sopenharmony_ci * If entity is a queue, then the entity is no longer a candidate for
18162306a36Sopenharmony_ci * next service according to the that definition, because entity is
18262306a36Sopenharmony_ci * about to become the in-service queue. This function then returns
18362306a36Sopenharmony_ci * true if entity is a queue.
18462306a36Sopenharmony_ci *
18562306a36Sopenharmony_ci * In contrast, entity could still be a candidate for next service if
18662306a36Sopenharmony_ci * it is not a queue, and has more than one active child. In fact,
18762306a36Sopenharmony_ci * even if one of its children is about to be set in service, other
18862306a36Sopenharmony_ci * active children may still be the next to serve, for the parent
18962306a36Sopenharmony_ci * entity, even according to the above definition. As a consequence, a
19062306a36Sopenharmony_ci * non-queue entity is not a candidate for next-service only if it has
19162306a36Sopenharmony_ci * only one active child. And only if this condition holds, then this
19262306a36Sopenharmony_ci * function returns true for a non-queue entity.
19362306a36Sopenharmony_ci */
19462306a36Sopenharmony_cistatic bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
19562306a36Sopenharmony_ci{
19662306a36Sopenharmony_ci	struct bfq_group *bfqg;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	if (bfq_entity_to_bfqq(entity))
19962306a36Sopenharmony_ci		return true;
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	bfqg = container_of(entity, struct bfq_group, entity);
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	/*
20462306a36Sopenharmony_ci	 * The field active_entities does not always contain the
20562306a36Sopenharmony_ci	 * actual number of active children entities: it happens to
20662306a36Sopenharmony_ci	 * not account for the in-service entity in case the latter is
20762306a36Sopenharmony_ci	 * removed from its active tree (which may get done after
20862306a36Sopenharmony_ci	 * invoking the function bfq_no_longer_next_in_service in
20962306a36Sopenharmony_ci	 * bfq_get_next_queue). Fortunately, here, i.e., while
21062306a36Sopenharmony_ci	 * bfq_no_longer_next_in_service is not yet completed in
21162306a36Sopenharmony_ci	 * bfq_get_next_queue, bfq_active_extract has not yet been
21262306a36Sopenharmony_ci	 * invoked, and thus active_entities still coincides with the
21362306a36Sopenharmony_ci	 * actual number of active entities.
21462306a36Sopenharmony_ci	 */
21562306a36Sopenharmony_ci	if (bfqg->active_entities == 1)
21662306a36Sopenharmony_ci		return true;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	return false;
21962306a36Sopenharmony_ci}
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_cistatic void bfq_inc_active_entities(struct bfq_entity *entity)
22262306a36Sopenharmony_ci{
22362306a36Sopenharmony_ci	struct bfq_sched_data *sd = entity->sched_data;
22462306a36Sopenharmony_ci	struct bfq_group *bfqg = container_of(sd, struct bfq_group, sched_data);
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	if (bfqg != bfqg->bfqd->root_group)
22762306a36Sopenharmony_ci		bfqg->active_entities++;
22862306a36Sopenharmony_ci}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_cistatic void bfq_dec_active_entities(struct bfq_entity *entity)
23162306a36Sopenharmony_ci{
23262306a36Sopenharmony_ci	struct bfq_sched_data *sd = entity->sched_data;
23362306a36Sopenharmony_ci	struct bfq_group *bfqg = container_of(sd, struct bfq_group, sched_data);
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	if (bfqg != bfqg->bfqd->root_group)
23662306a36Sopenharmony_ci		bfqg->active_entities--;
23762306a36Sopenharmony_ci}
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci#else /* CONFIG_BFQ_GROUP_IOSCHED */
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_cistatic bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
24262306a36Sopenharmony_ci{
24362306a36Sopenharmony_ci	return false;
24462306a36Sopenharmony_ci}
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_cistatic bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
24762306a36Sopenharmony_ci{
24862306a36Sopenharmony_ci	return true;
24962306a36Sopenharmony_ci}
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cistatic void bfq_inc_active_entities(struct bfq_entity *entity)
25262306a36Sopenharmony_ci{
25362306a36Sopenharmony_ci}
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_cistatic void bfq_dec_active_entities(struct bfq_entity *entity)
25662306a36Sopenharmony_ci{
25762306a36Sopenharmony_ci}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci#endif /* CONFIG_BFQ_GROUP_IOSCHED */
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci/*
26262306a36Sopenharmony_ci * Shift for timestamp calculations.  This actually limits the maximum
26362306a36Sopenharmony_ci * service allowed in one timestamp delta (small shift values increase it),
26462306a36Sopenharmony_ci * the maximum total weight that can be used for the queues in the system
26562306a36Sopenharmony_ci * (big shift values increase it), and the period of virtual time
26662306a36Sopenharmony_ci * wraparounds.
26762306a36Sopenharmony_ci */
26862306a36Sopenharmony_ci#define WFQ_SERVICE_SHIFT	22
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_cistruct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity)
27162306a36Sopenharmony_ci{
27262306a36Sopenharmony_ci	struct bfq_queue *bfqq = NULL;
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	if (!entity->my_sched_data)
27562306a36Sopenharmony_ci		bfqq = container_of(entity, struct bfq_queue, entity);
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	return bfqq;
27862306a36Sopenharmony_ci}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci/**
28262306a36Sopenharmony_ci * bfq_delta - map service into the virtual time domain.
28362306a36Sopenharmony_ci * @service: amount of service.
28462306a36Sopenharmony_ci * @weight: scale factor (weight of an entity or weight sum).
28562306a36Sopenharmony_ci */
28662306a36Sopenharmony_cistatic u64 bfq_delta(unsigned long service, unsigned long weight)
28762306a36Sopenharmony_ci{
28862306a36Sopenharmony_ci	return div64_ul((u64)service << WFQ_SERVICE_SHIFT, weight);
28962306a36Sopenharmony_ci}
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci/**
29262306a36Sopenharmony_ci * bfq_calc_finish - assign the finish time to an entity.
29362306a36Sopenharmony_ci * @entity: the entity to act upon.
29462306a36Sopenharmony_ci * @service: the service to be charged to the entity.
29562306a36Sopenharmony_ci */
29662306a36Sopenharmony_cistatic void bfq_calc_finish(struct bfq_entity *entity, unsigned long service)
29762306a36Sopenharmony_ci{
29862306a36Sopenharmony_ci	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	entity->finish = entity->start +
30162306a36Sopenharmony_ci		bfq_delta(service, entity->weight);
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	if (bfqq) {
30462306a36Sopenharmony_ci		bfq_log_bfqq(bfqq->bfqd, bfqq,
30562306a36Sopenharmony_ci			"calc_finish: serv %lu, w %d",
30662306a36Sopenharmony_ci			service, entity->weight);
30762306a36Sopenharmony_ci		bfq_log_bfqq(bfqq->bfqd, bfqq,
30862306a36Sopenharmony_ci			"calc_finish: start %llu, finish %llu, delta %llu",
30962306a36Sopenharmony_ci			entity->start, entity->finish,
31062306a36Sopenharmony_ci			bfq_delta(service, entity->weight));
31162306a36Sopenharmony_ci	}
31262306a36Sopenharmony_ci}
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci/**
31562306a36Sopenharmony_ci * bfq_entity_of - get an entity from a node.
31662306a36Sopenharmony_ci * @node: the node field of the entity.
31762306a36Sopenharmony_ci *
31862306a36Sopenharmony_ci * Convert a node pointer to the relative entity.  This is used only
31962306a36Sopenharmony_ci * to simplify the logic of some functions and not as the generic
32062306a36Sopenharmony_ci * conversion mechanism because, e.g., in the tree walking functions,
32162306a36Sopenharmony_ci * the check for a %NULL value would be redundant.
32262306a36Sopenharmony_ci */
32362306a36Sopenharmony_cistruct bfq_entity *bfq_entity_of(struct rb_node *node)
32462306a36Sopenharmony_ci{
32562306a36Sopenharmony_ci	struct bfq_entity *entity = NULL;
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	if (node)
32862306a36Sopenharmony_ci		entity = rb_entry(node, struct bfq_entity, rb_node);
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci	return entity;
33162306a36Sopenharmony_ci}
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci/**
33462306a36Sopenharmony_ci * bfq_extract - remove an entity from a tree.
33562306a36Sopenharmony_ci * @root: the tree root.
33662306a36Sopenharmony_ci * @entity: the entity to remove.
33762306a36Sopenharmony_ci */
33862306a36Sopenharmony_cistatic void bfq_extract(struct rb_root *root, struct bfq_entity *entity)
33962306a36Sopenharmony_ci{
34062306a36Sopenharmony_ci	entity->tree = NULL;
34162306a36Sopenharmony_ci	rb_erase(&entity->rb_node, root);
34262306a36Sopenharmony_ci}
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci/**
34562306a36Sopenharmony_ci * bfq_idle_extract - extract an entity from the idle tree.
34662306a36Sopenharmony_ci * @st: the service tree of the owning @entity.
34762306a36Sopenharmony_ci * @entity: the entity being removed.
34862306a36Sopenharmony_ci */
34962306a36Sopenharmony_cistatic void bfq_idle_extract(struct bfq_service_tree *st,
35062306a36Sopenharmony_ci			     struct bfq_entity *entity)
35162306a36Sopenharmony_ci{
35262306a36Sopenharmony_ci	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
35362306a36Sopenharmony_ci	struct rb_node *next;
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	if (entity == st->first_idle) {
35662306a36Sopenharmony_ci		next = rb_next(&entity->rb_node);
35762306a36Sopenharmony_ci		st->first_idle = bfq_entity_of(next);
35862306a36Sopenharmony_ci	}
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	if (entity == st->last_idle) {
36162306a36Sopenharmony_ci		next = rb_prev(&entity->rb_node);
36262306a36Sopenharmony_ci		st->last_idle = bfq_entity_of(next);
36362306a36Sopenharmony_ci	}
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	bfq_extract(&st->idle, entity);
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	if (bfqq)
36862306a36Sopenharmony_ci		list_del(&bfqq->bfqq_list);
36962306a36Sopenharmony_ci}
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci/**
37262306a36Sopenharmony_ci * bfq_insert - generic tree insertion.
37362306a36Sopenharmony_ci * @root: tree root.
37462306a36Sopenharmony_ci * @entity: entity to insert.
37562306a36Sopenharmony_ci *
37662306a36Sopenharmony_ci * This is used for the idle and the active tree, since they are both
37762306a36Sopenharmony_ci * ordered by finish time.
37862306a36Sopenharmony_ci */
37962306a36Sopenharmony_cistatic void bfq_insert(struct rb_root *root, struct bfq_entity *entity)
38062306a36Sopenharmony_ci{
38162306a36Sopenharmony_ci	struct bfq_entity *entry;
38262306a36Sopenharmony_ci	struct rb_node **node = &root->rb_node;
38362306a36Sopenharmony_ci	struct rb_node *parent = NULL;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	while (*node) {
38662306a36Sopenharmony_ci		parent = *node;
38762306a36Sopenharmony_ci		entry = rb_entry(parent, struct bfq_entity, rb_node);
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci		if (bfq_gt(entry->finish, entity->finish))
39062306a36Sopenharmony_ci			node = &parent->rb_left;
39162306a36Sopenharmony_ci		else
39262306a36Sopenharmony_ci			node = &parent->rb_right;
39362306a36Sopenharmony_ci	}
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	rb_link_node(&entity->rb_node, parent, node);
39662306a36Sopenharmony_ci	rb_insert_color(&entity->rb_node, root);
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	entity->tree = root;
39962306a36Sopenharmony_ci}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci/**
40262306a36Sopenharmony_ci * bfq_update_min - update the min_start field of a entity.
40362306a36Sopenharmony_ci * @entity: the entity to update.
40462306a36Sopenharmony_ci * @node: one of its children.
40562306a36Sopenharmony_ci *
40662306a36Sopenharmony_ci * This function is called when @entity may store an invalid value for
40762306a36Sopenharmony_ci * min_start due to updates to the active tree.  The function  assumes
40862306a36Sopenharmony_ci * that the subtree rooted at @node (which may be its left or its right
40962306a36Sopenharmony_ci * child) has a valid min_start value.
41062306a36Sopenharmony_ci */
41162306a36Sopenharmony_cistatic void bfq_update_min(struct bfq_entity *entity, struct rb_node *node)
41262306a36Sopenharmony_ci{
41362306a36Sopenharmony_ci	struct bfq_entity *child;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	if (node) {
41662306a36Sopenharmony_ci		child = rb_entry(node, struct bfq_entity, rb_node);
41762306a36Sopenharmony_ci		if (bfq_gt(entity->min_start, child->min_start))
41862306a36Sopenharmony_ci			entity->min_start = child->min_start;
41962306a36Sopenharmony_ci	}
42062306a36Sopenharmony_ci}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci/**
42362306a36Sopenharmony_ci * bfq_update_active_node - recalculate min_start.
42462306a36Sopenharmony_ci * @node: the node to update.
42562306a36Sopenharmony_ci *
42662306a36Sopenharmony_ci * @node may have changed position or one of its children may have moved,
42762306a36Sopenharmony_ci * this function updates its min_start value.  The left and right subtrees
42862306a36Sopenharmony_ci * are assumed to hold a correct min_start value.
42962306a36Sopenharmony_ci */
43062306a36Sopenharmony_cistatic void bfq_update_active_node(struct rb_node *node)
43162306a36Sopenharmony_ci{
43262306a36Sopenharmony_ci	struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node);
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	entity->min_start = entity->start;
43562306a36Sopenharmony_ci	bfq_update_min(entity, node->rb_right);
43662306a36Sopenharmony_ci	bfq_update_min(entity, node->rb_left);
43762306a36Sopenharmony_ci}
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci/**
44062306a36Sopenharmony_ci * bfq_update_active_tree - update min_start for the whole active tree.
44162306a36Sopenharmony_ci * @node: the starting node.
44262306a36Sopenharmony_ci *
44362306a36Sopenharmony_ci * @node must be the deepest modified node after an update.  This function
44462306a36Sopenharmony_ci * updates its min_start using the values held by its children, assuming
44562306a36Sopenharmony_ci * that they did not change, and then updates all the nodes that may have
44662306a36Sopenharmony_ci * changed in the path to the root.  The only nodes that may have changed
44762306a36Sopenharmony_ci * are the ones in the path or their siblings.
44862306a36Sopenharmony_ci */
44962306a36Sopenharmony_cistatic void bfq_update_active_tree(struct rb_node *node)
45062306a36Sopenharmony_ci{
45162306a36Sopenharmony_ci	struct rb_node *parent;
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ciup:
45462306a36Sopenharmony_ci	bfq_update_active_node(node);
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci	parent = rb_parent(node);
45762306a36Sopenharmony_ci	if (!parent)
45862306a36Sopenharmony_ci		return;
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci	if (node == parent->rb_left && parent->rb_right)
46162306a36Sopenharmony_ci		bfq_update_active_node(parent->rb_right);
46262306a36Sopenharmony_ci	else if (parent->rb_left)
46362306a36Sopenharmony_ci		bfq_update_active_node(parent->rb_left);
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci	node = parent;
46662306a36Sopenharmony_ci	goto up;
46762306a36Sopenharmony_ci}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci/**
47062306a36Sopenharmony_ci * bfq_active_insert - insert an entity in the active tree of its
47162306a36Sopenharmony_ci *                     group/device.
47262306a36Sopenharmony_ci * @st: the service tree of the entity.
47362306a36Sopenharmony_ci * @entity: the entity being inserted.
47462306a36Sopenharmony_ci *
47562306a36Sopenharmony_ci * The active tree is ordered by finish time, but an extra key is kept
47662306a36Sopenharmony_ci * per each node, containing the minimum value for the start times of
47762306a36Sopenharmony_ci * its children (and the node itself), so it's possible to search for
47862306a36Sopenharmony_ci * the eligible node with the lowest finish time in logarithmic time.
47962306a36Sopenharmony_ci */
48062306a36Sopenharmony_cistatic void bfq_active_insert(struct bfq_service_tree *st,
48162306a36Sopenharmony_ci			      struct bfq_entity *entity)
48262306a36Sopenharmony_ci{
48362306a36Sopenharmony_ci	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
48462306a36Sopenharmony_ci	struct rb_node *node = &entity->rb_node;
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci	bfq_insert(&st->active, entity);
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci	if (node->rb_left)
48962306a36Sopenharmony_ci		node = node->rb_left;
49062306a36Sopenharmony_ci	else if (node->rb_right)
49162306a36Sopenharmony_ci		node = node->rb_right;
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci	bfq_update_active_tree(node);
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	if (bfqq)
49662306a36Sopenharmony_ci		list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list[bfqq->actuator_idx]);
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	bfq_inc_active_entities(entity);
49962306a36Sopenharmony_ci}
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci/**
50262306a36Sopenharmony_ci * bfq_ioprio_to_weight - calc a weight from an ioprio.
50362306a36Sopenharmony_ci * @ioprio: the ioprio value to convert.
50462306a36Sopenharmony_ci */
50562306a36Sopenharmony_ciunsigned short bfq_ioprio_to_weight(int ioprio)
50662306a36Sopenharmony_ci{
50762306a36Sopenharmony_ci	return (IOPRIO_NR_LEVELS - ioprio) * BFQ_WEIGHT_CONVERSION_COEFF;
50862306a36Sopenharmony_ci}
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci/**
51162306a36Sopenharmony_ci * bfq_weight_to_ioprio - calc an ioprio from a weight.
51262306a36Sopenharmony_ci * @weight: the weight value to convert.
51362306a36Sopenharmony_ci *
51462306a36Sopenharmony_ci * To preserve as much as possible the old only-ioprio user interface,
51562306a36Sopenharmony_ci * 0 is used as an escape ioprio value for weights (numerically) equal or
51662306a36Sopenharmony_ci * larger than IOPRIO_NR_LEVELS * BFQ_WEIGHT_CONVERSION_COEFF.
51762306a36Sopenharmony_ci */
51862306a36Sopenharmony_cistatic unsigned short bfq_weight_to_ioprio(int weight)
51962306a36Sopenharmony_ci{
52062306a36Sopenharmony_ci	return max_t(int, 0,
52162306a36Sopenharmony_ci		     IOPRIO_NR_LEVELS - weight / BFQ_WEIGHT_CONVERSION_COEFF);
52262306a36Sopenharmony_ci}
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_cistatic void bfq_get_entity(struct bfq_entity *entity)
52562306a36Sopenharmony_ci{
52662306a36Sopenharmony_ci	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	if (bfqq) {
52962306a36Sopenharmony_ci		bfqq->ref++;
53062306a36Sopenharmony_ci		bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d",
53162306a36Sopenharmony_ci			     bfqq, bfqq->ref);
53262306a36Sopenharmony_ci	}
53362306a36Sopenharmony_ci}
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci/**
53662306a36Sopenharmony_ci * bfq_find_deepest - find the deepest node that an extraction can modify.
53762306a36Sopenharmony_ci * @node: the node being removed.
53862306a36Sopenharmony_ci *
53962306a36Sopenharmony_ci * Do the first step of an extraction in an rb tree, looking for the
54062306a36Sopenharmony_ci * node that will replace @node, and returning the deepest node that
54162306a36Sopenharmony_ci * the following modifications to the tree can touch.  If @node is the
54262306a36Sopenharmony_ci * last node in the tree return %NULL.
54362306a36Sopenharmony_ci */
54462306a36Sopenharmony_cistatic struct rb_node *bfq_find_deepest(struct rb_node *node)
54562306a36Sopenharmony_ci{
54662306a36Sopenharmony_ci	struct rb_node *deepest;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	if (!node->rb_right && !node->rb_left)
54962306a36Sopenharmony_ci		deepest = rb_parent(node);
55062306a36Sopenharmony_ci	else if (!node->rb_right)
55162306a36Sopenharmony_ci		deepest = node->rb_left;
55262306a36Sopenharmony_ci	else if (!node->rb_left)
55362306a36Sopenharmony_ci		deepest = node->rb_right;
55462306a36Sopenharmony_ci	else {
55562306a36Sopenharmony_ci		deepest = rb_next(node);
55662306a36Sopenharmony_ci		if (deepest->rb_right)
55762306a36Sopenharmony_ci			deepest = deepest->rb_right;
55862306a36Sopenharmony_ci		else if (rb_parent(deepest) != node)
55962306a36Sopenharmony_ci			deepest = rb_parent(deepest);
56062306a36Sopenharmony_ci	}
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	return deepest;
56362306a36Sopenharmony_ci}
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci/**
56662306a36Sopenharmony_ci * bfq_active_extract - remove an entity from the active tree.
56762306a36Sopenharmony_ci * @st: the service_tree containing the tree.
56862306a36Sopenharmony_ci * @entity: the entity being removed.
56962306a36Sopenharmony_ci */
57062306a36Sopenharmony_cistatic void bfq_active_extract(struct bfq_service_tree *st,
57162306a36Sopenharmony_ci			       struct bfq_entity *entity)
57262306a36Sopenharmony_ci{
57362306a36Sopenharmony_ci	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
57462306a36Sopenharmony_ci	struct rb_node *node;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	node = bfq_find_deepest(&entity->rb_node);
57762306a36Sopenharmony_ci	bfq_extract(&st->active, entity);
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	if (node)
58062306a36Sopenharmony_ci		bfq_update_active_tree(node);
58162306a36Sopenharmony_ci	if (bfqq)
58262306a36Sopenharmony_ci		list_del(&bfqq->bfqq_list);
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	bfq_dec_active_entities(entity);
58562306a36Sopenharmony_ci}
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci/**
58862306a36Sopenharmony_ci * bfq_idle_insert - insert an entity into the idle tree.
58962306a36Sopenharmony_ci * @st: the service tree containing the tree.
59062306a36Sopenharmony_ci * @entity: the entity to insert.
59162306a36Sopenharmony_ci */
59262306a36Sopenharmony_cistatic void bfq_idle_insert(struct bfq_service_tree *st,
59362306a36Sopenharmony_ci			    struct bfq_entity *entity)
59462306a36Sopenharmony_ci{
59562306a36Sopenharmony_ci	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
59662306a36Sopenharmony_ci	struct bfq_entity *first_idle = st->first_idle;
59762306a36Sopenharmony_ci	struct bfq_entity *last_idle = st->last_idle;
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci	if (!first_idle || bfq_gt(first_idle->finish, entity->finish))
60062306a36Sopenharmony_ci		st->first_idle = entity;
60162306a36Sopenharmony_ci	if (!last_idle || bfq_gt(entity->finish, last_idle->finish))
60262306a36Sopenharmony_ci		st->last_idle = entity;
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	bfq_insert(&st->idle, entity);
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci	if (bfqq)
60762306a36Sopenharmony_ci		list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list);
60862306a36Sopenharmony_ci}
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci/**
61162306a36Sopenharmony_ci * bfq_forget_entity - do not consider entity any longer for scheduling
61262306a36Sopenharmony_ci * @st: the service tree.
61362306a36Sopenharmony_ci * @entity: the entity being removed.
61462306a36Sopenharmony_ci * @is_in_service: true if entity is currently the in-service entity.
61562306a36Sopenharmony_ci *
61662306a36Sopenharmony_ci * Forget everything about @entity. In addition, if entity represents
61762306a36Sopenharmony_ci * a queue, and the latter is not in service, then release the service
61862306a36Sopenharmony_ci * reference to the queue (the one taken through bfq_get_entity). In
61962306a36Sopenharmony_ci * fact, in this case, there is really no more service reference to
62062306a36Sopenharmony_ci * the queue, as the latter is also outside any service tree. If,
62162306a36Sopenharmony_ci * instead, the queue is in service, then __bfq_bfqd_reset_in_service
62262306a36Sopenharmony_ci * will take care of putting the reference when the queue finally
62362306a36Sopenharmony_ci * stops being served.
62462306a36Sopenharmony_ci */
62562306a36Sopenharmony_cistatic void bfq_forget_entity(struct bfq_service_tree *st,
62662306a36Sopenharmony_ci			      struct bfq_entity *entity,
62762306a36Sopenharmony_ci			      bool is_in_service)
62862306a36Sopenharmony_ci{
62962306a36Sopenharmony_ci	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	entity->on_st_or_in_serv = false;
63262306a36Sopenharmony_ci	st->wsum -= entity->weight;
63362306a36Sopenharmony_ci	if (bfqq && !is_in_service)
63462306a36Sopenharmony_ci		bfq_put_queue(bfqq);
63562306a36Sopenharmony_ci}
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci/**
63862306a36Sopenharmony_ci * bfq_put_idle_entity - release the idle tree ref of an entity.
63962306a36Sopenharmony_ci * @st: service tree for the entity.
64062306a36Sopenharmony_ci * @entity: the entity being released.
64162306a36Sopenharmony_ci */
64262306a36Sopenharmony_civoid bfq_put_idle_entity(struct bfq_service_tree *st, struct bfq_entity *entity)
64362306a36Sopenharmony_ci{
64462306a36Sopenharmony_ci	bfq_idle_extract(st, entity);
64562306a36Sopenharmony_ci	bfq_forget_entity(st, entity,
64662306a36Sopenharmony_ci			  entity == entity->sched_data->in_service_entity);
64762306a36Sopenharmony_ci}
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci/**
65062306a36Sopenharmony_ci * bfq_forget_idle - update the idle tree if necessary.
65162306a36Sopenharmony_ci * @st: the service tree to act upon.
65262306a36Sopenharmony_ci *
65362306a36Sopenharmony_ci * To preserve the global O(log N) complexity we only remove one entry here;
65462306a36Sopenharmony_ci * as the idle tree will not grow indefinitely this can be done safely.
65562306a36Sopenharmony_ci */
65662306a36Sopenharmony_cistatic void bfq_forget_idle(struct bfq_service_tree *st)
65762306a36Sopenharmony_ci{
65862306a36Sopenharmony_ci	struct bfq_entity *first_idle = st->first_idle;
65962306a36Sopenharmony_ci	struct bfq_entity *last_idle = st->last_idle;
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	if (RB_EMPTY_ROOT(&st->active) && last_idle &&
66262306a36Sopenharmony_ci	    !bfq_gt(last_idle->finish, st->vtime)) {
66362306a36Sopenharmony_ci		/*
66462306a36Sopenharmony_ci		 * Forget the whole idle tree, increasing the vtime past
66562306a36Sopenharmony_ci		 * the last finish time of idle entities.
66662306a36Sopenharmony_ci		 */
66762306a36Sopenharmony_ci		st->vtime = last_idle->finish;
66862306a36Sopenharmony_ci	}
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	if (first_idle && !bfq_gt(first_idle->finish, st->vtime))
67162306a36Sopenharmony_ci		bfq_put_idle_entity(st, first_idle);
67262306a36Sopenharmony_ci}
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_cistruct bfq_service_tree *bfq_entity_service_tree(struct bfq_entity *entity)
67562306a36Sopenharmony_ci{
67662306a36Sopenharmony_ci	struct bfq_sched_data *sched_data = entity->sched_data;
67762306a36Sopenharmony_ci	unsigned int idx = bfq_class_idx(entity);
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	return sched_data->service_tree + idx;
68062306a36Sopenharmony_ci}
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci/*
68362306a36Sopenharmony_ci * Update weight and priority of entity. If update_class_too is true,
68462306a36Sopenharmony_ci * then update the ioprio_class of entity too.
68562306a36Sopenharmony_ci *
68662306a36Sopenharmony_ci * The reason why the update of ioprio_class is controlled through the
68762306a36Sopenharmony_ci * last parameter is as follows. Changing the ioprio class of an
68862306a36Sopenharmony_ci * entity implies changing the destination service trees for that
68962306a36Sopenharmony_ci * entity. If such a change occurred when the entity is already on one
69062306a36Sopenharmony_ci * of the service trees for its previous class, then the state of the
69162306a36Sopenharmony_ci * entity would become more complex: none of the new possible service
69262306a36Sopenharmony_ci * trees for the entity, according to bfq_entity_service_tree(), would
69362306a36Sopenharmony_ci * match any of the possible service trees on which the entity
69462306a36Sopenharmony_ci * is. Complex operations involving these trees, such as entity
69562306a36Sopenharmony_ci * activations and deactivations, should take into account this
69662306a36Sopenharmony_ci * additional complexity.  To avoid this issue, this function is
69762306a36Sopenharmony_ci * invoked with update_class_too unset in the points in the code where
69862306a36Sopenharmony_ci * entity may happen to be on some tree.
69962306a36Sopenharmony_ci */
70062306a36Sopenharmony_cistruct bfq_service_tree *
70162306a36Sopenharmony_ci__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
70262306a36Sopenharmony_ci				struct bfq_entity *entity,
70362306a36Sopenharmony_ci				bool update_class_too)
70462306a36Sopenharmony_ci{
70562306a36Sopenharmony_ci	struct bfq_service_tree *new_st = old_st;
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci	if (entity->prio_changed) {
70862306a36Sopenharmony_ci		struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
70962306a36Sopenharmony_ci		unsigned int prev_weight, new_weight;
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci		/* Matches the smp_wmb() in bfq_group_set_weight. */
71262306a36Sopenharmony_ci		smp_rmb();
71362306a36Sopenharmony_ci		old_st->wsum -= entity->weight;
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci		if (entity->new_weight != entity->orig_weight) {
71662306a36Sopenharmony_ci			if (entity->new_weight < BFQ_MIN_WEIGHT ||
71762306a36Sopenharmony_ci			    entity->new_weight > BFQ_MAX_WEIGHT) {
71862306a36Sopenharmony_ci				pr_crit("update_weight_prio: new_weight %d\n",
71962306a36Sopenharmony_ci					entity->new_weight);
72062306a36Sopenharmony_ci				if (entity->new_weight < BFQ_MIN_WEIGHT)
72162306a36Sopenharmony_ci					entity->new_weight = BFQ_MIN_WEIGHT;
72262306a36Sopenharmony_ci				else
72362306a36Sopenharmony_ci					entity->new_weight = BFQ_MAX_WEIGHT;
72462306a36Sopenharmony_ci			}
72562306a36Sopenharmony_ci			entity->orig_weight = entity->new_weight;
72662306a36Sopenharmony_ci			if (bfqq)
72762306a36Sopenharmony_ci				bfqq->ioprio =
72862306a36Sopenharmony_ci				  bfq_weight_to_ioprio(entity->orig_weight);
72962306a36Sopenharmony_ci		}
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci		if (bfqq && update_class_too)
73262306a36Sopenharmony_ci			bfqq->ioprio_class = bfqq->new_ioprio_class;
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci		/*
73562306a36Sopenharmony_ci		 * Reset prio_changed only if the ioprio_class change
73662306a36Sopenharmony_ci		 * is not pending any longer.
73762306a36Sopenharmony_ci		 */
73862306a36Sopenharmony_ci		if (!bfqq || bfqq->ioprio_class == bfqq->new_ioprio_class)
73962306a36Sopenharmony_ci			entity->prio_changed = 0;
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci		/*
74262306a36Sopenharmony_ci		 * NOTE: here we may be changing the weight too early,
74362306a36Sopenharmony_ci		 * this will cause unfairness.  The correct approach
74462306a36Sopenharmony_ci		 * would have required additional complexity to defer
74562306a36Sopenharmony_ci		 * weight changes to the proper time instants (i.e.,
74662306a36Sopenharmony_ci		 * when entity->finish <= old_st->vtime).
74762306a36Sopenharmony_ci		 */
74862306a36Sopenharmony_ci		new_st = bfq_entity_service_tree(entity);
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci		prev_weight = entity->weight;
75162306a36Sopenharmony_ci		new_weight = entity->orig_weight *
75262306a36Sopenharmony_ci			     (bfqq ? bfqq->wr_coeff : 1);
75362306a36Sopenharmony_ci		/*
75462306a36Sopenharmony_ci		 * If the weight of the entity changes, and the entity is a
75562306a36Sopenharmony_ci		 * queue, remove the entity from its old weight counter (if
75662306a36Sopenharmony_ci		 * there is a counter associated with the entity).
75762306a36Sopenharmony_ci		 */
75862306a36Sopenharmony_ci		if (prev_weight != new_weight && bfqq)
75962306a36Sopenharmony_ci			bfq_weights_tree_remove(bfqq);
76062306a36Sopenharmony_ci		entity->weight = new_weight;
76162306a36Sopenharmony_ci		/*
76262306a36Sopenharmony_ci		 * Add the entity, if it is not a weight-raised queue,
76362306a36Sopenharmony_ci		 * to the counter associated with its new weight.
76462306a36Sopenharmony_ci		 */
76562306a36Sopenharmony_ci		if (prev_weight != new_weight && bfqq && bfqq->wr_coeff == 1)
76662306a36Sopenharmony_ci			bfq_weights_tree_add(bfqq);
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_ci		new_st->wsum += entity->weight;
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ci		if (new_st != old_st)
77162306a36Sopenharmony_ci			entity->start = new_st->vtime;
77262306a36Sopenharmony_ci	}
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci	return new_st;
77562306a36Sopenharmony_ci}
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci/**
77862306a36Sopenharmony_ci * bfq_bfqq_served - update the scheduler status after selection for
77962306a36Sopenharmony_ci *                   service.
78062306a36Sopenharmony_ci * @bfqq: the queue being served.
78162306a36Sopenharmony_ci * @served: bytes to transfer.
78262306a36Sopenharmony_ci *
78362306a36Sopenharmony_ci * NOTE: this can be optimized, as the timestamps of upper level entities
78462306a36Sopenharmony_ci * are synchronized every time a new bfqq is selected for service.  By now,
78562306a36Sopenharmony_ci * we keep it to better check consistency.
78662306a36Sopenharmony_ci */
78762306a36Sopenharmony_civoid bfq_bfqq_served(struct bfq_queue *bfqq, int served)
78862306a36Sopenharmony_ci{
78962306a36Sopenharmony_ci	struct bfq_entity *entity = &bfqq->entity;
79062306a36Sopenharmony_ci	struct bfq_service_tree *st;
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci	if (!bfqq->service_from_backlogged)
79362306a36Sopenharmony_ci		bfqq->first_IO_time = jiffies;
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci	if (bfqq->wr_coeff > 1)
79662306a36Sopenharmony_ci		bfqq->service_from_wr += served;
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ci	bfqq->service_from_backlogged += served;
79962306a36Sopenharmony_ci	for_each_entity(entity) {
80062306a36Sopenharmony_ci		st = bfq_entity_service_tree(entity);
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci		entity->service += served;
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci		st->vtime += bfq_delta(served, st->wsum);
80562306a36Sopenharmony_ci		bfq_forget_idle(st);
80662306a36Sopenharmony_ci	}
80762306a36Sopenharmony_ci	bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %d secs", served);
80862306a36Sopenharmony_ci}
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci/**
81162306a36Sopenharmony_ci * bfq_bfqq_charge_time - charge an amount of service equivalent to the length
81262306a36Sopenharmony_ci *			  of the time interval during which bfqq has been in
81362306a36Sopenharmony_ci *			  service.
81462306a36Sopenharmony_ci * @bfqd: the device
81562306a36Sopenharmony_ci * @bfqq: the queue that needs a service update.
81662306a36Sopenharmony_ci * @time_ms: the amount of time during which the queue has received service
81762306a36Sopenharmony_ci *
81862306a36Sopenharmony_ci * If a queue does not consume its budget fast enough, then providing
81962306a36Sopenharmony_ci * the queue with service fairness may impair throughput, more or less
82062306a36Sopenharmony_ci * severely. For this reason, queues that consume their budget slowly
82162306a36Sopenharmony_ci * are provided with time fairness instead of service fairness. This
82262306a36Sopenharmony_ci * goal is achieved through the BFQ scheduling engine, even if such an
82362306a36Sopenharmony_ci * engine works in the service, and not in the time domain. The trick
82462306a36Sopenharmony_ci * is charging these queues with an inflated amount of service, equal
82562306a36Sopenharmony_ci * to the amount of service that they would have received during their
82662306a36Sopenharmony_ci * service slot if they had been fast, i.e., if their requests had
82762306a36Sopenharmony_ci * been dispatched at a rate equal to the estimated peak rate.
82862306a36Sopenharmony_ci *
82962306a36Sopenharmony_ci * It is worth noting that time fairness can cause important
83062306a36Sopenharmony_ci * distortions in terms of bandwidth distribution, on devices with
83162306a36Sopenharmony_ci * internal queueing. The reason is that I/O requests dispatched
83262306a36Sopenharmony_ci * during the service slot of a queue may be served after that service
83362306a36Sopenharmony_ci * slot is finished, and may have a total processing time loosely
83462306a36Sopenharmony_ci * correlated with the duration of the service slot. This is
83562306a36Sopenharmony_ci * especially true for short service slots.
83662306a36Sopenharmony_ci */
83762306a36Sopenharmony_civoid bfq_bfqq_charge_time(struct bfq_data *bfqd, struct bfq_queue *bfqq,
83862306a36Sopenharmony_ci			  unsigned long time_ms)
83962306a36Sopenharmony_ci{
84062306a36Sopenharmony_ci	struct bfq_entity *entity = &bfqq->entity;
84162306a36Sopenharmony_ci	unsigned long timeout_ms = jiffies_to_msecs(bfq_timeout);
84262306a36Sopenharmony_ci	unsigned long bounded_time_ms = min(time_ms, timeout_ms);
84362306a36Sopenharmony_ci	int serv_to_charge_for_time =
84462306a36Sopenharmony_ci		(bfqd->bfq_max_budget * bounded_time_ms) / timeout_ms;
84562306a36Sopenharmony_ci	int tot_serv_to_charge = max(serv_to_charge_for_time, entity->service);
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci	/* Increase budget to avoid inconsistencies */
84862306a36Sopenharmony_ci	if (tot_serv_to_charge > entity->budget)
84962306a36Sopenharmony_ci		entity->budget = tot_serv_to_charge;
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_ci	bfq_bfqq_served(bfqq,
85262306a36Sopenharmony_ci			max_t(int, 0, tot_serv_to_charge - entity->service));
85362306a36Sopenharmony_ci}
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_cistatic void bfq_update_fin_time_enqueue(struct bfq_entity *entity,
85662306a36Sopenharmony_ci					struct bfq_service_tree *st,
85762306a36Sopenharmony_ci					bool backshifted)
85862306a36Sopenharmony_ci{
85962306a36Sopenharmony_ci	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	/*
86262306a36Sopenharmony_ci	 * When this function is invoked, entity is not in any service
86362306a36Sopenharmony_ci	 * tree, then it is safe to invoke next function with the last
86462306a36Sopenharmony_ci	 * parameter set (see the comments on the function).
86562306a36Sopenharmony_ci	 */
86662306a36Sopenharmony_ci	st = __bfq_entity_update_weight_prio(st, entity, true);
86762306a36Sopenharmony_ci	bfq_calc_finish(entity, entity->budget);
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci	/*
87062306a36Sopenharmony_ci	 * If some queues enjoy backshifting for a while, then their
87162306a36Sopenharmony_ci	 * (virtual) finish timestamps may happen to become lower and
87262306a36Sopenharmony_ci	 * lower than the system virtual time.	In particular, if
87362306a36Sopenharmony_ci	 * these queues often happen to be idle for short time
87462306a36Sopenharmony_ci	 * periods, and during such time periods other queues with
87562306a36Sopenharmony_ci	 * higher timestamps happen to be busy, then the backshifted
87662306a36Sopenharmony_ci	 * timestamps of the former queues can become much lower than
87762306a36Sopenharmony_ci	 * the system virtual time. In fact, to serve the queues with
87862306a36Sopenharmony_ci	 * higher timestamps while the ones with lower timestamps are
87962306a36Sopenharmony_ci	 * idle, the system virtual time may be pushed-up to much
88062306a36Sopenharmony_ci	 * higher values than the finish timestamps of the idle
88162306a36Sopenharmony_ci	 * queues. As a consequence, the finish timestamps of all new
88262306a36Sopenharmony_ci	 * or newly activated queues may end up being much larger than
88362306a36Sopenharmony_ci	 * those of lucky queues with backshifted timestamps. The
88462306a36Sopenharmony_ci	 * latter queues may then monopolize the device for a lot of
88562306a36Sopenharmony_ci	 * time. This would simply break service guarantees.
88662306a36Sopenharmony_ci	 *
88762306a36Sopenharmony_ci	 * To reduce this problem, push up a little bit the
88862306a36Sopenharmony_ci	 * backshifted timestamps of the queue associated with this
88962306a36Sopenharmony_ci	 * entity (only a queue can happen to have the backshifted
89062306a36Sopenharmony_ci	 * flag set): just enough to let the finish timestamp of the
89162306a36Sopenharmony_ci	 * queue be equal to the current value of the system virtual
89262306a36Sopenharmony_ci	 * time. This may introduce a little unfairness among queues
89362306a36Sopenharmony_ci	 * with backshifted timestamps, but it does not break
89462306a36Sopenharmony_ci	 * worst-case fairness guarantees.
89562306a36Sopenharmony_ci	 *
89662306a36Sopenharmony_ci	 * As a special case, if bfqq is weight-raised, push up
89762306a36Sopenharmony_ci	 * timestamps much less, to keep very low the probability that
89862306a36Sopenharmony_ci	 * this push up causes the backshifted finish timestamps of
89962306a36Sopenharmony_ci	 * weight-raised queues to become higher than the backshifted
90062306a36Sopenharmony_ci	 * finish timestamps of non weight-raised queues.
90162306a36Sopenharmony_ci	 */
90262306a36Sopenharmony_ci	if (backshifted && bfq_gt(st->vtime, entity->finish)) {
90362306a36Sopenharmony_ci		unsigned long delta = st->vtime - entity->finish;
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_ci		if (bfqq)
90662306a36Sopenharmony_ci			delta /= bfqq->wr_coeff;
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_ci		entity->start += delta;
90962306a36Sopenharmony_ci		entity->finish += delta;
91062306a36Sopenharmony_ci	}
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci	bfq_active_insert(st, entity);
91362306a36Sopenharmony_ci}
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci/**
91662306a36Sopenharmony_ci * __bfq_activate_entity - handle activation of entity.
91762306a36Sopenharmony_ci * @entity: the entity being activated.
91862306a36Sopenharmony_ci * @non_blocking_wait_rq: true if entity was waiting for a request
91962306a36Sopenharmony_ci *
92062306a36Sopenharmony_ci * Called for a 'true' activation, i.e., if entity is not active and
92162306a36Sopenharmony_ci * one of its children receives a new request.
92262306a36Sopenharmony_ci *
92362306a36Sopenharmony_ci * Basically, this function updates the timestamps of entity and
92462306a36Sopenharmony_ci * inserts entity into its active tree, after possibly extracting it
92562306a36Sopenharmony_ci * from its idle tree.
92662306a36Sopenharmony_ci */
92762306a36Sopenharmony_cistatic void __bfq_activate_entity(struct bfq_entity *entity,
92862306a36Sopenharmony_ci				  bool non_blocking_wait_rq)
92962306a36Sopenharmony_ci{
93062306a36Sopenharmony_ci	struct bfq_service_tree *st = bfq_entity_service_tree(entity);
93162306a36Sopenharmony_ci	bool backshifted = false;
93262306a36Sopenharmony_ci	unsigned long long min_vstart;
93362306a36Sopenharmony_ci
93462306a36Sopenharmony_ci	/* See comments on bfq_fqq_update_budg_for_activation */
93562306a36Sopenharmony_ci	if (non_blocking_wait_rq && bfq_gt(st->vtime, entity->finish)) {
93662306a36Sopenharmony_ci		backshifted = true;
93762306a36Sopenharmony_ci		min_vstart = entity->finish;
93862306a36Sopenharmony_ci	} else
93962306a36Sopenharmony_ci		min_vstart = st->vtime;
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci	if (entity->tree == &st->idle) {
94262306a36Sopenharmony_ci		/*
94362306a36Sopenharmony_ci		 * Must be on the idle tree, bfq_idle_extract() will
94462306a36Sopenharmony_ci		 * check for that.
94562306a36Sopenharmony_ci		 */
94662306a36Sopenharmony_ci		bfq_idle_extract(st, entity);
94762306a36Sopenharmony_ci		entity->start = bfq_gt(min_vstart, entity->finish) ?
94862306a36Sopenharmony_ci			min_vstart : entity->finish;
94962306a36Sopenharmony_ci	} else {
95062306a36Sopenharmony_ci		/*
95162306a36Sopenharmony_ci		 * The finish time of the entity may be invalid, and
95262306a36Sopenharmony_ci		 * it is in the past for sure, otherwise the queue
95362306a36Sopenharmony_ci		 * would have been on the idle tree.
95462306a36Sopenharmony_ci		 */
95562306a36Sopenharmony_ci		entity->start = min_vstart;
95662306a36Sopenharmony_ci		st->wsum += entity->weight;
95762306a36Sopenharmony_ci		/*
95862306a36Sopenharmony_ci		 * entity is about to be inserted into a service tree,
95962306a36Sopenharmony_ci		 * and then set in service: get a reference to make
96062306a36Sopenharmony_ci		 * sure entity does not disappear until it is no
96162306a36Sopenharmony_ci		 * longer in service or scheduled for service.
96262306a36Sopenharmony_ci		 */
96362306a36Sopenharmony_ci		bfq_get_entity(entity);
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci		entity->on_st_or_in_serv = true;
96662306a36Sopenharmony_ci	}
96762306a36Sopenharmony_ci
96862306a36Sopenharmony_ci	bfq_update_fin_time_enqueue(entity, st, backshifted);
96962306a36Sopenharmony_ci}
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci/**
97262306a36Sopenharmony_ci * __bfq_requeue_entity - handle requeueing or repositioning of an entity.
97362306a36Sopenharmony_ci * @entity: the entity being requeued or repositioned.
97462306a36Sopenharmony_ci *
97562306a36Sopenharmony_ci * Requeueing is needed if this entity stops being served, which
97662306a36Sopenharmony_ci * happens if a leaf descendant entity has expired. On the other hand,
97762306a36Sopenharmony_ci * repositioning is needed if the next_inservice_entity for the child
97862306a36Sopenharmony_ci * entity has changed. See the comments inside the function for
97962306a36Sopenharmony_ci * details.
98062306a36Sopenharmony_ci *
98162306a36Sopenharmony_ci * Basically, this function: 1) removes entity from its active tree if
98262306a36Sopenharmony_ci * present there, 2) updates the timestamps of entity and 3) inserts
98362306a36Sopenharmony_ci * entity back into its active tree (in the new, right position for
98462306a36Sopenharmony_ci * the new values of the timestamps).
98562306a36Sopenharmony_ci */
98662306a36Sopenharmony_cistatic void __bfq_requeue_entity(struct bfq_entity *entity)
98762306a36Sopenharmony_ci{
98862306a36Sopenharmony_ci	struct bfq_sched_data *sd = entity->sched_data;
98962306a36Sopenharmony_ci	struct bfq_service_tree *st = bfq_entity_service_tree(entity);
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci	if (entity == sd->in_service_entity) {
99262306a36Sopenharmony_ci		/*
99362306a36Sopenharmony_ci		 * We are requeueing the current in-service entity,
99462306a36Sopenharmony_ci		 * which may have to be done for one of the following
99562306a36Sopenharmony_ci		 * reasons:
99662306a36Sopenharmony_ci		 * - entity represents the in-service queue, and the
99762306a36Sopenharmony_ci		 *   in-service queue is being requeued after an
99862306a36Sopenharmony_ci		 *   expiration;
99962306a36Sopenharmony_ci		 * - entity represents a group, and its budget has
100062306a36Sopenharmony_ci		 *   changed because one of its child entities has
100162306a36Sopenharmony_ci		 *   just been either activated or requeued for some
100262306a36Sopenharmony_ci		 *   reason; the timestamps of the entity need then to
100362306a36Sopenharmony_ci		 *   be updated, and the entity needs to be enqueued
100462306a36Sopenharmony_ci		 *   or repositioned accordingly.
100562306a36Sopenharmony_ci		 *
100662306a36Sopenharmony_ci		 * In particular, before requeueing, the start time of
100762306a36Sopenharmony_ci		 * the entity must be moved forward to account for the
100862306a36Sopenharmony_ci		 * service that the entity has received while in
100962306a36Sopenharmony_ci		 * service. This is done by the next instructions. The
101062306a36Sopenharmony_ci		 * finish time will then be updated according to this
101162306a36Sopenharmony_ci		 * new value of the start time, and to the budget of
101262306a36Sopenharmony_ci		 * the entity.
101362306a36Sopenharmony_ci		 */
101462306a36Sopenharmony_ci		bfq_calc_finish(entity, entity->service);
101562306a36Sopenharmony_ci		entity->start = entity->finish;
101662306a36Sopenharmony_ci		/*
101762306a36Sopenharmony_ci		 * In addition, if the entity had more than one child
101862306a36Sopenharmony_ci		 * when set in service, then it was not extracted from
101962306a36Sopenharmony_ci		 * the active tree. This implies that the position of
102062306a36Sopenharmony_ci		 * the entity in the active tree may need to be
102162306a36Sopenharmony_ci		 * changed now, because we have just updated the start
102262306a36Sopenharmony_ci		 * time of the entity, and we will update its finish
102362306a36Sopenharmony_ci		 * time in a moment (the requeueing is then, more
102462306a36Sopenharmony_ci		 * precisely, a repositioning in this case). To
102562306a36Sopenharmony_ci		 * implement this repositioning, we: 1) dequeue the
102662306a36Sopenharmony_ci		 * entity here, 2) update the finish time and requeue
102762306a36Sopenharmony_ci		 * the entity according to the new timestamps below.
102862306a36Sopenharmony_ci		 */
102962306a36Sopenharmony_ci		if (entity->tree)
103062306a36Sopenharmony_ci			bfq_active_extract(st, entity);
103162306a36Sopenharmony_ci	} else { /* The entity is already active, and not in service */
103262306a36Sopenharmony_ci		/*
103362306a36Sopenharmony_ci		 * In this case, this function gets called only if the
103462306a36Sopenharmony_ci		 * next_in_service entity below this entity has
103562306a36Sopenharmony_ci		 * changed, and this change has caused the budget of
103662306a36Sopenharmony_ci		 * this entity to change, which, finally implies that
103762306a36Sopenharmony_ci		 * the finish time of this entity must be
103862306a36Sopenharmony_ci		 * updated. Such an update may cause the scheduling,
103962306a36Sopenharmony_ci		 * i.e., the position in the active tree, of this
104062306a36Sopenharmony_ci		 * entity to change. We handle this change by: 1)
104162306a36Sopenharmony_ci		 * dequeueing the entity here, 2) updating the finish
104262306a36Sopenharmony_ci		 * time and requeueing the entity according to the new
104362306a36Sopenharmony_ci		 * timestamps below. This is the same approach as the
104462306a36Sopenharmony_ci		 * non-extracted-entity sub-case above.
104562306a36Sopenharmony_ci		 */
104662306a36Sopenharmony_ci		bfq_active_extract(st, entity);
104762306a36Sopenharmony_ci	}
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ci	bfq_update_fin_time_enqueue(entity, st, false);
105062306a36Sopenharmony_ci}
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_cistatic void __bfq_activate_requeue_entity(struct bfq_entity *entity,
105362306a36Sopenharmony_ci					  bool non_blocking_wait_rq)
105462306a36Sopenharmony_ci{
105562306a36Sopenharmony_ci	struct bfq_service_tree *st = bfq_entity_service_tree(entity);
105662306a36Sopenharmony_ci
105762306a36Sopenharmony_ci	if (entity->sched_data->in_service_entity == entity ||
105862306a36Sopenharmony_ci	    entity->tree == &st->active)
105962306a36Sopenharmony_ci		 /*
106062306a36Sopenharmony_ci		  * in service or already queued on the active tree,
106162306a36Sopenharmony_ci		  * requeue or reposition
106262306a36Sopenharmony_ci		  */
106362306a36Sopenharmony_ci		__bfq_requeue_entity(entity);
106462306a36Sopenharmony_ci	else
106562306a36Sopenharmony_ci		/*
106662306a36Sopenharmony_ci		 * Not in service and not queued on its active tree:
106762306a36Sopenharmony_ci		 * the activity is idle and this is a true activation.
106862306a36Sopenharmony_ci		 */
106962306a36Sopenharmony_ci		__bfq_activate_entity(entity, non_blocking_wait_rq);
107062306a36Sopenharmony_ci}
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_ci
107362306a36Sopenharmony_ci/**
107462306a36Sopenharmony_ci * bfq_activate_requeue_entity - activate or requeue an entity representing a
107562306a36Sopenharmony_ci *				 bfq_queue, and activate, requeue or reposition
107662306a36Sopenharmony_ci *				 all ancestors for which such an update becomes
107762306a36Sopenharmony_ci *				 necessary.
107862306a36Sopenharmony_ci * @entity: the entity to activate.
107962306a36Sopenharmony_ci * @non_blocking_wait_rq: true if this entity was waiting for a request
108062306a36Sopenharmony_ci * @requeue: true if this is a requeue, which implies that bfqq is
108162306a36Sopenharmony_ci *	     being expired; thus ALL its ancestors stop being served and must
108262306a36Sopenharmony_ci *	     therefore be requeued
108362306a36Sopenharmony_ci * @expiration: true if this function is being invoked in the expiration path
108462306a36Sopenharmony_ci *             of the in-service queue
108562306a36Sopenharmony_ci */
108662306a36Sopenharmony_cistatic void bfq_activate_requeue_entity(struct bfq_entity *entity,
108762306a36Sopenharmony_ci					bool non_blocking_wait_rq,
108862306a36Sopenharmony_ci					bool requeue, bool expiration)
108962306a36Sopenharmony_ci{
109062306a36Sopenharmony_ci	for_each_entity(entity) {
109162306a36Sopenharmony_ci		__bfq_activate_requeue_entity(entity, non_blocking_wait_rq);
109262306a36Sopenharmony_ci		if (!bfq_update_next_in_service(entity->sched_data, entity,
109362306a36Sopenharmony_ci						expiration) && !requeue)
109462306a36Sopenharmony_ci			break;
109562306a36Sopenharmony_ci	}
109662306a36Sopenharmony_ci}
109762306a36Sopenharmony_ci
109862306a36Sopenharmony_ci/**
109962306a36Sopenharmony_ci * __bfq_deactivate_entity - update sched_data and service trees for
110062306a36Sopenharmony_ci * entity, so as to represent entity as inactive
110162306a36Sopenharmony_ci * @entity: the entity being deactivated.
110262306a36Sopenharmony_ci * @ins_into_idle_tree: if false, the entity will not be put into the
110362306a36Sopenharmony_ci *			idle tree.
110462306a36Sopenharmony_ci *
110562306a36Sopenharmony_ci * If necessary and allowed, puts entity into the idle tree. NOTE:
110662306a36Sopenharmony_ci * entity may be on no tree if in service.
110762306a36Sopenharmony_ci */
110862306a36Sopenharmony_cibool __bfq_deactivate_entity(struct bfq_entity *entity, bool ins_into_idle_tree)
110962306a36Sopenharmony_ci{
111062306a36Sopenharmony_ci	struct bfq_sched_data *sd = entity->sched_data;
111162306a36Sopenharmony_ci	struct bfq_service_tree *st;
111262306a36Sopenharmony_ci	bool is_in_service;
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_ci	if (!entity->on_st_or_in_serv) /*
111562306a36Sopenharmony_ci					* entity never activated, or
111662306a36Sopenharmony_ci					* already inactive
111762306a36Sopenharmony_ci					*/
111862306a36Sopenharmony_ci		return false;
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci	/*
112162306a36Sopenharmony_ci	 * If we get here, then entity is active, which implies that
112262306a36Sopenharmony_ci	 * bfq_group_set_parent has already been invoked for the group
112362306a36Sopenharmony_ci	 * represented by entity. Therefore, the field
112462306a36Sopenharmony_ci	 * entity->sched_data has been set, and we can safely use it.
112562306a36Sopenharmony_ci	 */
112662306a36Sopenharmony_ci	st = bfq_entity_service_tree(entity);
112762306a36Sopenharmony_ci	is_in_service = entity == sd->in_service_entity;
112862306a36Sopenharmony_ci
112962306a36Sopenharmony_ci	bfq_calc_finish(entity, entity->service);
113062306a36Sopenharmony_ci
113162306a36Sopenharmony_ci	if (is_in_service)
113262306a36Sopenharmony_ci		sd->in_service_entity = NULL;
113362306a36Sopenharmony_ci	else
113462306a36Sopenharmony_ci		/*
113562306a36Sopenharmony_ci		 * Non in-service entity: nobody will take care of
113662306a36Sopenharmony_ci		 * resetting its service counter on expiration. Do it
113762306a36Sopenharmony_ci		 * now.
113862306a36Sopenharmony_ci		 */
113962306a36Sopenharmony_ci		entity->service = 0;
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_ci	if (entity->tree == &st->active)
114262306a36Sopenharmony_ci		bfq_active_extract(st, entity);
114362306a36Sopenharmony_ci	else if (!is_in_service && entity->tree == &st->idle)
114462306a36Sopenharmony_ci		bfq_idle_extract(st, entity);
114562306a36Sopenharmony_ci
114662306a36Sopenharmony_ci	if (!ins_into_idle_tree || !bfq_gt(entity->finish, st->vtime))
114762306a36Sopenharmony_ci		bfq_forget_entity(st, entity, is_in_service);
114862306a36Sopenharmony_ci	else
114962306a36Sopenharmony_ci		bfq_idle_insert(st, entity);
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_ci	return true;
115262306a36Sopenharmony_ci}
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci/**
115562306a36Sopenharmony_ci * bfq_deactivate_entity - deactivate an entity representing a bfq_queue.
115662306a36Sopenharmony_ci * @entity: the entity to deactivate.
115762306a36Sopenharmony_ci * @ins_into_idle_tree: true if the entity can be put into the idle tree
115862306a36Sopenharmony_ci * @expiration: true if this function is being invoked in the expiration path
115962306a36Sopenharmony_ci *             of the in-service queue
116062306a36Sopenharmony_ci */
116162306a36Sopenharmony_cistatic void bfq_deactivate_entity(struct bfq_entity *entity,
116262306a36Sopenharmony_ci				  bool ins_into_idle_tree,
116362306a36Sopenharmony_ci				  bool expiration)
116462306a36Sopenharmony_ci{
116562306a36Sopenharmony_ci	struct bfq_sched_data *sd;
116662306a36Sopenharmony_ci	struct bfq_entity *parent = NULL;
116762306a36Sopenharmony_ci
116862306a36Sopenharmony_ci	for_each_entity_safe(entity, parent) {
116962306a36Sopenharmony_ci		sd = entity->sched_data;
117062306a36Sopenharmony_ci
117162306a36Sopenharmony_ci		if (!__bfq_deactivate_entity(entity, ins_into_idle_tree)) {
117262306a36Sopenharmony_ci			/*
117362306a36Sopenharmony_ci			 * entity is not in any tree any more, so
117462306a36Sopenharmony_ci			 * this deactivation is a no-op, and there is
117562306a36Sopenharmony_ci			 * nothing to change for upper-level entities
117662306a36Sopenharmony_ci			 * (in case of expiration, this can never
117762306a36Sopenharmony_ci			 * happen).
117862306a36Sopenharmony_ci			 */
117962306a36Sopenharmony_ci			return;
118062306a36Sopenharmony_ci		}
118162306a36Sopenharmony_ci
118262306a36Sopenharmony_ci		if (sd->next_in_service == entity)
118362306a36Sopenharmony_ci			/*
118462306a36Sopenharmony_ci			 * entity was the next_in_service entity,
118562306a36Sopenharmony_ci			 * then, since entity has just been
118662306a36Sopenharmony_ci			 * deactivated, a new one must be found.
118762306a36Sopenharmony_ci			 */
118862306a36Sopenharmony_ci			bfq_update_next_in_service(sd, NULL, expiration);
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_ci		if (sd->next_in_service || sd->in_service_entity) {
119162306a36Sopenharmony_ci			/*
119262306a36Sopenharmony_ci			 * The parent entity is still active, because
119362306a36Sopenharmony_ci			 * either next_in_service or in_service_entity
119462306a36Sopenharmony_ci			 * is not NULL. So, no further upwards
119562306a36Sopenharmony_ci			 * deactivation must be performed.  Yet,
119662306a36Sopenharmony_ci			 * next_in_service has changed.	Then the
119762306a36Sopenharmony_ci			 * schedule does need to be updated upwards.
119862306a36Sopenharmony_ci			 *
119962306a36Sopenharmony_ci			 * NOTE If in_service_entity is not NULL, then
120062306a36Sopenharmony_ci			 * next_in_service may happen to be NULL,
120162306a36Sopenharmony_ci			 * although the parent entity is evidently
120262306a36Sopenharmony_ci			 * active. This happens if 1) the entity
120362306a36Sopenharmony_ci			 * pointed by in_service_entity is the only
120462306a36Sopenharmony_ci			 * active entity in the parent entity, and 2)
120562306a36Sopenharmony_ci			 * according to the definition of
120662306a36Sopenharmony_ci			 * next_in_service, the in_service_entity
120762306a36Sopenharmony_ci			 * cannot be considered as
120862306a36Sopenharmony_ci			 * next_in_service. See the comments on the
120962306a36Sopenharmony_ci			 * definition of next_in_service for details.
121062306a36Sopenharmony_ci			 */
121162306a36Sopenharmony_ci			break;
121262306a36Sopenharmony_ci		}
121362306a36Sopenharmony_ci
121462306a36Sopenharmony_ci		/*
121562306a36Sopenharmony_ci		 * If we get here, then the parent is no more
121662306a36Sopenharmony_ci		 * backlogged and we need to propagate the
121762306a36Sopenharmony_ci		 * deactivation upwards. Thus let the loop go on.
121862306a36Sopenharmony_ci		 */
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_ci		/*
122162306a36Sopenharmony_ci		 * Also let parent be queued into the idle tree on
122262306a36Sopenharmony_ci		 * deactivation, to preserve service guarantees, and
122362306a36Sopenharmony_ci		 * assuming that who invoked this function does not
122462306a36Sopenharmony_ci		 * need parent entities too to be removed completely.
122562306a36Sopenharmony_ci		 */
122662306a36Sopenharmony_ci		ins_into_idle_tree = true;
122762306a36Sopenharmony_ci	}
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	/*
123062306a36Sopenharmony_ci	 * If the deactivation loop is fully executed, then there are
123162306a36Sopenharmony_ci	 * no more entities to touch and next loop is not executed at
123262306a36Sopenharmony_ci	 * all. Otherwise, requeue remaining entities if they are
123362306a36Sopenharmony_ci	 * about to stop receiving service, or reposition them if this
123462306a36Sopenharmony_ci	 * is not the case.
123562306a36Sopenharmony_ci	 */
123662306a36Sopenharmony_ci	entity = parent;
123762306a36Sopenharmony_ci	for_each_entity(entity) {
123862306a36Sopenharmony_ci		/*
123962306a36Sopenharmony_ci		 * Invoke __bfq_requeue_entity on entity, even if
124062306a36Sopenharmony_ci		 * already active, to requeue/reposition it in the
124162306a36Sopenharmony_ci		 * active tree (because sd->next_in_service has
124262306a36Sopenharmony_ci		 * changed)
124362306a36Sopenharmony_ci		 */
124462306a36Sopenharmony_ci		__bfq_requeue_entity(entity);
124562306a36Sopenharmony_ci
124662306a36Sopenharmony_ci		sd = entity->sched_data;
124762306a36Sopenharmony_ci		if (!bfq_update_next_in_service(sd, entity, expiration) &&
124862306a36Sopenharmony_ci		    !expiration)
124962306a36Sopenharmony_ci			/*
125062306a36Sopenharmony_ci			 * next_in_service unchanged or not causing
125162306a36Sopenharmony_ci			 * any change in entity->parent->sd, and no
125262306a36Sopenharmony_ci			 * requeueing needed for expiration: stop
125362306a36Sopenharmony_ci			 * here.
125462306a36Sopenharmony_ci			 */
125562306a36Sopenharmony_ci			break;
125662306a36Sopenharmony_ci	}
125762306a36Sopenharmony_ci}
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci/**
126062306a36Sopenharmony_ci * bfq_calc_vtime_jump - compute the value to which the vtime should jump,
126162306a36Sopenharmony_ci *                       if needed, to have at least one entity eligible.
126262306a36Sopenharmony_ci * @st: the service tree to act upon.
126362306a36Sopenharmony_ci *
126462306a36Sopenharmony_ci * Assumes that st is not empty.
126562306a36Sopenharmony_ci */
126662306a36Sopenharmony_cistatic u64 bfq_calc_vtime_jump(struct bfq_service_tree *st)
126762306a36Sopenharmony_ci{
126862306a36Sopenharmony_ci	struct bfq_entity *root_entity = bfq_root_active_entity(&st->active);
126962306a36Sopenharmony_ci
127062306a36Sopenharmony_ci	if (bfq_gt(root_entity->min_start, st->vtime))
127162306a36Sopenharmony_ci		return root_entity->min_start;
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci	return st->vtime;
127462306a36Sopenharmony_ci}
127562306a36Sopenharmony_ci
127662306a36Sopenharmony_cistatic void bfq_update_vtime(struct bfq_service_tree *st, u64 new_value)
127762306a36Sopenharmony_ci{
127862306a36Sopenharmony_ci	if (new_value > st->vtime) {
127962306a36Sopenharmony_ci		st->vtime = new_value;
128062306a36Sopenharmony_ci		bfq_forget_idle(st);
128162306a36Sopenharmony_ci	}
128262306a36Sopenharmony_ci}
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci/**
128562306a36Sopenharmony_ci * bfq_first_active_entity - find the eligible entity with
128662306a36Sopenharmony_ci *                           the smallest finish time
128762306a36Sopenharmony_ci * @st: the service tree to select from.
128862306a36Sopenharmony_ci * @vtime: the system virtual to use as a reference for eligibility
128962306a36Sopenharmony_ci *
129062306a36Sopenharmony_ci * This function searches the first schedulable entity, starting from the
129162306a36Sopenharmony_ci * root of the tree and going on the left every time on this side there is
129262306a36Sopenharmony_ci * a subtree with at least one eligible (start <= vtime) entity. The path on
129362306a36Sopenharmony_ci * the right is followed only if a) the left subtree contains no eligible
129462306a36Sopenharmony_ci * entities and b) no eligible entity has been found yet.
129562306a36Sopenharmony_ci */
129662306a36Sopenharmony_cistatic struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st,
129762306a36Sopenharmony_ci						  u64 vtime)
129862306a36Sopenharmony_ci{
129962306a36Sopenharmony_ci	struct bfq_entity *entry, *first = NULL;
130062306a36Sopenharmony_ci	struct rb_node *node = st->active.rb_node;
130162306a36Sopenharmony_ci
130262306a36Sopenharmony_ci	while (node) {
130362306a36Sopenharmony_ci		entry = rb_entry(node, struct bfq_entity, rb_node);
130462306a36Sopenharmony_cileft:
130562306a36Sopenharmony_ci		if (!bfq_gt(entry->start, vtime))
130662306a36Sopenharmony_ci			first = entry;
130762306a36Sopenharmony_ci
130862306a36Sopenharmony_ci		if (node->rb_left) {
130962306a36Sopenharmony_ci			entry = rb_entry(node->rb_left,
131062306a36Sopenharmony_ci					 struct bfq_entity, rb_node);
131162306a36Sopenharmony_ci			if (!bfq_gt(entry->min_start, vtime)) {
131262306a36Sopenharmony_ci				node = node->rb_left;
131362306a36Sopenharmony_ci				goto left;
131462306a36Sopenharmony_ci			}
131562306a36Sopenharmony_ci		}
131662306a36Sopenharmony_ci		if (first)
131762306a36Sopenharmony_ci			break;
131862306a36Sopenharmony_ci		node = node->rb_right;
131962306a36Sopenharmony_ci	}
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_ci	return first;
132262306a36Sopenharmony_ci}
132362306a36Sopenharmony_ci
132462306a36Sopenharmony_ci/**
132562306a36Sopenharmony_ci * __bfq_lookup_next_entity - return the first eligible entity in @st.
132662306a36Sopenharmony_ci * @st: the service tree.
132762306a36Sopenharmony_ci * @in_service: whether or not there is an in-service entity for the sched_data
132862306a36Sopenharmony_ci *	this active tree belongs to.
132962306a36Sopenharmony_ci *
133062306a36Sopenharmony_ci * If there is no in-service entity for the sched_data st belongs to,
133162306a36Sopenharmony_ci * then return the entity that will be set in service if:
133262306a36Sopenharmony_ci * 1) the parent entity this st belongs to is set in service;
133362306a36Sopenharmony_ci * 2) no entity belonging to such parent entity undergoes a state change
133462306a36Sopenharmony_ci * that would influence the timestamps of the entity (e.g., becomes idle,
133562306a36Sopenharmony_ci * becomes backlogged, changes its budget, ...).
133662306a36Sopenharmony_ci *
133762306a36Sopenharmony_ci * In this first case, update the virtual time in @st too (see the
133862306a36Sopenharmony_ci * comments on this update inside the function).
133962306a36Sopenharmony_ci *
134062306a36Sopenharmony_ci * In contrast, if there is an in-service entity, then return the
134162306a36Sopenharmony_ci * entity that would be set in service if not only the above
134262306a36Sopenharmony_ci * conditions, but also the next one held true: the currently
134362306a36Sopenharmony_ci * in-service entity, on expiration,
134462306a36Sopenharmony_ci * 1) gets a finish time equal to the current one, or
134562306a36Sopenharmony_ci * 2) is not eligible any more, or
134662306a36Sopenharmony_ci * 3) is idle.
134762306a36Sopenharmony_ci */
134862306a36Sopenharmony_cistatic struct bfq_entity *
134962306a36Sopenharmony_ci__bfq_lookup_next_entity(struct bfq_service_tree *st, bool in_service)
135062306a36Sopenharmony_ci{
135162306a36Sopenharmony_ci	struct bfq_entity *entity;
135262306a36Sopenharmony_ci	u64 new_vtime;
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_ci	if (RB_EMPTY_ROOT(&st->active))
135562306a36Sopenharmony_ci		return NULL;
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci	/*
135862306a36Sopenharmony_ci	 * Get the value of the system virtual time for which at
135962306a36Sopenharmony_ci	 * least one entity is eligible.
136062306a36Sopenharmony_ci	 */
136162306a36Sopenharmony_ci	new_vtime = bfq_calc_vtime_jump(st);
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci	/*
136462306a36Sopenharmony_ci	 * If there is no in-service entity for the sched_data this
136562306a36Sopenharmony_ci	 * active tree belongs to, then push the system virtual time
136662306a36Sopenharmony_ci	 * up to the value that guarantees that at least one entity is
136762306a36Sopenharmony_ci	 * eligible. If, instead, there is an in-service entity, then
136862306a36Sopenharmony_ci	 * do not make any such update, because there is already an
136962306a36Sopenharmony_ci	 * eligible entity, namely the in-service one (even if the
137062306a36Sopenharmony_ci	 * entity is not on st, because it was extracted when set in
137162306a36Sopenharmony_ci	 * service).
137262306a36Sopenharmony_ci	 */
137362306a36Sopenharmony_ci	if (!in_service)
137462306a36Sopenharmony_ci		bfq_update_vtime(st, new_vtime);
137562306a36Sopenharmony_ci
137662306a36Sopenharmony_ci	entity = bfq_first_active_entity(st, new_vtime);
137762306a36Sopenharmony_ci
137862306a36Sopenharmony_ci	return entity;
137962306a36Sopenharmony_ci}
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_ci/**
138262306a36Sopenharmony_ci * bfq_lookup_next_entity - return the first eligible entity in @sd.
138362306a36Sopenharmony_ci * @sd: the sched_data.
138462306a36Sopenharmony_ci * @expiration: true if we are on the expiration path of the in-service queue
138562306a36Sopenharmony_ci *
138662306a36Sopenharmony_ci * This function is invoked when there has been a change in the trees
138762306a36Sopenharmony_ci * for sd, and we need to know what is the new next entity to serve
138862306a36Sopenharmony_ci * after this change.
138962306a36Sopenharmony_ci */
139062306a36Sopenharmony_cistatic struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
139162306a36Sopenharmony_ci						 bool expiration)
139262306a36Sopenharmony_ci{
139362306a36Sopenharmony_ci	struct bfq_service_tree *st = sd->service_tree;
139462306a36Sopenharmony_ci	struct bfq_service_tree *idle_class_st = st + (BFQ_IOPRIO_CLASSES - 1);
139562306a36Sopenharmony_ci	struct bfq_entity *entity = NULL;
139662306a36Sopenharmony_ci	int class_idx = 0;
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci	/*
139962306a36Sopenharmony_ci	 * Choose from idle class, if needed to guarantee a minimum
140062306a36Sopenharmony_ci	 * bandwidth to this class (and if there is some active entity
140162306a36Sopenharmony_ci	 * in idle class). This should also mitigate
140262306a36Sopenharmony_ci	 * priority-inversion problems in case a low priority task is
140362306a36Sopenharmony_ci	 * holding file system resources.
140462306a36Sopenharmony_ci	 */
140562306a36Sopenharmony_ci	if (time_is_before_jiffies(sd->bfq_class_idle_last_service +
140662306a36Sopenharmony_ci				   BFQ_CL_IDLE_TIMEOUT)) {
140762306a36Sopenharmony_ci		if (!RB_EMPTY_ROOT(&idle_class_st->active))
140862306a36Sopenharmony_ci			class_idx = BFQ_IOPRIO_CLASSES - 1;
140962306a36Sopenharmony_ci		/* About to be served if backlogged, or not yet backlogged */
141062306a36Sopenharmony_ci		sd->bfq_class_idle_last_service = jiffies;
141162306a36Sopenharmony_ci	}
141262306a36Sopenharmony_ci
141362306a36Sopenharmony_ci	/*
141462306a36Sopenharmony_ci	 * Find the next entity to serve for the highest-priority
141562306a36Sopenharmony_ci	 * class, unless the idle class needs to be served.
141662306a36Sopenharmony_ci	 */
141762306a36Sopenharmony_ci	for (; class_idx < BFQ_IOPRIO_CLASSES; class_idx++) {
141862306a36Sopenharmony_ci		/*
141962306a36Sopenharmony_ci		 * If expiration is true, then bfq_lookup_next_entity
142062306a36Sopenharmony_ci		 * is being invoked as a part of the expiration path
142162306a36Sopenharmony_ci		 * of the in-service queue. In this case, even if
142262306a36Sopenharmony_ci		 * sd->in_service_entity is not NULL,
142362306a36Sopenharmony_ci		 * sd->in_service_entity at this point is actually not
142462306a36Sopenharmony_ci		 * in service any more, and, if needed, has already
142562306a36Sopenharmony_ci		 * been properly queued or requeued into the right
142662306a36Sopenharmony_ci		 * tree. The reason why sd->in_service_entity is still
142762306a36Sopenharmony_ci		 * not NULL here, even if expiration is true, is that
142862306a36Sopenharmony_ci		 * sd->in_service_entity is reset as a last step in the
142962306a36Sopenharmony_ci		 * expiration path. So, if expiration is true, tell
143062306a36Sopenharmony_ci		 * __bfq_lookup_next_entity that there is no
143162306a36Sopenharmony_ci		 * sd->in_service_entity.
143262306a36Sopenharmony_ci		 */
143362306a36Sopenharmony_ci		entity = __bfq_lookup_next_entity(st + class_idx,
143462306a36Sopenharmony_ci						  sd->in_service_entity &&
143562306a36Sopenharmony_ci						  !expiration);
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci		if (entity)
143862306a36Sopenharmony_ci			break;
143962306a36Sopenharmony_ci	}
144062306a36Sopenharmony_ci
144162306a36Sopenharmony_ci	return entity;
144262306a36Sopenharmony_ci}
144362306a36Sopenharmony_ci
144462306a36Sopenharmony_cibool next_queue_may_preempt(struct bfq_data *bfqd)
144562306a36Sopenharmony_ci{
144662306a36Sopenharmony_ci	struct bfq_sched_data *sd = &bfqd->root_group->sched_data;
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_ci	return sd->next_in_service != sd->in_service_entity;
144962306a36Sopenharmony_ci}
145062306a36Sopenharmony_ci
145162306a36Sopenharmony_ci/*
145262306a36Sopenharmony_ci * Get next queue for service.
145362306a36Sopenharmony_ci */
145462306a36Sopenharmony_cistruct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
145562306a36Sopenharmony_ci{
145662306a36Sopenharmony_ci	struct bfq_entity *entity = NULL;
145762306a36Sopenharmony_ci	struct bfq_sched_data *sd;
145862306a36Sopenharmony_ci	struct bfq_queue *bfqq;
145962306a36Sopenharmony_ci
146062306a36Sopenharmony_ci	if (bfq_tot_busy_queues(bfqd) == 0)
146162306a36Sopenharmony_ci		return NULL;
146262306a36Sopenharmony_ci
146362306a36Sopenharmony_ci	/*
146462306a36Sopenharmony_ci	 * Traverse the path from the root to the leaf entity to
146562306a36Sopenharmony_ci	 * serve. Set in service all the entities visited along the
146662306a36Sopenharmony_ci	 * way.
146762306a36Sopenharmony_ci	 */
146862306a36Sopenharmony_ci	sd = &bfqd->root_group->sched_data;
146962306a36Sopenharmony_ci	for (; sd ; sd = entity->my_sched_data) {
147062306a36Sopenharmony_ci		/*
147162306a36Sopenharmony_ci		 * WARNING. We are about to set the in-service entity
147262306a36Sopenharmony_ci		 * to sd->next_in_service, i.e., to the (cached) value
147362306a36Sopenharmony_ci		 * returned by bfq_lookup_next_entity(sd) the last
147462306a36Sopenharmony_ci		 * time it was invoked, i.e., the last time when the
147562306a36Sopenharmony_ci		 * service order in sd changed as a consequence of the
147662306a36Sopenharmony_ci		 * activation or deactivation of an entity. In this
147762306a36Sopenharmony_ci		 * respect, if we execute bfq_lookup_next_entity(sd)
147862306a36Sopenharmony_ci		 * in this very moment, it may, although with low
147962306a36Sopenharmony_ci		 * probability, yield a different entity than that
148062306a36Sopenharmony_ci		 * pointed to by sd->next_in_service. This rare event
148162306a36Sopenharmony_ci		 * happens in case there was no CLASS_IDLE entity to
148262306a36Sopenharmony_ci		 * serve for sd when bfq_lookup_next_entity(sd) was
148362306a36Sopenharmony_ci		 * invoked for the last time, while there is now one
148462306a36Sopenharmony_ci		 * such entity.
148562306a36Sopenharmony_ci		 *
148662306a36Sopenharmony_ci		 * If the above event happens, then the scheduling of
148762306a36Sopenharmony_ci		 * such entity in CLASS_IDLE is postponed until the
148862306a36Sopenharmony_ci		 * service of the sd->next_in_service entity
148962306a36Sopenharmony_ci		 * finishes. In fact, when the latter is expired,
149062306a36Sopenharmony_ci		 * bfq_lookup_next_entity(sd) gets called again,
149162306a36Sopenharmony_ci		 * exactly to update sd->next_in_service.
149262306a36Sopenharmony_ci		 */
149362306a36Sopenharmony_ci
149462306a36Sopenharmony_ci		/* Make next_in_service entity become in_service_entity */
149562306a36Sopenharmony_ci		entity = sd->next_in_service;
149662306a36Sopenharmony_ci		sd->in_service_entity = entity;
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_ci		/*
149962306a36Sopenharmony_ci		 * If entity is no longer a candidate for next
150062306a36Sopenharmony_ci		 * service, then it must be extracted from its active
150162306a36Sopenharmony_ci		 * tree, so as to make sure that it won't be
150262306a36Sopenharmony_ci		 * considered when computing next_in_service. See the
150362306a36Sopenharmony_ci		 * comments on the function
150462306a36Sopenharmony_ci		 * bfq_no_longer_next_in_service() for details.
150562306a36Sopenharmony_ci		 */
150662306a36Sopenharmony_ci		if (bfq_no_longer_next_in_service(entity))
150762306a36Sopenharmony_ci			bfq_active_extract(bfq_entity_service_tree(entity),
150862306a36Sopenharmony_ci					   entity);
150962306a36Sopenharmony_ci
151062306a36Sopenharmony_ci		/*
151162306a36Sopenharmony_ci		 * Even if entity is not to be extracted according to
151262306a36Sopenharmony_ci		 * the above check, a descendant entity may get
151362306a36Sopenharmony_ci		 * extracted in one of the next iterations of this
151462306a36Sopenharmony_ci		 * loop. Such an event could cause a change in
151562306a36Sopenharmony_ci		 * next_in_service for the level of the descendant
151662306a36Sopenharmony_ci		 * entity, and thus possibly back to this level.
151762306a36Sopenharmony_ci		 *
151862306a36Sopenharmony_ci		 * However, we cannot perform the resulting needed
151962306a36Sopenharmony_ci		 * update of next_in_service for this level before the
152062306a36Sopenharmony_ci		 * end of the whole loop, because, to know which is
152162306a36Sopenharmony_ci		 * the correct next-to-serve candidate entity for each
152262306a36Sopenharmony_ci		 * level, we need first to find the leaf entity to set
152362306a36Sopenharmony_ci		 * in service. In fact, only after we know which is
152462306a36Sopenharmony_ci		 * the next-to-serve leaf entity, we can discover
152562306a36Sopenharmony_ci		 * whether the parent entity of the leaf entity
152662306a36Sopenharmony_ci		 * becomes the next-to-serve, and so on.
152762306a36Sopenharmony_ci		 */
152862306a36Sopenharmony_ci	}
152962306a36Sopenharmony_ci
153062306a36Sopenharmony_ci	bfqq = bfq_entity_to_bfqq(entity);
153162306a36Sopenharmony_ci
153262306a36Sopenharmony_ci	/*
153362306a36Sopenharmony_ci	 * We can finally update all next-to-serve entities along the
153462306a36Sopenharmony_ci	 * path from the leaf entity just set in service to the root.
153562306a36Sopenharmony_ci	 */
153662306a36Sopenharmony_ci	for_each_entity(entity) {
153762306a36Sopenharmony_ci		struct bfq_sched_data *sd = entity->sched_data;
153862306a36Sopenharmony_ci
153962306a36Sopenharmony_ci		if (!bfq_update_next_in_service(sd, NULL, false))
154062306a36Sopenharmony_ci			break;
154162306a36Sopenharmony_ci	}
154262306a36Sopenharmony_ci
154362306a36Sopenharmony_ci	return bfqq;
154462306a36Sopenharmony_ci}
154562306a36Sopenharmony_ci
154662306a36Sopenharmony_ci/* returns true if the in-service queue gets freed */
154762306a36Sopenharmony_cibool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
154862306a36Sopenharmony_ci{
154962306a36Sopenharmony_ci	struct bfq_queue *in_serv_bfqq = bfqd->in_service_queue;
155062306a36Sopenharmony_ci	struct bfq_entity *in_serv_entity = &in_serv_bfqq->entity;
155162306a36Sopenharmony_ci	struct bfq_entity *entity = in_serv_entity;
155262306a36Sopenharmony_ci
155362306a36Sopenharmony_ci	bfq_clear_bfqq_wait_request(in_serv_bfqq);
155462306a36Sopenharmony_ci	hrtimer_try_to_cancel(&bfqd->idle_slice_timer);
155562306a36Sopenharmony_ci	bfqd->in_service_queue = NULL;
155662306a36Sopenharmony_ci
155762306a36Sopenharmony_ci	/*
155862306a36Sopenharmony_ci	 * When this function is called, all in-service entities have
155962306a36Sopenharmony_ci	 * been properly deactivated or requeued, so we can safely
156062306a36Sopenharmony_ci	 * execute the final step: reset in_service_entity along the
156162306a36Sopenharmony_ci	 * path from entity to the root.
156262306a36Sopenharmony_ci	 */
156362306a36Sopenharmony_ci	for_each_entity(entity)
156462306a36Sopenharmony_ci		entity->sched_data->in_service_entity = NULL;
156562306a36Sopenharmony_ci
156662306a36Sopenharmony_ci	/*
156762306a36Sopenharmony_ci	 * in_serv_entity is no longer in service, so, if it is in no
156862306a36Sopenharmony_ci	 * service tree either, then release the service reference to
156962306a36Sopenharmony_ci	 * the queue it represents (taken with bfq_get_entity).
157062306a36Sopenharmony_ci	 */
157162306a36Sopenharmony_ci	if (!in_serv_entity->on_st_or_in_serv) {
157262306a36Sopenharmony_ci		/*
157362306a36Sopenharmony_ci		 * If no process is referencing in_serv_bfqq any
157462306a36Sopenharmony_ci		 * longer, then the service reference may be the only
157562306a36Sopenharmony_ci		 * reference to the queue. If this is the case, then
157662306a36Sopenharmony_ci		 * bfqq gets freed here.
157762306a36Sopenharmony_ci		 */
157862306a36Sopenharmony_ci		int ref = in_serv_bfqq->ref;
157962306a36Sopenharmony_ci		bfq_put_queue(in_serv_bfqq);
158062306a36Sopenharmony_ci		if (ref == 1)
158162306a36Sopenharmony_ci			return true;
158262306a36Sopenharmony_ci	}
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci	return false;
158562306a36Sopenharmony_ci}
158662306a36Sopenharmony_ci
158762306a36Sopenharmony_civoid bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
158862306a36Sopenharmony_ci			 bool ins_into_idle_tree, bool expiration)
158962306a36Sopenharmony_ci{
159062306a36Sopenharmony_ci	struct bfq_entity *entity = &bfqq->entity;
159162306a36Sopenharmony_ci
159262306a36Sopenharmony_ci	bfq_deactivate_entity(entity, ins_into_idle_tree, expiration);
159362306a36Sopenharmony_ci}
159462306a36Sopenharmony_ci
159562306a36Sopenharmony_civoid bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
159662306a36Sopenharmony_ci{
159762306a36Sopenharmony_ci	struct bfq_entity *entity = &bfqq->entity;
159862306a36Sopenharmony_ci
159962306a36Sopenharmony_ci	bfq_activate_requeue_entity(entity, bfq_bfqq_non_blocking_wait_rq(bfqq),
160062306a36Sopenharmony_ci				    false, false);
160162306a36Sopenharmony_ci	bfq_clear_bfqq_non_blocking_wait_rq(bfqq);
160262306a36Sopenharmony_ci}
160362306a36Sopenharmony_ci
160462306a36Sopenharmony_civoid bfq_requeue_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
160562306a36Sopenharmony_ci		      bool expiration)
160662306a36Sopenharmony_ci{
160762306a36Sopenharmony_ci	struct bfq_entity *entity = &bfqq->entity;
160862306a36Sopenharmony_ci
160962306a36Sopenharmony_ci	bfq_activate_requeue_entity(entity, false,
161062306a36Sopenharmony_ci				    bfqq == bfqd->in_service_queue, expiration);
161162306a36Sopenharmony_ci}
161262306a36Sopenharmony_ci
161362306a36Sopenharmony_civoid bfq_add_bfqq_in_groups_with_pending_reqs(struct bfq_queue *bfqq)
161462306a36Sopenharmony_ci{
161562306a36Sopenharmony_ci#ifdef CONFIG_BFQ_GROUP_IOSCHED
161662306a36Sopenharmony_ci	struct bfq_entity *entity = &bfqq->entity;
161762306a36Sopenharmony_ci
161862306a36Sopenharmony_ci	if (!entity->in_groups_with_pending_reqs) {
161962306a36Sopenharmony_ci		entity->in_groups_with_pending_reqs = true;
162062306a36Sopenharmony_ci		if (!(bfqq_group(bfqq)->num_queues_with_pending_reqs++))
162162306a36Sopenharmony_ci			bfqq->bfqd->num_groups_with_pending_reqs++;
162262306a36Sopenharmony_ci	}
162362306a36Sopenharmony_ci#endif
162462306a36Sopenharmony_ci}
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_civoid bfq_del_bfqq_in_groups_with_pending_reqs(struct bfq_queue *bfqq)
162762306a36Sopenharmony_ci{
162862306a36Sopenharmony_ci#ifdef CONFIG_BFQ_GROUP_IOSCHED
162962306a36Sopenharmony_ci	struct bfq_entity *entity = &bfqq->entity;
163062306a36Sopenharmony_ci
163162306a36Sopenharmony_ci	if (entity->in_groups_with_pending_reqs) {
163262306a36Sopenharmony_ci		entity->in_groups_with_pending_reqs = false;
163362306a36Sopenharmony_ci		if (!(--bfqq_group(bfqq)->num_queues_with_pending_reqs))
163462306a36Sopenharmony_ci			bfqq->bfqd->num_groups_with_pending_reqs--;
163562306a36Sopenharmony_ci	}
163662306a36Sopenharmony_ci#endif
163762306a36Sopenharmony_ci}
163862306a36Sopenharmony_ci
163962306a36Sopenharmony_ci/*
164062306a36Sopenharmony_ci * Called when the bfqq no longer has requests pending, remove it from
164162306a36Sopenharmony_ci * the service tree. As a special case, it can be invoked during an
164262306a36Sopenharmony_ci * expiration.
164362306a36Sopenharmony_ci */
164462306a36Sopenharmony_civoid bfq_del_bfqq_busy(struct bfq_queue *bfqq, bool expiration)
164562306a36Sopenharmony_ci{
164662306a36Sopenharmony_ci	struct bfq_data *bfqd = bfqq->bfqd;
164762306a36Sopenharmony_ci
164862306a36Sopenharmony_ci	bfq_log_bfqq(bfqd, bfqq, "del from busy");
164962306a36Sopenharmony_ci
165062306a36Sopenharmony_ci	bfq_clear_bfqq_busy(bfqq);
165162306a36Sopenharmony_ci
165262306a36Sopenharmony_ci	bfqd->busy_queues[bfqq->ioprio_class - 1]--;
165362306a36Sopenharmony_ci
165462306a36Sopenharmony_ci	if (bfqq->wr_coeff > 1)
165562306a36Sopenharmony_ci		bfqd->wr_busy_queues--;
165662306a36Sopenharmony_ci
165762306a36Sopenharmony_ci	bfqg_stats_update_dequeue(bfqq_group(bfqq));
165862306a36Sopenharmony_ci
165962306a36Sopenharmony_ci	bfq_deactivate_bfqq(bfqd, bfqq, true, expiration);
166062306a36Sopenharmony_ci
166162306a36Sopenharmony_ci	if (!bfqq->dispatched) {
166262306a36Sopenharmony_ci		bfq_del_bfqq_in_groups_with_pending_reqs(bfqq);
166362306a36Sopenharmony_ci		/*
166462306a36Sopenharmony_ci		 * Next function is invoked last, because it causes bfqq to be
166562306a36Sopenharmony_ci		 * freed. DO NOT use bfqq after the next function invocation.
166662306a36Sopenharmony_ci		 */
166762306a36Sopenharmony_ci		bfq_weights_tree_remove(bfqq);
166862306a36Sopenharmony_ci	}
166962306a36Sopenharmony_ci}
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_ci/*
167262306a36Sopenharmony_ci * Called when an inactive queue receives a new request.
167362306a36Sopenharmony_ci */
167462306a36Sopenharmony_civoid bfq_add_bfqq_busy(struct bfq_queue *bfqq)
167562306a36Sopenharmony_ci{
167662306a36Sopenharmony_ci	struct bfq_data *bfqd = bfqq->bfqd;
167762306a36Sopenharmony_ci
167862306a36Sopenharmony_ci	bfq_log_bfqq(bfqd, bfqq, "add to busy");
167962306a36Sopenharmony_ci
168062306a36Sopenharmony_ci	bfq_activate_bfqq(bfqd, bfqq);
168162306a36Sopenharmony_ci
168262306a36Sopenharmony_ci	bfq_mark_bfqq_busy(bfqq);
168362306a36Sopenharmony_ci	bfqd->busy_queues[bfqq->ioprio_class - 1]++;
168462306a36Sopenharmony_ci
168562306a36Sopenharmony_ci	if (!bfqq->dispatched) {
168662306a36Sopenharmony_ci		bfq_add_bfqq_in_groups_with_pending_reqs(bfqq);
168762306a36Sopenharmony_ci		if (bfqq->wr_coeff == 1)
168862306a36Sopenharmony_ci			bfq_weights_tree_add(bfqq);
168962306a36Sopenharmony_ci	}
169062306a36Sopenharmony_ci
169162306a36Sopenharmony_ci	if (bfqq->wr_coeff > 1)
169262306a36Sopenharmony_ci		bfqd->wr_busy_queues++;
169362306a36Sopenharmony_ci
169462306a36Sopenharmony_ci	/* Move bfqq to the head of the woken list of its waker */
169562306a36Sopenharmony_ci	if (!hlist_unhashed(&bfqq->woken_list_node) &&
169662306a36Sopenharmony_ci	    &bfqq->woken_list_node != bfqq->waker_bfqq->woken_list.first) {
169762306a36Sopenharmony_ci		hlist_del_init(&bfqq->woken_list_node);
169862306a36Sopenharmony_ci		hlist_add_head(&bfqq->woken_list_node,
169962306a36Sopenharmony_ci			       &bfqq->waker_bfqq->woken_list);
170062306a36Sopenharmony_ci	}
170162306a36Sopenharmony_ci}
1702