Tune arch_scale_core_capacity for powerpc architecture by scaling capacity w.r.t to the number of online SMT in the core such that for SMT-4, core capacity is 1.5x the capacity of sibling thread.
Signed-off-by: Parth Shah <pa...@linux.ibm.com> --- arch/powerpc/include/asm/topology.h | 4 ++++ arch/powerpc/kernel/smp.c | 33 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index f85e2b01c3df..1c777ee67180 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -132,6 +132,10 @@ static inline void shared_proc_topology_init(void) {} #define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) #define topology_core_id(cpu) (cpu_to_core_id(cpu)) +#define arch_scale_core_capacity powerpc_scale_core_capacity + +unsigned long powerpc_scale_core_capacity(int first_smt, + unsigned long smt_cap); int dlpar_cpu_readd(int cpu); #endif diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index ea6adbf6a221..149a3fbf8ed3 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -1169,6 +1169,39 @@ static void remove_cpu_from_masks(int cpu) } #endif +#ifdef CONFIG_SCHED_SMT +/* + * Calculate capacity of a core based on the active threads in the core + * Scale the capacity of first SM-thread based on total number of + * active threads in the respective smt_mask. + * + * The scaling is done such that for + * SMT-4, core_capacity = 1.5x first_cpu_capacity + * and for SMT-8, core_capacity multiplication factor is 2x + * + * So, core_capacity multiplication factor = (1 + smt_mode*0.125) + * + * @first_cpu: First/any CPU id in the core + * @cap: Capacity of the first_cpu + */ +unsigned long powerpc_scale_core_capacity(int first_cpu, + unsigned long cap) +{ + struct cpumask select_idles; + struct cpumask *cpus = &select_idles; + int cpu, smt_mode = 0; + + cpumask_and(cpus, cpu_smt_mask(first_cpu), cpu_online_mask); + + /* Find SMT mode from active SM-threads */ + for_each_cpu(cpu, cpus) + smt_mode++; + + /* Scale core capacity based on smt mode */ + return smt_mode == 1 ? cap : ((cap * smt_mode) >> 3) + cap; +} +#endif + static inline void add_cpu_to_smallcore_masks(int cpu) { struct cpumask *this_l1_cache_map = per_cpu(cpu_l1_cache_map, cpu); -- 2.17.1