Anton reported that his 4096 cpu (1024 cores in a socket) was taking too
long to boot. He also analyzed that most of the time was being spent on
updating cpu_core_mask.
Here are some optimizations and fixes to make ppc64_cpu --smt=8/ppc64_cpu
--smt=1 run faster and hence boot the kernel also faster.
Its based on top of my v4 coregroup support patchset.
http://lore.kernel.org/lkml/20200727053230.19753-1-srikar@linux.vnet.ibm.com/t/#u
The first two patches should solve Anton's immediate problem.
On the unofficial patches, Anton reported that the boot time came from 30
mins to 6 seconds. (Basically a high core count in a single socket
configuration). Satheesh also reported similar numbers.
The rest are simple cleanups/optimizations.
Since cpu_core_mask is an exported symbol for a long duration, lets retain
as a snapshot of cpumask_of_node.
Architecture: ppc64le
Byte Order: Little Endian
CPU(s): 160
On-line CPU(s) list: 0-159
Thread(s) per core: 4
Core(s) per socket: 20
Socket(s): 2
NUMA node(s): 2
Model: 2.2 (pvr 004e 1202)
Model name: POWER9, altivec supported
CPU max MHz: 3800.0000
CPU min MHz: 2166.0000
L1d cache: 32K
L1i cache: 32K
L2 cache: 512K
L3 cache: 10240K
NUMA node0 CPU(s): 0-79
NUMA node8 CPU(s): 80-159
without patch (powerpc/next)
[ 0.099347] smp: Bringing up secondary CPUs ...
[ 0.832513] smp: Brought up 2 nodes, 160 CPUs
with powerpc/next + coregroup support patchset
[ 0.099241] smp: Bringing up secondary CPUs ...
[ 0.835627] smp: Brought up 2 nodes, 160 CPUs
with powerpc/next + coregroup + this patchset
[ 0.097232] smp: Bringing up secondary CPUs ...
[ 0.528457] smp: Brought up 2 nodes, 160 CPUs
x ppc64_cpu --smt=1
+ ppc64_cpu --smt=4
without patch
N Min Max Median Avg Stddev
x 100 11.82 17.06 14.01 14.05 1.2665247
+ 100 12.25 16.59 13.86 14.1143 1.164293
with patch
N Min Max Median Avg Stddev
x 100 12.68 16.15 14.24 14.238 0.75489246
+ 100 12.93 15.85 14.35 14.2897 0.60041813
Cc: linuxppc-dev <redacted>
Cc: LKML <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Anton Blanchard <redacted>
Cc: Oliver O'Halloran <oohall@gmail.com>
Cc: Nathan Lynch <redacted>
Cc: Michael Neuling <redacted>
Cc: Gautham R Shenoy <redacted>
Cc: Satheesh Rajendran <redacted>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Valentin Schneider <redacted>
Srikar Dronamraju (7):
powerpc/topology: Update topology_core_cpumask
powerpc/smp: Stop updating cpu_core_mask
powerpc/smp: Remove get_physical_package_id
powerpc/smp: Optimize remove_cpu_from_masks
powerpc/smp: Limit cpus traversed to within a node.
powerpc/smp: Stop passing mask to update_mask_by_l2
powerpc/smp: Depend on cpu_l1_cache_map when adding cpus
arch/powerpc/include/asm/smp.h | 5 --
arch/powerpc/include/asm/topology.h | 7 +--
arch/powerpc/kernel/smp.c | 79 +++++++++--------------------
3 files changed, 24 insertions(+), 67 deletions(-)
--
2.17.1
On Power, cpu_core_mask and cpu_cpu_mask refer to the same set of CPUs.
cpu_cpu_mask is needed by scheduler, hence look at deprecating
cpu_core_mask. Before deleting the cpu_core_mask, ensure its only user
is moved to cpu_cpu_mask.
Cc: linuxppc-dev <redacted>
Cc: LKML <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Anton Blanchard <redacted>
Cc: Oliver O'Halloran <oohall@gmail.com>
Cc: Nathan Lynch <redacted>
Cc: Michael Neuling <redacted>
Cc: Gautham R Shenoy <redacted>
Cc: Satheesh Rajendran <redacted>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Valentin Schneider <redacted>
Signed-off-by: Srikar Dronamraju <redacted>
---
arch/powerpc/include/asm/topology.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 <redacted>
Cc: LKML <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Anton Blanchard <redacted>
Cc: Oliver O'Halloran <oohall@gmail.com>
Cc: Nathan Lynch <redacted>
Cc: Michael Neuling <redacted>
Cc: Gautham R Shenoy <redacted>
Cc: Satheesh Rajendran <redacted>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Valentin Schneider <redacted>
Signed-off-by: Srikar Dronamraju <redacted>
---
arch/powerpc/include/asm/smp.h | 5 -----
arch/powerpc/kernel/smp.c | 33 +++++++--------------------------
2 files changed, 7 insertions(+), 31 deletions(-)
@@ -957,12 +957,17 @@ void __init smp_prepare_cpus(unsigned int max_cpus)local_memory_node(numa_cpu_lookup_table[cpu]));}#endif+/*+*cpu_core_mapisnomoreupdatedandexistsonlysince+*itsbeenexportedforlong.Itonlywillhaveasnapshot+*ofcpu_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){inti;-/* 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)
Now that cpu_core_mask has been removed and topology_core_cpumask has
been updated to use cpu_cpu_mask, we no more need
get_physical_package_id.
Please note get_physical_package_id is an exported symbol. However
it was introduced recently and probably no users outside kernel.
Cc: linuxppc-dev <redacted>
Cc: LKML <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Anton Blanchard <redacted>
Cc: Oliver O'Halloran <oohall@gmail.com>
Cc: Nathan Lynch <redacted>
Cc: Michael Neuling <redacted>
Cc: Gautham R Shenoy <redacted>
Cc: Satheesh Rajendran <redacted>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Valentin Schneider <redacted>
Signed-off-by: Srikar Dronamraju <redacted>
---
arch/powerpc/include/asm/topology.h | 5 -----
arch/powerpc/kernel/smp.c | 20 --------------------
2 files changed, 25 deletions(-)
Currently while offlining a cpu, we iterate through all the cpus in the
DIE to clear sibling, l2_cache and smallcore maps. However if there are
more number of cores in a DIE, we end up spending more time iterating
through cpus which are completely unrelated.
Optimize this by only iterating through lesser but relevant cpumap.
If shared_cache is set, cpu_l2_cache_map should be relevant else
cpu_sibling_map would be relevant.
Cc: linuxppc-dev <redacted>
Cc: LKML <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Anton Blanchard <redacted>
Cc: Oliver O'Halloran <oohall@gmail.com>
Cc: Nathan Lynch <redacted>
Cc: Michael Neuling <redacted>
Cc: Gautham R Shenoy <redacted>
Cc: Satheesh Rajendran <redacted>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Valentin Schneider <redacted>
Signed-off-by: Srikar Dronamraju <redacted>
---
arch/powerpc/kernel/smp.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
All the arch specific topology cpumasks are within a node/die.
However when setting these per cpu cpumasks, system traverses through
all the online cpus. This is redundant.
Reduce the traversal to only cpus that are online in the node to which
the cpu belongs to.
Cc: linuxppc-dev <redacted>
Cc: LKML <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Anton Blanchard <redacted>
Cc: Oliver O'Halloran <oohall@gmail.com>
Cc: Nathan Lynch <redacted>
Cc: Michael Neuling <redacted>
Cc: Gautham R Shenoy <redacted>
Cc: Satheesh Rajendran <redacted>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Valentin Schneider <redacted>
Signed-off-by: Srikar Dronamraju <redacted>
---
arch/powerpc/kernel/smp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Currently on hotplug/hotunplug, the cpu iterates through all the cpus in
its core to find threads in its thread group. However this info is
already captured in cpu_l1_cache_map. Hence we could reduce the
iteration and cleanup add_cpu_to_smallcore_masks function.
Cc: linuxppc-dev <redacted>
Cc: LKML <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Anton Blanchard <redacted>
Cc: Oliver O'Halloran <oohall@gmail.com>
Cc: Nathan Lynch <redacted>
Cc: Michael Neuling <redacted>
Cc: Gautham R Shenoy <redacted>
Cc: Satheesh Rajendran <redacted>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Valentin Schneider <redacted>
Signed-off-by: Srikar Dronamraju <redacted>
---
arch/powerpc/kernel/smp.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
On Mon, Jul 27, 2020 at 01:25:25PM +0530, Srikar Dronamraju wrote:
Anton reported that his 4096 cpu (1024 cores in a socket) was taking too
long to boot. He also analyzed that most of the time was being spent on
updating cpu_core_mask.
Here are some optimizations and fixes to make ppc64_cpu --smt=8/ppc64_cpu
--smt=1 run faster and hence boot the kernel also faster.
Its based on top of my v4 coregroup support patchset.
http://lore.kernel.org/lkml/20200727053230.19753-1-srikar@linux.vnet.ibm.com/t/#u
The first two patches should solve Anton's immediate problem.
On the unofficial patches, Anton reported that the boot time came from 30
mins to 6 seconds. (Basically a high core count in a single socket
configuration). Satheesh also reported similar numbers.
The rest are simple cleanups/optimizations.
Since cpu_core_mask is an exported symbol for a long duration, lets retain
as a snapshot of cpumask_of_node.
boot tested on P9 KVM guest.
without this series:
# dmesg|grep smp
[ 0.066624] smp: Bringing up secondary CPUs ...
[ 347.521264] smp: Brought up 1 node, 2048 CPUs
with this series:
# dmesg|grep smp
[ 0.067744] smp: Bringing up secondary CPUs ...
[ 5.416910] smp: Brought up 1 node, 2048 CPUs
Tested-by: Satheesh Rajendran <redacted>
Regards,
-Satheesh
Architecture: ppc64le
Byte Order: Little Endian
CPU(s): 160
On-line CPU(s) list: 0-159
Thread(s) per core: 4
Core(s) per socket: 20
Socket(s): 2
NUMA node(s): 2
Model: 2.2 (pvr 004e 1202)
Model name: POWER9, altivec supported
CPU max MHz: 3800.0000
CPU min MHz: 2166.0000
L1d cache: 32K
L1i cache: 32K
L2 cache: 512K
L3 cache: 10240K
NUMA node0 CPU(s): 0-79
NUMA node8 CPU(s): 80-159
without patch (powerpc/next)
[ 0.099347] smp: Bringing up secondary CPUs ...
[ 0.832513] smp: Brought up 2 nodes, 160 CPUs
with powerpc/next + coregroup support patchset
[ 0.099241] smp: Bringing up secondary CPUs ...
[ 0.835627] smp: Brought up 2 nodes, 160 CPUs
with powerpc/next + coregroup + this patchset
[ 0.097232] smp: Bringing up secondary CPUs ...
[ 0.528457] smp: Brought up 2 nodes, 160 CPUs
x ppc64_cpu --smt=1
+ ppc64_cpu --smt=4
without patch
N Min Max Median Avg Stddev
x 100 11.82 17.06 14.01 14.05 1.2665247
+ 100 12.25 16.59 13.86 14.1143 1.164293
with patch
N Min Max Median Avg Stddev
x 100 12.68 16.15 14.24 14.238 0.75489246
+ 100 12.93 15.85 14.35 14.2897 0.60041813
Cc: linuxppc-dev <redacted>
Cc: LKML <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Anton Blanchard <redacted>
Cc: Oliver O'Halloran <oohall@gmail.com>
Cc: Nathan Lynch <redacted>
Cc: Michael Neuling <redacted>
Cc: Gautham R Shenoy <redacted>
Cc: Satheesh Rajendran <redacted>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Valentin Schneider <redacted>
Srikar Dronamraju (7):
powerpc/topology: Update topology_core_cpumask
powerpc/smp: Stop updating cpu_core_mask
powerpc/smp: Remove get_physical_package_id
powerpc/smp: Optimize remove_cpu_from_masks
powerpc/smp: Limit cpus traversed to within a node.
powerpc/smp: Stop passing mask to update_mask_by_l2
powerpc/smp: Depend on cpu_l1_cache_map when adding cpus
arch/powerpc/include/asm/smp.h | 5 --
arch/powerpc/include/asm/topology.h | 7 +--
arch/powerpc/kernel/smp.c | 79 +++++++++--------------------
3 files changed, 24 insertions(+), 67 deletions(-)
--
2.17.1