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)
committerPunit Agrawal <punit.agrawal@arm.com>
Mon, 21 Mar 2016 12:34:30 +0000 (12:34 +0000)
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>
kernel/sched/fair.c

index 3cfb4be3d88fd83f86bf9a3087d8e92a43f4f866..c11bc73929163a879d5b94d638833dcc0c550f79 100644 (file)
@@ -4815,6 +4815,20 @@ static int find_new_capacity(struct energy_env *eenv,
        return 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_cpus(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
@@ -4867,7 +4881,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;
@@ -4875,11 +4890,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_LOAD_SCALE-group_util) * sg->sge->idle_states[0].power)
-                                                                               >> SCHED_CAPACITY_SHIFT;
+                                                               >> SCHED_CAPACITY_SHIFT;
+                               sg_idle_energy = ((SCHED_LOAD_SCALE-group_util)
+                                                               * sg->sge->idle_states[idle_idx].power)
+                                                               >> SCHED_CAPACITY_SHIFT;
 
                                total_energy += sg_busy_energy + sg_idle_energy;