| From | Morten Rasmussen <> | Subject | [RFCv3 PATCH 36/48] sched: Count number of shallower idle-states in struct sched_group_energy | Date | Wed, 4 Feb 2015 18:31:13 +0000 |
| |
cpuidle associates all idle-states with each cpu while the energy model associates them with the sched_group covering the cpus coordinating entry to the idle-state. To get idle-state power consumption it is therefore necessary to translate from cpuidle idle-state index to energy model index. For this purpose it is helpful to know how many idle-states that are listed in lower level sched_groups (in struct sched_group_energy).
cc: Ingo Molnar <mingo@redhat.com> cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Morten Rasmussen <morten.rasmussen@arm.com> --- include/linux/sched.h | 1 + kernel/sched/core.c | 12 ++++++++++++ 2 files changed, 13 insertions(+)
diff --git a/include/linux/sched.h b/include/linux/sched.h index 78b6eb7..f984b4e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -958,6 +958,7 @@ struct sched_group_energy { atomic_t ref; unsigned int nr_idle_states; /* number of idle states */ struct idle_state *idle_states; /* ptr to idle state array */ + unsigned int idle_states_below; /* Number idle states in lower groups */ unsigned int nr_cap_states; /* number of capacity states */ struct capacity_state *cap_states; /* ptr to capacity state array */ }; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index e47febf..4f52c2e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6075,6 +6075,7 @@ static void init_sched_energy(int cpu, struct sched_domain *sd, struct sched_group_energy *energy = sg->sge; sched_domain_energy_f fn = tl->energy; struct cpumask *mask = sched_group_cpus(sg); + int idle_states_below = 0; if (!fn || !fn(cpu)) return; @@ -6082,9 +6083,20 @@ static void init_sched_energy(int cpu, struct sched_domain *sd, if (cpumask_weight(mask) > 1) check_sched_energy_data(cpu, fn, mask); + /* Figure out the number of true cpuidle states below current group */ + sd = sd->child; + for_each_lower_domain(sd) { + idle_states_below += sd->groups->sge->nr_idle_states; + + /* Disregard non-cpuidle 'active' idle states */ + if (sd->child) + idle_states_below--; + } + energy->nr_idle_states = fn(cpu)->nr_idle_states; memcpy(energy->idle_states, fn(cpu)->idle_states, energy->nr_idle_states*sizeof(struct idle_state)); + energy->idle_states_below = idle_states_below; energy->nr_cap_states = fn(cpu)->nr_cap_states; memcpy(energy->cap_states, fn(cpu)->cap_states, energy->nr_cap_states*sizeof(struct capacity_state)); -- 1.9.1
|