[PATCH 2/2] powerpc/pseries/cpuhp: respect current SMT when adding new CPU
From: Laurent Dufour
Date: Fri Mar 31 2023 - 11:39:52 EST
When a new CPU is added, the kernel is activating all its threads. This
leads to weird, but functional, result when adding CPU on a SMT 4 system
for instance.
Here the newly added CPU 1 has 8 threads while the other one has 4 threads
active (system has been booted with the 'smt-enabled=4' kernel option):
ltcden3-lp12:~ # ppc64_cpu --info
Core 0: 0* 1* 2* 3* 4 5 6 7
Core 1: 8* 9* 10* 11* 12* 13* 14* 15*
We rely on the newly pseries_smt value which should be updated when
changing the SMT level by ppc64_cpu --smt=x and at boot time using the
smt-enabled kernel option.
This way on a LPAR running in SMT=4, newly added CPU will be running 4
threads, which is what a end user would expect.
Cc: Srikar Dronamraju <srikar@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Laurent Dufour <ldufour@xxxxxxxxxxxxx>
---
arch/powerpc/platforms/pseries/hotplug-cpu.c | 18 +++++++++++++-----
arch/powerpc/platforms/pseries/smp.c | 2 +-
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 1a3cb313976a..e623ed8649b3 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -382,7 +382,7 @@ static int dlpar_online_cpu(struct device_node *dn)
{
int rc = 0;
unsigned int cpu;
- int len, nthreads, i;
+ int len, nthreads, i, smt;
const __be32 *intserv;
u32 thread;
@@ -392,6 +392,11 @@ static int dlpar_online_cpu(struct device_node *dn)
nthreads = len / sizeof(u32);
+ smt = READ_ONCE(pseries_smt);
+ /* We should online at least one thread */
+ if (smt < 1)
+ smt = 1;
+
cpu_maps_update_begin();
for (i = 0; i < nthreads; i++) {
thread = be32_to_cpu(intserv[i]);
@@ -400,10 +405,13 @@ static int dlpar_online_cpu(struct device_node *dn)
continue;
cpu_maps_update_done();
find_and_update_cpu_nid(cpu);
- rc = device_online(get_cpu_device(cpu));
- if (rc) {
- dlpar_offline_cpu(dn);
- goto out;
+ /* Don't active CPU over the current SMT setting */
+ if (smt-- > 0) {
+ rc = device_online(get_cpu_device(cpu));
+ if (rc) {
+ dlpar_offline_cpu(dn);
+ goto out;
+ }
}
cpu_maps_update_begin();
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 6c382922f8f3..ef8070651846 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -295,7 +295,7 @@ static ssize_t pseries_smt_store(struct class *class,
return -EINVAL;
}
- pseries_smt = smt;
+ WRITE_ONCE(pseries_smt, smt);
return count;
}
--
2.40.0