aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Bellasi <patrick.bellasi@arm.com>2016-01-14 18:35:13 +0000
committerPunit Agrawal <punit.agrawal@arm.com>2016-03-21 14:57:36 +0000
commit81cc39cc812f53517f0bf4881795e2917aace6c5 (patch)
tree2695cd467cf3d1f23838d88eb60d5759da63c33a
parentaa0c021706f3049cca12f22bdaca4ce56157e056 (diff)
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>
-rw-r--r--kernel/sched/fair.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index f582d58daea5..3b80ad01aa8b 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4706,6 +4706,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;
};
/*
@@ -4872,6 +4882,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)
@@ -4920,6 +4946,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)
@@ -4941,13 +4969,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;
}
/*