[PATCH v2] powerpc/smp: poll cpu_callin_map more aggressively in __cpu_up()
Nathan Lynch
nathanl at linux.ibm.com
Thu Jun 30 06:58:52 AEST 2022
It is not necessary to delay or sleep between polls of cpu_callin_map when
waiting for a kicked CPU to come up. We can use spin_until_cond(),
combining the boot and hotplug paths while preserving the intended timeout.
Without the msleep(1) in the hotplug path, the time it takes to online a
CPU on a P9 PowerVM LPAR goes from roughly 30ms to 4ms or less when
exercised via thaw_secondary_cpus().
Signed-off-by: Nathan Lynch <nathanl at linux.ibm.com>
---
Notes:
Changes since v1:
* Do not poll indefinitely; restore the original 5sec timeout
"Benchmark" method, on a LPAR with 24 CPUs:
$ echo processors > /sys/power/pm_test
$ echo mem > /sys/power/state
$ dmesg --reltime | grep -A23 'Enabling non-boot CPUs'
Before:
[ +5.000003] Enabling non-boot CPUs ...
[ +0.047537] CPU1 is up
[ +0.030177] CPU2 is up
[ +0.030082] CPU3 is up
[ +0.030146] CPU4 is up
[ +0.030114] CPU5 is up
[ +0.030108] CPU6 is up
[ +0.030134] CPU7 is up
[ +0.040272] CPU8 is up
[ +0.030352] CPU9 is up
[ +0.030169] CPU10 is up
[ +0.040224] CPU11 is up
[ +0.030186] CPU12 is up
[ +0.030173] CPU13 is up
[ +0.030181] CPU14 is up
[ +0.030179] CPU15 is up
[ +0.030236] CPU16 is up
[ +0.030012] CPU17 is up
[ +0.030188] CPU18 is up
[ +0.030233] CPU19 is up
[ +0.030182] CPU20 is up
[ +0.030160] CPU21 is up
[ +0.030226] CPU22 is up
[ +0.030125] CPU23 is up
After:
[ +5.000004] Enabling non-boot CPUs ...
[ +0.000956] CPU1 is up
[ +0.000568] CPU2 is up
[ +0.000682] CPU3 is up
[ +0.000836] CPU4 is up
[ +0.000914] CPU5 is up
[ +0.001054] CPU6 is up
[ +0.001184] CPU7 is up
[ +0.001533] CPU8 is up
[ +0.001779] CPU9 is up
[ +0.001935] CPU10 is up
[ +0.002151] CPU11 is up
[ +0.002358] CPU12 is up
[ +0.002597] CPU13 is up
[ +0.002713] CPU14 is up
[ +0.002891] CPU15 is up
[ +0.003209] CPU16 is up
[ +0.003149] CPU17 is up
[ +0.003337] CPU18 is up
[ +0.003552] CPU19 is up
[ +0.003765] CPU20 is up
[ +0.003922] CPU21 is up
[ +0.004104] CPU22 is up
[ +0.004266] CPU23 is up
arch/powerpc/kernel/smp.c | 23 ++++++-----------------
1 file changed, 6 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index bcefab484ea6..c8431074d590 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/spinlock.h>
+#include <linux/jiffies.h>
#include <linux/cache.h>
#include <linux/err.h>
#include <linux/device.h>
@@ -1268,7 +1269,8 @@ static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle)
int __cpu_up(unsigned int cpu, struct task_struct *tidle)
{
- int rc, c;
+ unsigned long deadline;
+ int rc;
/*
* Don't allow secondary threads to come online if inhibited
@@ -1313,23 +1315,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
}
/*
- * wait to see if the cpu made a callin (is actually up).
- * use this value that I found through experimentation.
- * -- Cort
+ * Give the remote CPU five seconds to enter the kernel.
*/
- if (system_state < SYSTEM_RUNNING)
- for (c = 50000; c && !cpu_callin_map[cpu]; c--)
- udelay(100);
-#ifdef CONFIG_HOTPLUG_CPU
- else
- /*
- * CPUs can take much longer to come up in the
- * hotplug case. Wait five seconds.
- */
- for (c = 5000; c && !cpu_callin_map[cpu]; c--)
- msleep(1);
-#endif
-
+ deadline = jiffies + msecs_to_jiffies(5000);
+ spin_until_cond(cpu_callin_map[cpu] != 0 || time_after(jiffies, deadline));
if (!cpu_callin_map[cpu]) {
printk(KERN_ERR "Processor %u is stuck.\n", cpu);
return -ENOENT;
--
2.36.1
More information about the Linuxppc-dev
mailing list