2023-08-09 13:29:04

by Mihai Carabas

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

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

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.410 [sec]

8.410882 usecs/op
118893 ops/sec

b) with haltpoll:
perf bench sched pipe
# Running 'sched/pipe' benchmark:
# Executed 1000000 pipe operations between two processes
Total time: 5.183 [sec]
5.183491 usecs/op
192920 ops/sec

Joao Martins (7):
cpuidle-haltpoll: Make boot_option_idle_override check X86 specific
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

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

--
1.8.3.1



2023-08-09 13:29:17

by Mihai Carabas

[permalink] [raw]
Subject: [PATCH 6/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


2023-08-09 13:32:12

by Mihai Carabas

[permalink] [raw]
Subject: [PATCH 7/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


2023-08-09 13:32:44

by Mihai Carabas

[permalink] [raw]
Subject: [PATCH 2/7] x86: Move ARCH_HAS_CPU_RELAX to arch

From: Joao Martins <[email protected]>

ARM64 is going to use it for haltpoll support (for poll-state)
so move the definition to be arch-agnostic and allow architectures
to override it.

Signed-off-by: Joao Martins <[email protected]>
Signed-off-by: Mihai Carabas <[email protected]>
---
arch/Kconfig | 3 +++
arch/x86/Kconfig | 1 +
2 files changed, 4 insertions(+)

diff --git a/arch/Kconfig b/arch/Kconfig
index aff2746c8af2..31bd138f406d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1371,6 +1371,9 @@ config RELR
config ARCH_HAS_MEM_ENCRYPT
bool

+config ARCH_HAS_CPU_RELAX
+ bool
+
config ARCH_HAS_CC_PLATFORM
bool

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7422db409770..2eab3be6abbb 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -72,6 +72,7 @@ config X86
select ARCH_HAS_CACHE_LINE_SIZE
select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
select ARCH_HAS_CPU_FINALIZE_INIT
+ select ARCH_HAS_CPU_RELAX
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE
--
1.8.3.1


2023-08-09 16:10:17

by Peter Zijlstra

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

On Wed, Aug 09, 2023 at 02:39:34PM +0300, Mihai Carabas wrote:

> Joao Martins (7):
> cpuidle-haltpoll: Make boot_option_idle_override check X86 specific
> 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

You have far too many SOB's on some or all of these patches.

Using poll_state as is on arm64 seems sub-optimal, would not something
like the below make sense?

---
diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c
index 9b6d90a72601..9ab40198b042 100644
--- a/drivers/cpuidle/poll_state.c
+++ b/drivers/cpuidle/poll_state.c
@@ -27,7 +27,11 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev,
limit = cpuidle_poll_time(drv, dev);

while (!need_resched()) {
- cpu_relax();
+
+ smp_cond_load_relaxed(current_thread_info()->flags,
+ (VAL & TIF_NEED_RESCHED) ||
+ (loop_count++ >= POLL_IDLE_RELAX_COUNT));
+
if (loop_count++ < POLL_IDLE_RELAX_COUNT)
continue;