Idle-haltpoll has been supported in X86. Now, we will provide it in ARM.
Xiangyou Xie (5): arm64: Optimize ttwu IPI cpuidle-haltpoll: Use arch_cpu_idle() to replace default_idle() arm64: Add some definitions of kvm_para* ARM: cpuidle: Add support for cpuidle-haltpoll driver for ARM config: set default value of haltpoll
arch/arm64/Kconfig | 3 +++ arch/arm64/configs/euleros_defconfig | 2 ++ arch/arm64/configs/hulk_defconfig | 2 ++ arch/arm64/configs/openeuler_defconfig | 4 +++- arch/arm64/include/asm/kvm_para.h | 27 ++++++++++++++++++++++++++ arch/arm64/include/asm/thread_info.h | 3 +++ arch/arm64/kernel/process.c | 4 ++++ arch/x86/kernel/process.c | 1 + drivers/cpuidle/Kconfig | 4 ++-- drivers/cpuidle/cpuidle-haltpoll.c | 6 +++--- drivers/cpuidle/governors/haltpoll.c | 6 +++++- drivers/cpuidle/poll_state.c | 3 +++ 12 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 arch/arm64/include/asm/kvm_para.h
From: Xiangyou Xie xiexiangyou@huawei.com
hulk inclusion category: feature bugzilla: NA CVE: NA
When it is to wake up a task in a remote cpu shared LLC , we can simply set need_resched flag, waking up a cpu that is in polling idle. This wakeup action does not require an IPI.
But the premise is that it need to support _TIF_POLLING_NRFLAG
Signed-off-by: Xiangyou Xie xiexiangyou@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Reviewed-by: zhanghailiang zhang.zhanghailiang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/include/asm/thread_info.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index 30c2bdea970ff..01f063a81d648 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -69,6 +69,7 @@ void arch_release_task_struct(struct task_struct *tsk); * TIF_NEED_RESCHED - rescheduling necessary * TIF_NOTIFY_RESUME - callback before returning to user * TIF_USEDFPU - FPU was used by this task this quantum (SMP) + * TIF_POLLING_NRFLAG - idle is polling for TIF_NEED_RESCHED */ #define TIF_SIGPENDING 0 #define TIF_NEED_RESCHED 1 @@ -82,6 +83,7 @@ void arch_release_task_struct(struct task_struct *tsk); #define TIF_SYSCALL_AUDIT 9 #define TIF_SYSCALL_TRACEPOINT 10 #define TIF_SECCOMP 11 +#define TIF_POLLING_NRFLAG 16 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_FREEZE 19 #define TIF_RESTORE_SIGMASK 20 @@ -108,6 +110,7 @@ void arch_release_task_struct(struct task_struct *tsk); #define _TIF_32BIT (1 << TIF_32BIT) #define _TIF_SVE (1 << TIF_SVE) #define _TIF_32BIT_AARCH64 (1 << TIF_32BIT_AARCH64) +#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \
From: Xiangyou Xie xiexiangyou@huawei.com
hulk inclusion category: feature bugzilla: NA CVE: NA
Use arch_cpu_idle() to replace default_idle() in default_enter_idle(). default_idle() is defined only in x86.
Signed-off-by: Xiangyou Xie xiexiangyou@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Reviewed-by: zhanghailiang zhang.zhanghailiang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/x86/kernel/process.c | 1 + drivers/cpuidle/cpuidle-haltpoll.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index aabd8cd9d5e34..1de41328b277f 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -559,6 +559,7 @@ void __cpuidle default_idle(void) } #if defined(CONFIG_APM_MODULE) || defined(CONFIG_HALTPOLL_CPUIDLE_MODULE) EXPORT_SYMBOL(default_idle); +EXPORT_SYMBOL(arch_cpu_idle); #endif
#ifdef CONFIG_XEN diff --git a/drivers/cpuidle/cpuidle-haltpoll.c b/drivers/cpuidle/cpuidle-haltpoll.c index d007c2f650bc5..8b1e6b0c53628 100644 --- a/drivers/cpuidle/cpuidle-haltpoll.c +++ b/drivers/cpuidle/cpuidle-haltpoll.c @@ -32,7 +32,7 @@ static int default_enter_idle(struct cpuidle_device *dev, local_irq_enable(); return index; } - default_idle(); + arch_cpu_idle(); return index; }
From: Xiangyou Xie xiexiangyou@huawei.com
hulk inclusion category: feature bugzilla: NA CVE: NA
Currently, ARM does not support kvm_para* of KVM_GUEST. We provide some definitions of kvm_para* functions, although it is only a simple return.
Signed-off-by: Xiangyou Xie xiexiangyou@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Reviewed-by: zhanghailiang zhang.zhanghailiang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/include/asm/kvm_para.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 arch/arm64/include/asm/kvm_para.h
diff --git a/arch/arm64/include/asm/kvm_para.h b/arch/arm64/include/asm/kvm_para.h new file mode 100644 index 0000000000000..e1ecc089ee9b8 --- /dev/null +++ b/arch/arm64/include/asm/kvm_para.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ARM64_KVM_PARA_H +#define _ASM_ARM64_KVM_PARA_H + +#define KVM_HINTS_REALTIME 0 + +static inline bool kvm_check_and_clear_guest_paused(void) +{ + return false; +} + +static inline bool kvm_para_available(void) +{ + return false; +} + +static inline unsigned int kvm_arch_para_features(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_para_hints(void) +{ + return 0; +} + +#endif /* _ASM_ARM64_KVM_PARA_H */
From: Xiangyou Xie xiexiangyou@huawei.com
hulk inclusion category: feature bugzilla: NA CVE: NA
Add support for cpuidle-haltpoll driver for ARM. Allow arm to use the couidle-haltpoll driver.
Signed-off-by: Xiangyou Xie xiexiangyou@huawei.com Signed-off-by: Yubo Miao miaoyubo@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Reviewed-by: zhanghailiang zhang.zhanghailiang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/Kconfig | 3 +++ arch/arm64/kernel/process.c | 4 ++++ drivers/cpuidle/Kconfig | 4 ++-- drivers/cpuidle/cpuidle-haltpoll.c | 4 ++-- drivers/cpuidle/governors/haltpoll.c | 6 +++++- drivers/cpuidle/poll_state.c | 3 +++ 6 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 83344333670e2..2c7e6a0196a34 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -288,6 +288,9 @@ config ARCH_SUPPORTS_UPROBES config ARCH_PROC_KCORE_TEXT def_bool y
+config ARCH_HAS_CPU_RELAX + def_bool y + source "arch/arm64/Kconfig.platforms"
source "kernel/livepatch/Kconfig" diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 834245929e548..b9dded33e7b30 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -133,6 +133,10 @@ void arch_cpu_idle(void) trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); }
+#if defined(CONFIG_HALTPOLL_CPUIDLE_MODULE) +EXPORT_SYMBOL(arch_cpu_idle); +#endif + #ifdef CONFIG_HOTPLUG_CPU void arch_cpu_idle_dead(void) { diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig index f7e3ccc68395b..ba75686d20375 100644 --- a/drivers/cpuidle/Kconfig +++ b/drivers/cpuidle/Kconfig @@ -34,7 +34,7 @@ config CPU_IDLE_GOV_TEO
config CPU_IDLE_GOV_HALTPOLL bool "Haltpoll governor (for virtualized systems)" - depends on KVM_GUEST + depends on KVM_GUEST || ARM64 help This governor implements haltpoll idle state selection, to be used in conjunction with the haltpoll cpuidle driver, allowing @@ -63,7 +63,7 @@ endmenu
config HALTPOLL_CPUIDLE tristate "Halt poll cpuidle driver" - depends on X86 && KVM_GUEST + depends on (X86 && KVM_GUEST) || ARM64 default y help This option enables halt poll cpuidle driver, which allows to poll diff --git a/drivers/cpuidle/cpuidle-haltpoll.c b/drivers/cpuidle/cpuidle-haltpoll.c index 8b1e6b0c53628..926a6bcfed9bd 100644 --- a/drivers/cpuidle/cpuidle-haltpoll.c +++ b/drivers/cpuidle/cpuidle-haltpoll.c @@ -96,7 +96,7 @@ static void haltpoll_uninit(void)
static bool haltpoll_want(void) { - return kvm_para_has_hint(KVM_HINTS_REALTIME) || force; + return kvm_para_has_hint(KVM_HINTS_REALTIME); }
static int __init haltpoll_init(void) @@ -106,7 +106,7 @@ static int __init haltpoll_init(void)
cpuidle_poll_state_init(drv);
- if (!kvm_para_available() || !haltpoll_want()) + if (!force && (!kvm_para_available() || !haltpoll_want())) return -ENODEV;
ret = cpuidle_register_driver(drv); diff --git a/drivers/cpuidle/governors/haltpoll.c b/drivers/cpuidle/governors/haltpoll.c index 7a703d2e00640..ce550ab98e665 100644 --- a/drivers/cpuidle/governors/haltpoll.c +++ b/drivers/cpuidle/governors/haltpoll.c @@ -39,6 +39,10 @@ module_param(guest_halt_poll_grow_start, uint, 0644); static bool guest_halt_poll_allow_shrink __read_mostly = true; module_param(guest_halt_poll_allow_shrink, bool, 0644);
+static bool enable __read_mostly; +module_param(enable, bool, 0444); +MODULE_PARM_DESC(enable, "Load unconditionally"); + /** * haltpoll_select - selects the next idle state to enter * @drv: cpuidle driver containing state data @@ -141,7 +145,7 @@ static struct cpuidle_governor haltpoll_governor = {
static int __init init_haltpoll(void) { - if (kvm_para_available()) + if (kvm_para_available() || enable) return cpuidle_register_governor(&haltpoll_governor);
return 0; diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c index c8459fdb28e8e..aa9842b1f1cc2 100644 --- a/drivers/cpuidle/poll_state.c +++ b/drivers/cpuidle/poll_state.c @@ -8,6 +8,9 @@ #include <linux/sched.h> #include <linux/sched/clock.h> #include <linux/sched/idle.h> +#ifdef CONFIG_ARM64 +#include <linux/cpu.h> +#endif
#define POLL_IDLE_RELAX_COUNT 200
From: Xiangyou Xie xiexiangyou@huawei.com
hulk inclusion category: config bugzilla: NA CVE: NA
We enable haltpoll by default for the improvement of performance. X86 has been supported. Now, we will provide it on ARM.
Signed-off-by: Xiangyou Xie xiexiangyou@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Reviewed-by: zhanghailiang zhang.zhanghailiang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/configs/euleros_defconfig | 2 ++ arch/arm64/configs/hulk_defconfig | 2 ++ arch/arm64/configs/openeuler_defconfig | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/configs/euleros_defconfig b/arch/arm64/configs/euleros_defconfig index a62af24c9faab..af6fb5732ee68 100644 --- a/arch/arm64/configs/euleros_defconfig +++ b/arch/arm64/configs/euleros_defconfig @@ -528,11 +528,13 @@ CONFIG_CPU_IDLE=y # CONFIG_CPU_IDLE_GOV_LADDER is not set CONFIG_CPU_IDLE_GOV_MENU=y # CONFIG_CPU_IDLE_GOV_TEO is not set +# CONFIG_CPU_IDLE_GOV_HALTPOLL is not set
# # ARM CPU Idle Drivers # # CONFIG_ARM_CPUIDLE is not set +# CONFIG_HALTPOLL_CPUIDLE is not set
# # CPU Frequency scaling diff --git a/arch/arm64/configs/hulk_defconfig b/arch/arm64/configs/hulk_defconfig index da787ef81484e..b5325f18054f3 100644 --- a/arch/arm64/configs/hulk_defconfig +++ b/arch/arm64/configs/hulk_defconfig @@ -534,11 +534,13 @@ CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y CONFIG_CPU_IDLE_GOV_MENU=y CONFIG_CPU_IDLE_GOV_TEO=y CONFIG_DT_IDLE_STATES=y +# CONFIG_CPU_IDLE_GOV_HALTPOLL is not set
# # ARM CPU Idle Drivers # CONFIG_ARM_CPUIDLE=y +# CONFIG_HALTPOLL_CPUIDLE is not set
# # CPU Frequency scaling diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index e4aff6ad6a67f..9f2d1475cfa64 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -531,11 +531,13 @@ CONFIG_CPU_IDLE=y # CONFIG_CPU_IDLE_GOV_LADDER is not set CONFIG_CPU_IDLE_GOV_MENU=y # CONFIG_CPU_IDLE_GOV_TEO is not set +CONFIG_CPU_IDLE_GOV_HALTPOLL=y
# # ARM CPU Idle Drivers # -# CONFIG_ARM_CPUIDLE is not set +CONFIG_ARM_CPUIDLE=y +CONFIG_HALTPOLL_CPUIDLE=y
# # CPU Frequency scaling