From 4e480c5d43dc3cee5c0b7664d0ee394d1206d994 Mon Sep 17 00:00:00 2001 From: Juri Lelli Date: Thu, 30 Apr 2015 11:53:48 +0100 Subject: [PATCH 69/92] arm64: Cpu invariant scheduler load-tracking and capacity support Provides the scheduler with a cpu scaling correction factor for more accurate load-tracking and cpu capacity handling. The Energy Model (EM) (in fact the capacity value of the last element of the capacity states vector of the core (MC) level sched_group_energy structure) is used as the source for this cpu scaling factor. The cpu capacity value depends on the micro-architecture and the maximum frequency of the cpu. The maximum frequency part should not be confused with the frequency invariant scheduler load-tracking support which deals with frequency related scaling due to DFVS functionality. Signed-off-by: Juri Lelli Signed-off-by: Dietmar Eggemann (cherry picked from commit ea98c1ac6d9b31033caa1f29ed1b8b707f437ae8) Signed-off-by: Gaku Inami --- arch/arm64/kernel/topology.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index a75db2b..761fcb6 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -172,12 +172,17 @@ static void __init parse_cpu_capacity(struct device_node *cpu_node, int cpu) } } +static const struct sched_group_energy * const cpu_core_energy(int cpu); + static void normalize_cpu_capacity(void) { u64 capacity; int cpu; bool asym = false; + if (cpu_core_energy(0)) + return; + if (!raw_capacity || cap_parsing_failed) return; @@ -667,6 +672,26 @@ static int cpu_coregroup_flags(void) return mc_flags; } +static void update_cpu_capacity(unsigned int cpu) +{ + unsigned long capacity; + int max_cap_idx; + + if (!cpu_core_energy(cpu)) + return; + + max_cap_idx = cpu_core_energy(cpu)->nr_cap_states - 1; + capacity = cpu_core_energy(cpu)->cap_states[max_cap_idx].cap; + + set_capacity_scale(cpu, capacity); + + if (capacity < SCHED_CAPACITY_SCALE) + asym_cpucap = true; + + pr_info("CPU%d: update cpu_capacity %lu\n", + cpu, arch_scale_cpu_capacity(NULL, cpu)); +} + static void update_siblings_masks(unsigned int cpuid) { struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; @@ -728,6 +753,7 @@ void store_cpu_topology(unsigned int cpuid) topology_populated: update_siblings_masks(cpuid); + update_cpu_capacity(cpuid); } static void __init reset_cpu_topology(void) -- 1.9.1