2024-01-29 11:58:38

by Mihai Carabas

[permalink] [raw]
Subject: [PATCH v3] Enable haltpoll for arm64

This patchset enables the usage of haltpoll governer on arm64. This is
specifically interesting for KVM guests by reducing the IPC latencies.

Here are some benchmarks without/with haltpoll for a KVM guest:

a) without haltpoll:
perf bench sched pipe
# Running 'sched/pipe' benchmark:
# Executed 1000000 pipe operations between two processes

Total time: 8.138 [sec]

8.138094 usecs/op
122878 ops/sec

b) with haltpoll:
perf bench sched pipe
# Running 'sched/pipe' benchmark:
# Executed 1000000 pipe operations between two processes

Total time: 5.003 [sec]

5.003085 usecs/op
199876 ops/sec

v3 changes from v2:
- fix 1/7 per Petr Mladek - remove ARCH_HAS_CPU_RELAX from arch/x86/Kconfig
- add Ack-by from Rafael Wysocki on 2/7

v2 changes from v1:
- added patch 7 where we change cpu_relax with smp_cond_load_relaxed per PeterZ
(this improves by 50% at least the CPU cycles consumed in the tests above:
10,716,881,137 now vs 14,503,014,257 before)
- removed the ifdef from patch 1 per RafaelW

Joao Martins (6):
x86: Move ARCH_HAS_CPU_RELAX to arch
x86/kvm: Move haltpoll_want() to be arch defined
governors/haltpoll: Drop kvm_para_available() check
arm64: Select ARCH_HAS_CPU_RELAX
arm64: Define TIF_POLLING_NRFLAG
cpuidle-haltpoll: ARM64 support

Mihai Carabas (1):
cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed

arch/Kconfig | 3 +++
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/thread_info.h | 6 ++++++
arch/x86/Kconfig | 4 +---
arch/x86/include/asm/cpuidle_haltpoll.h | 1 +
arch/x86/kernel/kvm.c | 10 ++++++++++
drivers/cpuidle/Kconfig | 4 ++--
drivers/cpuidle/cpuidle-haltpoll.c | 8 ++------
drivers/cpuidle/governors/haltpoll.c | 5 +----
drivers/cpuidle/poll_state.c | 14 +++++++++-----
include/linux/cpuidle_haltpoll.h | 5 +++++
11 files changed, 41 insertions(+), 20 deletions(-)

--
1.8.3.1



2024-01-29 11:58:41

by Mihai Carabas

[permalink] [raw]
Subject: [PATCH v3 5/7] arm64: Define TIF_POLLING_NRFLAG

From: Joao Martins <[email protected]>

The default idle method for arm64 is WFI and it therefore
unconditionally requires the reschedule interrupt when idle.

Commit 842514849a61 ("arm64: Remove TIF_POLLING_NRFLAG") had
reverted it because WFI was the only idle method. ARM64 support
for haltpoll means that poll_idle() polls for TIF_POLLING_NRFLAG,
so define on arm64 *only if* haltpoll is built, using the same bit.

Signed-off-by: Joao Martins <[email protected]>
Signed-off-by: Mihai Carabas <[email protected]>
---
arch/arm64/include/asm/thread_info.h | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 553d1bc559c6..d3010d0b2988 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -69,6 +69,9 @@ struct thread_info {
#define TIF_SYSCALL_TRACEPOINT 10 /* syscall tracepoint for ftrace */
#define TIF_SECCOMP 11 /* syscall secure computing */
#define TIF_SYSCALL_EMU 12 /* syscall emulation active */
+#if IS_ENABLED(CONFIG_HALTPOLL_CPUIDLE) || IS_ENABLED(CONFIG_HALTPOLL_CPUIDLE_MODULE)
+#define TIF_POLLING_NRFLAG 16 /* poll_idle() polls TIF_NEED_RESCHED */
+#endif
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_FREEZE 19
#define TIF_RESTORE_SIGMASK 20
@@ -90,6 +93,9 @@ struct thread_info {
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU)
+#if IS_ENABLED(CONFIG_HALTPOLL_CPUIDLE) || IS_ENABLED(CONFIG_HALTPOLL_CPUIDLE_MODULE)
+#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+#endif
#define _TIF_UPROBE (1 << TIF_UPROBE)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_32BIT (1 << TIF_32BIT)
--
1.8.3.1


2024-01-29 11:58:59

by Mihai Carabas

[permalink] [raw]
Subject: [PATCH v3 6/7] cpuidle-haltpoll: ARM64 support

From: Joao Martins <[email protected]>

To test whether it's a guest or not for the default cases, the haltpoll
driver uses the kvm_para* helpers to find out if it's a guest or not.

ARM64 doesn't have or defined any of these, so it remains disabled on
the default. Although it allows to be force-loaded.

Signed-off-by: Joao Martins <[email protected]>
Signed-off-by: Mihai Carabas <[email protected]>
---
drivers/cpuidle/Kconfig | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index cac5997dca50..067927eda466 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -35,7 +35,7 @@ config CPU_IDLE_GOV_TEO

config CPU_IDLE_GOV_HALTPOLL
bool "Haltpoll governor (for virtualized systems)"
- depends on KVM_GUEST
+ depends on (X86 && KVM_GUEST) || ARM64
help
This governor implements haltpoll idle state selection, to be
used in conjunction with the haltpoll cpuidle driver, allowing
@@ -73,7 +73,7 @@ endmenu

config HALTPOLL_CPUIDLE
tristate "Halt poll cpuidle driver"
- depends on X86 && KVM_GUEST
+ depends on (X86 && KVM_GUEST) || ARM64
select CPU_IDLE_GOV_HALTPOLL
default y
help
--
1.8.3.1