hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I9NR7Q CVE: NA
--------------------------------
Commit 08ae95f4fd3b ("nohz_full: Allow the boot CPU to be nohz_full") allow CPU0 to be housekeeping CPU. But it is only supproted when CONFIG_PM_SLEEP_SMP is not configured, or when it is configured and the arch allows suspend on non-zero CPUs.
We cannot disable CONFIG_PM_SLEEP_SMP because freeze_secondary_cpus(), which is used in kexec, is included in the config. For arm64, there is not restriction in kernel to prevent nonzero cpu entering suspend using PSCI interface. when ARCH_SUSPEND_NONZERO_CPU is enabled, PM_SLEEP_SMP_NONZERO_CPU will be also enabled. The only influence is that suspend_disable_secondary_cpus() will use a housekeeping CPU to enter suspend. If pm sleep/hibernate is not involved, only kexec will use this function, which is tested on a arm64 server, and the vmcore can be created successfully. We add 'enable_cpu0_nohz_full' in the CONFIG_PM_SLEEP_SMP_NONZERO_CPU check branch. When 'enable_cpu0_nohz_full' is zero. There is no functional change.
Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com --- arch/arm64/Kconfig | 3 +++ include/linux/cpu.h | 3 ++- kernel/time/tick-sched.c | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 273a58b74470..eb7334370cfe 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -2306,6 +2306,9 @@ config ARCH_HIBERNATION_HEADER config ARCH_SUSPEND_POSSIBLE def_bool y
+config ARCH_SUSPEND_NONZERO_CPU + def_bool y + endmenu
menu "CPU Power Management" diff --git a/include/linux/cpu.h b/include/linux/cpu.h index c282f6355aef..513cd860b3e3 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -18,6 +18,7 @@ #include <linux/compiler.h> #include <linux/cpumask.h> #include <linux/cpuhotplug.h> +#include <linux/sched/isolation.h>
struct device; struct device_node; @@ -163,7 +164,7 @@ static inline int suspend_disable_secondary_cpus(void) { int cpu = 0;
- if (IS_ENABLED(CONFIG_PM_SLEEP_SMP_NONZERO_CPU)) + if (support_cpu0_nohz_full && IS_ENABLED(CONFIG_PM_SLEEP_SMP_NONZERO_CPU)) cpu = -1;
return freeze_secondary_cpus(cpu); diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index f50dc8f36707..cde853082074 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -16,6 +16,7 @@ #include <linux/percpu.h> #include <linux/nmi.h> #include <linux/profile.h> +#include <linux/sched/isolation.h> #include <linux/sched/signal.h> #include <linux/sched/clock.h> #include <linux/sched/stat.h> @@ -557,7 +558,7 @@ void __init tick_nohz_init(void) }
if (IS_ENABLED(CONFIG_PM_SLEEP_SMP) && - !IS_ENABLED(CONFIG_PM_SLEEP_SMP_NONZERO_CPU)) { + (!support_cpu0_nohz_full || !IS_ENABLED(CONFIG_PM_SLEEP_SMP_NONZERO_CPU))) { cpu = smp_processor_id();
if (cpumask_test_cpu(cpu, tick_nohz_full_mask)) {