aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/topology.c
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2014-05-26 18:19:39 -0400
committerIngo Molnar <mingo@kernel.org>2014-06-05 05:52:30 -0400
commitca8ce3d0b144c318a5a9ce99649053e9029061ea (patch)
treec16f890097b570d2703c1295831470c17937ee10 /arch/arm/kernel/topology.c
parentced549fa5fc1fdaf7fac93894dc673092eb3dc20 (diff)
sched: Final power vs. capacity cleanups
It is better not to think about compute capacity as being equivalent to "CPU power". The upcoming "power aware" scheduler work may create confusion with the notion of energy consumption if "power" is used too liberally. This contains the architecture visible changes. Incidentally, only ARM takes advantage of the available pow^H^H^Hcapacity scaling hooks and therefore those changes outside kernel/sched/ are confined to one ARM specific file. The default arch_scale_smt_power() hook is not overridden by anyone. Replacements are as follows: arch_scale_freq_power --> arch_scale_freq_capacity arch_scale_smt_power --> arch_scale_smt_capacity SCHED_POWER_SCALE --> SCHED_CAPACITY_SCALE SCHED_POWER_SHIFT --> SCHED_CAPACITY_SHIFT The local usage of "power" in arch/arm/kernel/topology.c is also changed to "capacity" as appropriate. Signed-off-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Cc: Vincent Guittot <vincent.guittot@linaro.org> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Morten Rasmussen <morten.rasmussen@arm.com> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Cc: linaro-kernel@lists.linaro.org Cc: Arnd Bergmann <arnd@arndb.de> Cc: Dietmar Eggemann <dietmar.eggemann@arm.com> Cc: Grant Likely <grant.likely@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mark Brown <broonie@linaro.org> Cc: Rob Herring <robh+dt@kernel.org> Cc: Russell King <linux@arm.linux.org.uk> Cc: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com> Cc: Vincent Guittot <vincent.guittot@linaro.org> Cc: devicetree@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Link: http://lkml.kernel.org/n/tip-48zba9qbznvglwelgq2cfygh@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/arm/kernel/topology.c')
-rw-r--r--arch/arm/kernel/topology.c54
1 files changed, 27 insertions, 27 deletions
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index 71e1fec6d31a..d42a7db22236 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -26,30 +26,30 @@
26#include <asm/topology.h> 26#include <asm/topology.h>
27 27
28/* 28/*
29 * cpu power scale management 29 * cpu capacity scale management
30 */ 30 */
31 31
32/* 32/*
33 * cpu power table 33 * cpu capacity table
34 * This per cpu data structure describes the relative capacity of each core. 34 * This per cpu data structure describes the relative capacity of each core.
35 * On a heteregenous system, cores don't have the same computation capacity 35 * On a heteregenous system, cores don't have the same computation capacity
36 * and we reflect that difference in the cpu_power field so the scheduler can 36 * and we reflect that difference in the cpu_capacity field so the scheduler
37 * take this difference into account during load balance. A per cpu structure 37 * can take this difference into account during load balance. A per cpu
38 * is preferred because each CPU updates its own cpu_power field during the 38 * structure is preferred because each CPU updates its own cpu_capacity field
39 * load balance except for idle cores. One idle core is selected to run the 39 * during the load balance except for idle cores. One idle core is selected
40 * rebalance_domains for all idle cores and the cpu_power can be updated 40 * to run the rebalance_domains for all idle cores and the cpu_capacity can be
41 * during this sequence. 41 * updated during this sequence.
42 */ 42 */
43static DEFINE_PER_CPU(unsigned long, cpu_scale); 43static DEFINE_PER_CPU(unsigned long, cpu_scale);
44 44
45unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu) 45unsigned long arch_scale_freq_capacity(struct sched_domain *sd, int cpu)
46{ 46{
47 return per_cpu(cpu_scale, cpu); 47 return per_cpu(cpu_scale, cpu);
48} 48}
49 49
50static void set_power_scale(unsigned int cpu, unsigned long power) 50static void set_capacity_scale(unsigned int cpu, unsigned long capacity)
51{ 51{
52 per_cpu(cpu_scale, cpu) = power; 52 per_cpu(cpu_scale, cpu) = capacity;
53} 53}
54 54
55#ifdef CONFIG_OF 55#ifdef CONFIG_OF
@@ -62,11 +62,11 @@ struct cpu_efficiency {
62 * Table of relative efficiency of each processors 62 * Table of relative efficiency of each processors
63 * The efficiency value must fit in 20bit and the final 63 * The efficiency value must fit in 20bit and the final
64 * cpu_scale value must be in the range 64 * cpu_scale value must be in the range
65 * 0 < cpu_scale < 3*SCHED_POWER_SCALE/2 65 * 0 < cpu_scale < 3*SCHED_CAPACITY_SCALE/2
66 * in order to return at most 1 when DIV_ROUND_CLOSEST 66 * in order to return at most 1 when DIV_ROUND_CLOSEST
67 * is used to compute the capacity of a CPU. 67 * is used to compute the capacity of a CPU.
68 * Processors that are not defined in the table, 68 * Processors that are not defined in the table,
69 * use the default SCHED_POWER_SCALE value for cpu_scale. 69 * use the default SCHED_CAPACITY_SCALE value for cpu_scale.
70 */ 70 */
71static const struct cpu_efficiency table_efficiency[] = { 71static const struct cpu_efficiency table_efficiency[] = {
72 {"arm,cortex-a15", 3891}, 72 {"arm,cortex-a15", 3891},
@@ -83,9 +83,9 @@ static unsigned long middle_capacity = 1;
83 * Iterate all CPUs' descriptor in DT and compute the efficiency 83 * Iterate all CPUs' descriptor in DT and compute the efficiency
84 * (as per table_efficiency). Also calculate a middle efficiency 84 * (as per table_efficiency). Also calculate a middle efficiency
85 * as close as possible to (max{eff_i} - min{eff_i}) / 2 85 * as close as possible to (max{eff_i} - min{eff_i}) / 2
86 * This is later used to scale the cpu_power field such that an 86 * This is later used to scale the cpu_capacity field such that an
87 * 'average' CPU is of middle power. Also see the comments near 87 * 'average' CPU is of middle capacity. Also see the comments near
88 * table_efficiency[] and update_cpu_power(). 88 * table_efficiency[] and update_cpu_capacity().
89 */ 89 */
90static void __init parse_dt_topology(void) 90static void __init parse_dt_topology(void)
91{ 91{
@@ -141,15 +141,15 @@ static void __init parse_dt_topology(void)
141 * cpu_scale because all CPUs have the same capacity. Otherwise, we 141 * cpu_scale because all CPUs have the same capacity. Otherwise, we
142 * compute a middle_capacity factor that will ensure that the capacity 142 * compute a middle_capacity factor that will ensure that the capacity
143 * of an 'average' CPU of the system will be as close as possible to 143 * of an 'average' CPU of the system will be as close as possible to
144 * SCHED_POWER_SCALE, which is the default value, but with the 144 * SCHED_CAPACITY_SCALE, which is the default value, but with the
145 * constraint explained near table_efficiency[]. 145 * constraint explained near table_efficiency[].
146 */ 146 */
147 if (4*max_capacity < (3*(max_capacity + min_capacity))) 147 if (4*max_capacity < (3*(max_capacity + min_capacity)))
148 middle_capacity = (min_capacity + max_capacity) 148 middle_capacity = (min_capacity + max_capacity)
149 >> (SCHED_POWER_SHIFT+1); 149 >> (SCHED_CAPACITY_SHIFT+1);
150 else 150 else
151 middle_capacity = ((max_capacity / 3) 151 middle_capacity = ((max_capacity / 3)
152 >> (SCHED_POWER_SHIFT-1)) + 1; 152 >> (SCHED_CAPACITY_SHIFT-1)) + 1;
153 153
154} 154}
155 155
@@ -158,20 +158,20 @@ static void __init parse_dt_topology(void)
158 * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the 158 * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
159 * function returns directly for SMP system. 159 * function returns directly for SMP system.
160 */ 160 */
161static void update_cpu_power(unsigned int cpu) 161static void update_cpu_capacity(unsigned int cpu)
162{ 162{
163 if (!cpu_capacity(cpu)) 163 if (!cpu_capacity(cpu))
164 return; 164 return;
165 165
166 set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity); 166 set_capacity_scale(cpu, cpu_capacity(cpu) / middle_capacity);
167 167
168 printk(KERN_INFO "CPU%u: update cpu_power %lu\n", 168 printk(KERN_INFO "CPU%u: update cpu_capacity %lu\n",
169 cpu, arch_scale_freq_power(NULL, cpu)); 169 cpu, arch_scale_freq_capacity(NULL, cpu));
170} 170}
171 171
172#else 172#else
173static inline void parse_dt_topology(void) {} 173static inline void parse_dt_topology(void) {}
174static inline void update_cpu_power(unsigned int cpuid) {} 174static inline void update_cpu_capacity(unsigned int cpuid) {}
175#endif 175#endif
176 176
177 /* 177 /*
@@ -267,7 +267,7 @@ void store_cpu_topology(unsigned int cpuid)
267 267
268 update_siblings_masks(cpuid); 268 update_siblings_masks(cpuid);
269 269
270 update_cpu_power(cpuid); 270 update_cpu_capacity(cpuid);
271 271
272 printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", 272 printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
273 cpuid, cpu_topology[cpuid].thread_id, 273 cpuid, cpu_topology[cpuid].thread_id,
@@ -297,7 +297,7 @@ void __init init_cpu_topology(void)
297{ 297{
298 unsigned int cpu; 298 unsigned int cpu;
299 299
300 /* init core mask and power*/ 300 /* init core mask and capacity */
301 for_each_possible_cpu(cpu) { 301 for_each_possible_cpu(cpu) {
302 struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]); 302 struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]);
303 303
@@ -307,7 +307,7 @@ void __init init_cpu_topology(void)
307 cpumask_clear(&cpu_topo->core_sibling); 307 cpumask_clear(&cpu_topo->core_sibling);
308 cpumask_clear(&cpu_topo->thread_sibling); 308 cpumask_clear(&cpu_topo->thread_sibling);
309 309
310 set_power_scale(cpu, SCHED_POWER_SCALE); 310 set_capacity_scale(cpu, SCHED_CAPACITY_SCALE);
311 } 311 }
312 smp_wmb(); 312 smp_wmb();
313 313