Anton Blanchard reported that his 4096 vcpu KVM guest took around 30 minutes to boot. He also analyzed it to the time taken to iterate while setting the cpu_core_mask.
Further analysis shows that cpu_core_mask and cpu_cpu_mask for any CPU would be equal on Power. However updating cpu_core_mask took forever to update as its a per cpu cpumask variable. Instead cpu_cpu_mask was a per NODE /per DIE cpumask that was shared by all the respective CPUs. Also cpu_cpu_mask is needed from a scheduler perspective. However cpu_core_map is an exported symbol. Hence stop updating cpu_core_map and make it point to cpu_cpu_mask. Cc: linuxppc-dev <linuxppc-dev@lists.ozlabs.org> Cc: LKML <linux-ker...@vger.kernel.org> Cc: Michael Ellerman <m...@ellerman.id.au> Cc: Nicholas Piggin <npig...@gmail.com> Cc: Anton Blanchard <an...@ozlabs.org> Cc: Oliver O'Halloran <ooh...@gmail.com> Cc: Nathan Lynch <nath...@linux.ibm.com> Cc: Michael Neuling <mi...@neuling.org> Cc: Gautham R Shenoy <e...@linux.vnet.ibm.com> Cc: Satheesh Rajendran <sathn...@linux.vnet.ibm.com> Cc: Ingo Molnar <mi...@kernel.org> Cc: Peter Zijlstra <pet...@infradead.org> Cc: Valentin Schneider <valentin.schnei...@arm.com> Signed-off-by: Srikar Dronamraju <sri...@linux.vnet.ibm.com> --- arch/powerpc/include/asm/smp.h | 5 ----- arch/powerpc/kernel/smp.c | 33 +++++++-------------------------- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 5bdc17a7049f..cf6e7c7be62b 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -119,11 +119,6 @@ static inline struct cpumask *cpu_sibling_mask(int cpu) return per_cpu(cpu_sibling_map, cpu); } -static inline struct cpumask *cpu_core_mask(int cpu) -{ - return per_cpu(cpu_core_map, cpu); -} - static inline struct cpumask *cpu_l2_cache_mask(int cpu) { return per_cpu(cpu_l2_cache_map, cpu); diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 95f0bf72e283..8c28e1b4957b 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -957,12 +957,17 @@ void __init smp_prepare_cpus(unsigned int max_cpus) local_memory_node(numa_cpu_lookup_table[cpu])); } #endif + /* + * cpu_core_map is no more updated and exists only since + * its been exported for long. It only will have a snapshot + * of cpu_cpu_mask. + */ + cpumask_copy(per_cpu(cpu_core_map, cpu), cpu_cpu_mask(cpu)); } /* Init the cpumasks so the boot CPU is related to itself */ cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid)); 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)); @@ -1251,9 +1256,7 @@ static void remove_cpu_from_masks(int cpu) { int i; - /* NB: cpu_core_mask is a superset of the others */ - for_each_cpu(i, cpu_core_mask(cpu)) { - set_cpus_unrelated(cpu, i, cpu_core_mask); + for_each_cpu(i, cpu_cpu_mask(cpu)) { set_cpus_unrelated(cpu, i, cpu_l2_cache_mask); set_cpus_unrelated(cpu, i, cpu_sibling_mask); if (has_big_cores) @@ -1303,7 +1306,6 @@ EXPORT_SYMBOL_GPL(get_physical_package_id); static void add_cpu_to_masks(int cpu) { int first_thread = cpu_first_thread_sibling(cpu); - int pkg_id = get_physical_package_id(cpu); int i; /* @@ -1311,7 +1313,6 @@ static void add_cpu_to_masks(int cpu) * add it to it's own thread sibling mask. */ cpumask_set_cpu(cpu, cpu_sibling_mask(cpu)); - cpumask_set_cpu(cpu, cpu_core_mask(cpu)); for (i = first_thread; i < first_thread + threads_per_core; i++) if (cpu_online(i)) @@ -1333,26 +1334,6 @@ static void add_cpu_to_masks(int cpu) set_cpus_related(cpu, i, cpu_coregroup_mask); } } - - if (pkg_id == -1) { - struct cpumask *(*mask)(int) = cpu_sibling_mask; - - /* - * Copy the sibling mask into core sibling mask and - * mark any CPUs on the same chip as this CPU. - */ - if (shared_caches) - mask = cpu_l2_cache_mask; - - for_each_cpu(i, mask(cpu)) - set_cpus_related(cpu, i, cpu_core_mask); - - return; - } - - for_each_cpu(i, cpu_online_mask) - if (get_physical_package_id(i) == pkg_id) - set_cpus_related(cpu, i, cpu_core_mask); } /* Activate a secondary processor. */ -- 2.17.1