sched: Determine the current sched_group idle-state
authorDietmar Eggemann <dietmar.eggemann@arm.com>
Tue, 27 Jan 2015 14:04:17 +0000 (14:04 +0000)
committerLukasz Luba <l.luba@partner.samsung.com>
Mon, 10 Sep 2018 08:20:55 +0000 (10:20 +0200)
To estimate the energy consumption of a sched_group in
sched_group_energy() it is necessary to know which idle-state the group
is in when it is idle. For now, it is assumed that this is the current
idle-state (though it might be wrong). Based on the individual cpu
idle-states group_idle_state() finds the group idle-state.

cc: Ingo Molnar <mingo@redhat.com>
cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Morten Rasmussen <morten.rasmussen@arm.com>
Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Signed-off-by: Lukasz Luba <l.luba@partner.samsung.com>
kernel/sched/fair.c

index 40b47d422bf520d53c746b9e86ef3970c3cb05bd..26f80f30dee8d498c3e7a4a0e6330987d1bee03e 100644 (file)
@@ -5759,6 +5759,20 @@ static int find_new_capacity(struct energy_env *eenv,
        return eenv->cap_idx;
 }
 
+static int group_idle_state(struct sched_group *sg)
+{
+       int i, state = INT_MAX;
+
+       /* Find the shallowest idle state in the sched group. */
+       for_each_cpu(i, sched_group_span(sg))
+               state = min(state, idle_get_state_idx(cpu_rq(i)));
+
+       /* Take non-cpuidle idling into account (active idle/arch_cpu_idle()) */
+       state++;
+
+       return state;
+}
+
 /*
  * sched_group_energy(): Computes the absolute energy consumption of cpus
  * belonging to the sched_group including shared resources shared only by
@@ -5811,7 +5825,8 @@ static int sched_group_energy(struct energy_env *eenv)
 
                        do {
                                unsigned long group_util;
-                               int sg_busy_energy, sg_idle_energy, cap_idx;
+                               int sg_busy_energy, sg_idle_energy;
+                               int cap_idx, idle_idx;
 
                                if (sg_shared_cap && sg_shared_cap->group_weight >= sg->group_weight)
                                        eenv->sg_cap = sg_shared_cap;
@@ -5819,11 +5834,13 @@ static int sched_group_energy(struct energy_env *eenv)
                                        eenv->sg_cap = sg;
 
                                cap_idx = find_new_capacity(eenv, sg->sge);
+                               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_idle_energy = ((SCHED_CAPACITY_SCALE-group_util) * sg->sge->idle_states[0].power)
-                                                                               >> SCHED_CAPACITY_SHIFT;
+                                                               >> SCHED_CAPACITY_SHIFT;
+                               sg_idle_energy = ((SCHED_CAPACITY_SCALE-group_util)
+                                                               * sg->sge->idle_states[idle_idx].power)
+                                                               >> SCHED_CAPACITY_SHIFT;
 
                                total_energy += sg_busy_energy + sg_idle_energy;