Add percpu coregroup maps and masks to create coregroup domain. If a coregroup doesn't exist, the coregroup domain will be degenerated in favour of SMT/CACHE domain.
Cc: linuxppc-dev <linuxppc-dev@lists.ozlabs.org> Cc: Michael Ellerman <micha...@au1.ibm.com> Cc: Nick Piggin <npig...@au1.ibm.com> Cc: Oliver OHalloran <olive...@au1.ibm.com> Cc: Nathan Lynch <nath...@linux.ibm.com> Cc: Michael Neuling <mi...@linux.ibm.com> Cc: Anton Blanchard <an...@au1.ibm.com> Cc: Gautham R Shenoy <e...@linux.vnet.ibm.com> Cc: Vaidyanathan Srinivasan <sva...@linux.ibm.com> Signed-off-by: Srikar Dronamraju <sri...@linux.vnet.ibm.com> --- arch/powerpc/include/asm/topology.h | 10 ++++++++ arch/powerpc/kernel/smp.c | 37 +++++++++++++++++++++++++++++ arch/powerpc/mm/numa.c | 5 ++++ 3 files changed, 52 insertions(+) diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 2db7ba789720..34812c35018e 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -98,6 +98,7 @@ extern int stop_topology_update(void); extern int prrn_is_enabled(void); extern int find_and_online_cpu_nid(int cpu); extern int timed_topology_update(int nsecs); +extern int cpu_to_coregroup_id(int cpu); #else static inline int start_topology_update(void) { @@ -120,6 +121,15 @@ static inline int timed_topology_update(int nsecs) return 0; } +static inline int cpu_to_coregroup_id(int cpu) +{ +#ifdef CONFIG_SMP + return cpu_to_core_id(cpu); +#else + return 0; +#endif +} + #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */ #include <asm-generic/topology.h> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index ef19eeccd21e..bb25c13bbb79 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -80,6 +80,7 @@ DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); DEFINE_PER_CPU(cpumask_var_t, cpu_smallcore_map); DEFINE_PER_CPU(cpumask_var_t, cpu_l2_cache_map); DEFINE_PER_CPU(cpumask_var_t, cpu_core_map); +DEFINE_PER_CPU(cpumask_var_t, cpu_coregroup_map); EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); EXPORT_PER_CPU_SYMBOL(cpu_l2_cache_map); @@ -91,6 +92,7 @@ enum { smt_idx, #endif bigcore_idx, + mc_idx, die_idx, }; @@ -869,6 +871,21 @@ static const struct cpumask *smallcore_smt_mask(int cpu) } #endif +static struct cpumask *cpu_coregroup_mask(int cpu) +{ + return per_cpu(cpu_coregroup_map, cpu); +} + +static bool has_coregroup_support(void) +{ + return coregroup_enabled; +} + +static const struct cpumask *cpu_mc_mask(int cpu) +{ + return cpu_coregroup_mask(cpu); +} + static const struct cpumask *cpu_bigcore_mask(int cpu) { return cpu_core_mask(cpu); @@ -879,6 +896,7 @@ static struct sched_domain_topology_level powerpc_topology[] = { { cpu_smt_mask, powerpc_smt_flags, SD_INIT_NAME(SMT) }, #endif { cpu_bigcore_mask, SD_INIT_NAME(BIGCORE) }, + { cpu_mc_mask, SD_INIT_NAME(MC) }, { cpu_cpu_mask, SD_INIT_NAME(DIE) }, { NULL, }, }; @@ -933,6 +951,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) GFP_KERNEL, node); zalloc_cpumask_var_node(&per_cpu(cpu_core_map, cpu), GFP_KERNEL, node); + if (has_coregroup_support()) + zalloc_cpumask_var_node(&per_cpu(cpu_coregroup_map, cpu), + GFP_KERNEL, node); + #ifdef CONFIG_NEED_MULTIPLE_NODES /* * numa_node_id() works after this. @@ -950,6 +972,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) cpumask_set_cpu(boot_cpuid, cpu_l2_cache_mask(boot_cpuid)); cpumask_set_cpu(boot_cpuid, cpu_core_mask(boot_cpuid)); + if (has_coregroup_support()) + cpumask_set_cpu(boot_cpuid, cpu_coregroup_mask(boot_cpuid)); + else + powerpc_topology[mc_idx].mask = cpu_bigcore_mask; + init_big_cores(); if (has_big_cores) { cpumask_set_cpu(boot_cpuid, @@ -1241,6 +1268,8 @@ static void remove_cpu_from_masks(int cpu) set_cpus_unrelated(cpu, i, cpu_sibling_mask); if (has_big_cores) set_cpus_unrelated(cpu, i, cpu_smallcore_mask); + if (has_coregroup_support()) + set_cpus_unrelated(cpu, i, cpu_coregroup_mask); } } #endif @@ -1301,6 +1330,14 @@ static void add_cpu_to_masks(int cpu) add_cpu_to_smallcore_masks(cpu); update_mask_by_l2(cpu, cpu_l2_cache_mask); + if (has_coregroup_support()) { + cpumask_set_cpu(cpu, cpu_coregroup_mask(cpu)); + for_each_cpu(i, cpu_online_mask) { + if (cpu_to_coregroup_id(cpu) == cpu_to_coregroup_id(i)) + set_cpus_related(cpu, i, cpu_coregroup_mask); + } + } + if (pkg_id == -1) { struct cpumask *(*mask)(int) = cpu_sibling_mask; diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index a43eab455be4..d9ab9da85eab 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1695,6 +1695,11 @@ static const struct proc_ops topology_proc_ops = { .proc_release = single_release, }; +int cpu_to_coregroup_id(int cpu) +{ + return cpu_to_core_id(cpu); +} + static int topology_update_init(void) { start_topology_update(); -- 2.17.1