In old code the energy calculation results are right shifted by SCHED_CAPACITY_SHIFT, so this essentially decreases resolution for the calculation. After applied patch "sched/fair: select candidate CPUs by cluster basis" it introduces many times energy comparison between one little core and one big core. But there have many times wrongly task placement on big core, and this is caused by the resolution issue.
Let's use Juno-r2 modeling parameters as an example:
Capacity Power CA53 267 37 CA72 501 174
Below is one case for utilization of task and CPUs:
task_util(p)=2 cpu_util(src_cpu::ca53)=805; cpu_util(src_cpu::ca53)`=797; cpu_util(dst_cpu::ca72)=12; cpu_util(dst_cpu::ca72)`=16; ^ ^ - before task migration - after task migration
So if compare energy difference for task 'p' from 'src_cpu::ca53' to 'dst_cpu::ca72' then we can see if task migrate to 'dst_cpu:ca72' it can save energy '1'. Finally task 'p' was wrongly placed on big core.
energy_delta(src_cpu::ca53) = (797 * 37) / 1024 - (805 * 37) / 1024 = -1
energy_delta(dst_cpu::ca72) = (16 * 174) / 1024 - (12 * 174) / 1024 = 0
This patch removes right shifting SCHED_CAPACITY_SHIFT to increase calculation resolution. After applied this patch, it can clearly fix upper case, the energy calculation is as below:
energy_delta(src_cpu::ca53) = (797 * 37) - (805 * 37) = -296
energy_delta(dst_cpu::ca72) = (16 * 174) - (12 * 174) = 696
Signed-off-by: Leo Yan leo.yan@linaro.org --- kernel/sched/fair.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 0486edb..d9a2969 100755 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5487,11 +5487,9 @@ static int sched_group_energy(struct energy_env *eenv)
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) - >> SCHED_CAPACITY_SHIFT; + sg_busy_energy = (group_util * sg->sge->cap_states[cap_idx].power); sg_idle_energy = ((SCHED_LOAD_SCALE-group_util) - * sg->sge->idle_states[idle_idx].power) - >> SCHED_CAPACITY_SHIFT; + * sg->sge->idle_states[idle_idx].power);
total_energy += sg_busy_energy + sg_idle_energy;
@@ -5626,9 +5624,6 @@ normalize_energy(int energy_diff) /* Do scaling using positive numbers to increase the range */ normalized_nrg = (energy_diff < 0) ? -energy_diff : energy_diff;
- /* Scale by energy magnitude */ - normalized_nrg <<= SCHED_CAPACITY_SHIFT; - /* Normalize on max energy for target platform */ normalized_nrg = reciprocal_divide( normalized_nrg, schedtune_target_nrg.rdiv); -- 1.9.1