ANDROID: sched/fair: keep track of energy/capacity variations

The current EAS implementation does not allow "to boost" tasks
performances, for example by running them at an higher OPP (or a more
capable CPU), even if that could require a "reasonable" increase in
energy consumption.  To defined how much reasonable is an energy
increase with respect to a required boost value, it is required to
define and compute a trade-off between the expected energy and
performance variations.
However, the current EAS implementation considers only energy variations
while completely disregard the impact on performance for the selection
of a certain schedule candidate.

This patch extends the eenv energy environment to keep track of both
energy and performance deltas which are implied by the activation of a
schedule candidate.
The performance variation is estimated considering the different
capacities of the CPUs in which the task could be scheduled. The idea is
that while running on a CPU with higher capacity (e.g. higher operating
point) the task could (potentially) complete faster and thus get better
performance.

Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com>
Signed-off-by: Andres Oportus <andresoportus@google.com>
This commit is contained in:
Patrick Bellasi
2016-01-14 18:35:13 +00:00
committed by Dmitry Shmidt
parent 9b2b8da324
commit 632905f02f

View File

@@ -5161,6 +5161,16 @@ struct energy_env {
int src_cpu;
int dst_cpu;
int energy;
struct {
int before;
int after;
int diff;
} nrg;
struct {
int before;
int after;
int delta;
} cap;
};
/*
@@ -5327,6 +5337,22 @@ static int sched_group_energy(struct energy_env *eenv)
eenv->sg_cap = sg;
cap_idx = find_new_capacity(eenv, sg->sge);
if (sg->group_weight == 1) {
/* Remove capacity of src CPU (before task move) */
if (eenv->util_delta == 0 &&
cpumask_test_cpu(eenv->src_cpu, sched_group_cpus(sg))) {
eenv->cap.before = sg->sge->cap_states[cap_idx].cap;
eenv->cap.delta -= eenv->cap.before;
}
/* Add capacity of dst CPU (after task move) */
if (eenv->util_delta != 0 &&
cpumask_test_cpu(eenv->dst_cpu, sched_group_cpus(sg))) {
eenv->cap.after = sg->sge->cap_states[cap_idx].cap;
eenv->cap.delta += eenv->cap.after;
}
}
idle_idx = group_idle_state(sg);
group_util = group_norm_util(eenv, sg);
sg_busy_energy = (group_util * sg->sge->cap_states[cap_idx].power)
@@ -5375,6 +5401,8 @@ static int energy_diff(struct energy_env *eenv)
.util_delta = 0,
.src_cpu = eenv->src_cpu,
.dst_cpu = eenv->dst_cpu,
.nrg = { 0, 0, 0 },
.cap = { 0, 0, 0 },
};
if (eenv->src_cpu == eenv->dst_cpu)
@@ -5396,13 +5424,21 @@ static int energy_diff(struct energy_env *eenv)
return 0; /* Invalid result abort */
energy_before += eenv_before.energy;
/* Keep track of SRC cpu (before) capacity */
eenv->cap.before = eenv_before.cap.before;
eenv->cap.delta = eenv_before.cap.delta;
if (sched_group_energy(eenv))
return 0; /* Invalid result abort */
energy_after += eenv->energy;
}
} while (sg = sg->next, sg != sd->groups);
return energy_after-energy_before;
eenv->nrg.before = energy_before;
eenv->nrg.after = energy_after;
eenv->nrg.diff = eenv->nrg.after - eenv->nrg.before;
return eenv->nrg.diff;
}
/*