* [PATCH v3] Enable haltpoll for arm64
@ 2024-01-29 10:40 Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 1/7] x86: Move ARCH_HAS_CPU_RELAX to arch Mihai Carabas
` (6 more replies)
0 siblings, 7 replies; 11+ messages in thread
From: Mihai Carabas @ 2024-01-29 10:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: kvm, linux-pm, linux-kernel, catalin.marinas, will, tglx, mingo,
bp, x86, hpa, pbonzini, wanpengli, vkuznets, rafael,
daniel.lezcano, akpm, pmladek, peterz, dianders, npiggin,
rick.p.edgecombe, joao.m.martins, juerg.haefliger, mic,
mihai.carabas, arnd, ankur.a.arora
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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 1/7] x86: Move ARCH_HAS_CPU_RELAX to arch
2024-01-29 10:40 [PATCH v3] Enable haltpoll for arm64 Mihai Carabas
@ 2024-01-29 10:40 ` Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 2/7] x86/kvm: Move haltpoll_want() to be arch defined Mihai Carabas
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Mihai Carabas @ 2024-01-29 10:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: kvm, linux-pm, linux-kernel, catalin.marinas, will, tglx, mingo,
bp, x86, hpa, pbonzini, wanpengli, vkuznets, rafael,
daniel.lezcano, akpm, pmladek, peterz, dianders, npiggin,
rick.p.edgecombe, joao.m.martins, juerg.haefliger, mic,
mihai.carabas, arnd, ankur.a.arora
From: Joao Martins <joao.m.martins@oracle.com>
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 <joao.m.martins@oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
---
arch/Kconfig | 3 +++
arch/x86/Kconfig | 4 +---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index 12d51495caec..626ddd9ba7e0 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 66bfabae8814..aaca90ba791a 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
@@ -363,9 +364,6 @@ config ARCH_MAY_HAVE_PC_FDC
config GENERIC_CALIBRATE_DELAY
def_bool y
-config ARCH_HAS_CPU_RELAX
- def_bool y
-
config ARCH_HIBERNATION_POSSIBLE
def_bool y
--
1.8.3.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 2/7] x86/kvm: Move haltpoll_want() to be arch defined
2024-01-29 10:40 [PATCH v3] Enable haltpoll for arm64 Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 1/7] x86: Move ARCH_HAS_CPU_RELAX to arch Mihai Carabas
@ 2024-01-29 10:40 ` Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 3/7] governors/haltpoll: Drop kvm_para_available() check Mihai Carabas
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Mihai Carabas @ 2024-01-29 10:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: kvm, linux-pm, linux-kernel, catalin.marinas, will, tglx, mingo,
bp, x86, hpa, pbonzini, wanpengli, vkuznets, rafael,
daniel.lezcano, akpm, pmladek, peterz, dianders, npiggin,
rick.p.edgecombe, joao.m.martins, juerg.haefliger, mic,
mihai.carabas, arnd, ankur.a.arora
From: Joao Martins <joao.m.martins@oracle.com>
Right now, kvm_para_has_hint(KVM_HINTS_REALTIME) is x86 only, and so in the
pursuit of making cpuidle-haltpoll arch independent, move the check for
haltpoll enablement to be defined per architecture. Same thing for
boot_option_idle_override. To that end, add a arch_haltpoll_want() and move the
check there.
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
Acked-by: Rafael J. Wysocki <rafael@kernel.org>
---
arch/x86/include/asm/cpuidle_haltpoll.h | 1 +
arch/x86/kernel/kvm.c | 10 ++++++++++
drivers/cpuidle/cpuidle-haltpoll.c | 8 ++------
include/linux/cpuidle_haltpoll.h | 5 +++++
4 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/arch/x86/include/asm/cpuidle_haltpoll.h b/arch/x86/include/asm/cpuidle_haltpoll.h
index c8b39c6716ff..2c5a53ce266f 100644
--- a/arch/x86/include/asm/cpuidle_haltpoll.h
+++ b/arch/x86/include/asm/cpuidle_haltpoll.h
@@ -4,5 +4,6 @@
void arch_haltpoll_enable(unsigned int cpu);
void arch_haltpoll_disable(unsigned int cpu);
+bool arch_haltpoll_want(void);
#endif
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index b8ab9ee5896c..2ba12da13fc1 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -1149,4 +1149,14 @@ void arch_haltpoll_disable(unsigned int cpu)
smp_call_function_single(cpu, kvm_enable_host_haltpoll, NULL, 1);
}
EXPORT_SYMBOL_GPL(arch_haltpoll_disable);
+
+bool arch_haltpoll_want(void)
+{
+ /* Do not load haltpoll if idle= is passed */
+ if (boot_option_idle_override != IDLE_NO_OVERRIDE)
+ return false;
+
+ return kvm_para_has_hint(KVM_HINTS_REALTIME);
+}
+EXPORT_SYMBOL_GPL(arch_haltpoll_want);
#endif
diff --git a/drivers/cpuidle/cpuidle-haltpoll.c b/drivers/cpuidle/cpuidle-haltpoll.c
index e66df22f9695..72f9c84990c5 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_available() && arch_haltpoll_want()) || force;
}
static int __init haltpoll_init(void)
@@ -104,11 +104,7 @@ static int __init haltpoll_init(void)
int ret;
struct cpuidle_driver *drv = &haltpoll_driver;
- /* Do not load haltpoll if idle= is passed */
- if (boot_option_idle_override != IDLE_NO_OVERRIDE)
- return -ENODEV;
-
- if (!kvm_para_available() || !haltpoll_want())
+ if (!haltpoll_want())
return -ENODEV;
cpuidle_poll_state_init(drv);
diff --git a/include/linux/cpuidle_haltpoll.h b/include/linux/cpuidle_haltpoll.h
index d50c1e0411a2..bae68a6603e3 100644
--- a/include/linux/cpuidle_haltpoll.h
+++ b/include/linux/cpuidle_haltpoll.h
@@ -12,5 +12,10 @@ static inline void arch_haltpoll_enable(unsigned int cpu)
static inline void arch_haltpoll_disable(unsigned int cpu)
{
}
+
+static inline bool arch_haltpoll_want(void)
+{
+ return false;
+}
#endif
#endif
--
1.8.3.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 3/7] governors/haltpoll: Drop kvm_para_available() check
2024-01-29 10:40 [PATCH v3] Enable haltpoll for arm64 Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 1/7] x86: Move ARCH_HAS_CPU_RELAX to arch Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 2/7] x86/kvm: Move haltpoll_want() to be arch defined Mihai Carabas
@ 2024-01-29 10:40 ` Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 4/7] arm64: Select ARCH_HAS_CPU_RELAX Mihai Carabas
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Mihai Carabas @ 2024-01-29 10:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: kvm, linux-pm, linux-kernel, catalin.marinas, will, tglx, mingo,
bp, x86, hpa, pbonzini, wanpengli, vkuznets, rafael,
daniel.lezcano, akpm, pmladek, peterz, dianders, npiggin,
rick.p.edgecombe, joao.m.martins, juerg.haefliger, mic,
mihai.carabas, arnd, ankur.a.arora
From: Joao Martins <joao.m.martins@oracle.com>
This is duplicated already in the haltpoll idle driver,
and there's no need to re-check KVM guest availability in
the governor.
Either guests uses the module which explicitly selects this
governor, and given that it has the lowest rating of all governors
(menu=20,teo=19,ladder=10/25,haltpoll=9) means that unless it's
the only one compiled in, it won't be selected.
Dropping such check also allows to test haltpoll in baremetal.
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
Acked-by: Rafael J. Wysocki <rafael@kernel.org>
---
drivers/cpuidle/governors/haltpoll.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/cpuidle/governors/haltpoll.c b/drivers/cpuidle/governors/haltpoll.c
index 1dff3a52917d..c9b69651d377 100644
--- a/drivers/cpuidle/governors/haltpoll.c
+++ b/drivers/cpuidle/governors/haltpoll.c
@@ -143,10 +143,7 @@ static int haltpoll_enable_device(struct cpuidle_driver *drv,
static int __init init_haltpoll(void)
{
- if (kvm_para_available())
- return cpuidle_register_governor(&haltpoll_governor);
-
- return 0;
+ return cpuidle_register_governor(&haltpoll_governor);
}
postcore_initcall(init_haltpoll);
--
1.8.3.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 4/7] arm64: Select ARCH_HAS_CPU_RELAX
2024-01-29 10:40 [PATCH v3] Enable haltpoll for arm64 Mihai Carabas
` (2 preceding siblings ...)
2024-01-29 10:40 ` [PATCH v3 3/7] governors/haltpoll: Drop kvm_para_available() check Mihai Carabas
@ 2024-01-29 10:40 ` Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 5/7] arm64: Define TIF_POLLING_NRFLAG Mihai Carabas
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Mihai Carabas @ 2024-01-29 10:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: kvm, linux-pm, linux-kernel, catalin.marinas, will, tglx, mingo,
bp, x86, hpa, pbonzini, wanpengli, vkuznets, rafael,
daniel.lezcano, akpm, pmladek, peterz, dianders, npiggin,
rick.p.edgecombe, joao.m.martins, juerg.haefliger, mic,
mihai.carabas, arnd, ankur.a.arora
From: Joao Martins <joao.m.martins@oracle.com>
ARCH_HAS_CPU_RELAX controls the build of poll-state, so select it from ARM64
kconfig.
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
---
arch/arm64/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 78f20e632712..24adbe9a2aa6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -106,6 +106,7 @@ config ARM64
select ARCH_WANT_LD_ORPHAN_WARN
select ARCH_WANTS_NO_INSTR
select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
+ select ARCH_HAS_CPU_RELAX
select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARM_AMBA
select ARM_ARCH_TIMER
--
1.8.3.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 5/7] arm64: Define TIF_POLLING_NRFLAG
2024-01-29 10:40 [PATCH v3] Enable haltpoll for arm64 Mihai Carabas
` (3 preceding siblings ...)
2024-01-29 10:40 ` [PATCH v3 4/7] arm64: Select ARCH_HAS_CPU_RELAX Mihai Carabas
@ 2024-01-29 10:40 ` Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 6/7] cpuidle-haltpoll: ARM64 support Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 7/7] cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed Mihai Carabas
6 siblings, 0 replies; 11+ messages in thread
From: Mihai Carabas @ 2024-01-29 10:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: kvm, linux-pm, linux-kernel, catalin.marinas, will, tglx, mingo,
bp, x86, hpa, pbonzini, wanpengli, vkuznets, rafael,
daniel.lezcano, akpm, pmladek, peterz, dianders, npiggin,
rick.p.edgecombe, joao.m.martins, juerg.haefliger, mic,
mihai.carabas, arnd, ankur.a.arora
From: Joao Martins <joao.m.martins@oracle.com>
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 <joao.m.martins@oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
---
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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 6/7] cpuidle-haltpoll: ARM64 support
2024-01-29 10:40 [PATCH v3] Enable haltpoll for arm64 Mihai Carabas
` (4 preceding siblings ...)
2024-01-29 10:40 ` [PATCH v3 5/7] arm64: Define TIF_POLLING_NRFLAG Mihai Carabas
@ 2024-01-29 10:40 ` Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 7/7] cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed Mihai Carabas
6 siblings, 0 replies; 11+ messages in thread
From: Mihai Carabas @ 2024-01-29 10:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: kvm, linux-pm, linux-kernel, catalin.marinas, will, tglx, mingo,
bp, x86, hpa, pbonzini, wanpengli, vkuznets, rafael,
daniel.lezcano, akpm, pmladek, peterz, dianders, npiggin,
rick.p.edgecombe, joao.m.martins, juerg.haefliger, mic,
mihai.carabas, arnd, ankur.a.arora
From: Joao Martins <joao.m.martins@oracle.com>
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 <joao.m.martins@oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
---
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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 7/7] cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed
2024-01-29 10:40 [PATCH v3] Enable haltpoll for arm64 Mihai Carabas
` (5 preceding siblings ...)
2024-01-29 10:40 ` [PATCH v3 6/7] cpuidle-haltpoll: ARM64 support Mihai Carabas
@ 2024-01-29 10:40 ` Mihai Carabas
2024-01-29 14:52 ` Rafael J. Wysocki
6 siblings, 1 reply; 11+ messages in thread
From: Mihai Carabas @ 2024-01-29 10:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: kvm, linux-pm, linux-kernel, catalin.marinas, will, tglx, mingo,
bp, x86, hpa, pbonzini, wanpengli, vkuznets, rafael,
daniel.lezcano, akpm, pmladek, peterz, dianders, npiggin,
rick.p.edgecombe, joao.m.martins, juerg.haefliger, mic,
mihai.carabas, arnd, ankur.a.arora
cpu_relax on ARM64 does a simple "yield". Thus we replace it with
smp_cond_load_relaxed which basically does a "wfe".
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
---
drivers/cpuidle/poll_state.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c
index 9b6d90a72601..440cd713e39a 100644
--- a/drivers/cpuidle/poll_state.c
+++ b/drivers/cpuidle/poll_state.c
@@ -26,12 +26,16 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev,
limit = cpuidle_poll_time(drv, dev);
- while (!need_resched()) {
- cpu_relax();
- if (loop_count++ < POLL_IDLE_RELAX_COUNT)
- continue;
-
+ for (;;) {
loop_count = 0;
+
+ smp_cond_load_relaxed(¤t_thread_info()->flags,
+ (VAL & _TIF_NEED_RESCHED) ||
+ (loop_count++ >= POLL_IDLE_RELAX_COUNT));
+
+ if (loop_count < POLL_IDLE_RELAX_COUNT)
+ break;
+
if (local_clock_noinstr() - time_start > limit) {
dev->poll_time_limit = true;
break;
--
1.8.3.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 7/7] cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed
2024-01-29 10:40 ` [PATCH v3 7/7] cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed Mihai Carabas
@ 2024-01-29 14:52 ` Rafael J. Wysocki
2024-01-29 19:20 ` Mihai Carabas
0 siblings, 1 reply; 11+ messages in thread
From: Rafael J. Wysocki @ 2024-01-29 14:52 UTC (permalink / raw)
To: Mihai Carabas
Cc: linux-arm-kernel, kvm, linux-pm, linux-kernel, catalin.marinas,
will, tglx, mingo, bp, x86, hpa, pbonzini, wanpengli, vkuznets,
rafael, daniel.lezcano, akpm, pmladek, peterz, dianders, npiggin,
rick.p.edgecombe, joao.m.martins, juerg.haefliger, mic, arnd,
ankur.a.arora
On Mon, Jan 29, 2024 at 12:56 PM Mihai Carabas <mihai.carabas@oracle.com> wrote:
>
> cpu_relax on ARM64 does a simple "yield". Thus we replace it with
> smp_cond_load_relaxed which basically does a "wfe".
>
> Suggested-by: Peter Zijlstra <peterz@infradead.org>
> Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
> ---
> drivers/cpuidle/poll_state.c | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c
> index 9b6d90a72601..440cd713e39a 100644
> --- a/drivers/cpuidle/poll_state.c
> +++ b/drivers/cpuidle/poll_state.c
> @@ -26,12 +26,16 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev,
>
> limit = cpuidle_poll_time(drv, dev);
>
> - while (!need_resched()) {
> - cpu_relax();
> - if (loop_count++ < POLL_IDLE_RELAX_COUNT)
> - continue;
> -
> + for (;;) {
> loop_count = 0;
> +
> + smp_cond_load_relaxed(¤t_thread_info()->flags,
> + (VAL & _TIF_NEED_RESCHED) ||
> + (loop_count++ >= POLL_IDLE_RELAX_COUNT));
The inner parens are not necessary AFAICS.
Also, doesn't this return a value which can be used for checking if
_TIF_NEED_RESCHED is set instead of the condition below?
> +
> + if (loop_count < POLL_IDLE_RELAX_COUNT)
> + break;
> +
> if (local_clock_noinstr() - time_start > limit) {
> dev->poll_time_limit = true;
> break;
> --
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 7/7] cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed
2024-01-29 14:52 ` Rafael J. Wysocki
@ 2024-01-29 19:20 ` Mihai Carabas
2024-01-29 19:41 ` Rafael J. Wysocki
0 siblings, 1 reply; 11+ messages in thread
From: Mihai Carabas @ 2024-01-29 19:20 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: linux-arm-kernel, kvm, linux-pm, linux-kernel, catalin.marinas,
will, tglx, mingo, bp, x86, hpa, pbonzini, wanpengli, vkuznets,
daniel.lezcano, akpm, pmladek, peterz, dianders, npiggin,
rick.p.edgecombe, joao.m.martins, juerg.haefliger, mic, arnd,
ankur.a.arora
La 29.01.2024 16:52, Rafael J. Wysocki a scris:
> On Mon, Jan 29, 2024 at 12:56 PM Mihai Carabas <mihai.carabas@oracle.com> wrote:
>> cpu_relax on ARM64 does a simple "yield". Thus we replace it with
>> smp_cond_load_relaxed which basically does a "wfe".
>>
>> Suggested-by: Peter Zijlstra <peterz@infradead.org>
>> Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
>> ---
>> drivers/cpuidle/poll_state.c | 14 +++++++++-----
>> 1 file changed, 9 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c
>> index 9b6d90a72601..440cd713e39a 100644
>> --- a/drivers/cpuidle/poll_state.c
>> +++ b/drivers/cpuidle/poll_state.c
>> @@ -26,12 +26,16 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev,
>>
>> limit = cpuidle_poll_time(drv, dev);
>>
>> - while (!need_resched()) {
>> - cpu_relax();
>> - if (loop_count++ < POLL_IDLE_RELAX_COUNT)
>> - continue;
>> -
>> + for (;;) {
>> loop_count = 0;
>> +
>> + smp_cond_load_relaxed(¤t_thread_info()->flags,
>> + (VAL & _TIF_NEED_RESCHED) ||
>> + (loop_count++ >= POLL_IDLE_RELAX_COUNT));
> The inner parens are not necessary AFAICS.
Provides better reading. Do you want to remove these?
> Also, doesn't this return a value which can be used for checking if
> _TIF_NEED_RESCHED is set instead of the condition below?
Yes, indeed - should I modify this check? (somehow I wanted to preserve
the original check)
Thank you,
Mihai
>> +
>> + if (loop_count < POLL_IDLE_RELAX_COUNT)
>> + break;
>> +
>> if (local_clock_noinstr() - time_start > limit) {
>> dev->poll_time_limit = true;
>> break;
>> --
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 7/7] cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed
2024-01-29 19:20 ` Mihai Carabas
@ 2024-01-29 19:41 ` Rafael J. Wysocki
0 siblings, 0 replies; 11+ messages in thread
From: Rafael J. Wysocki @ 2024-01-29 19:41 UTC (permalink / raw)
To: Mihai Carabas
Cc: Rafael J. Wysocki, linux-arm-kernel, kvm, linux-pm, linux-kernel,
catalin.marinas, will, tglx, mingo, bp, x86, hpa, pbonzini,
wanpengli, vkuznets, daniel.lezcano, akpm, pmladek, peterz,
dianders, npiggin, rick.p.edgecombe, joao.m.martins,
juerg.haefliger, mic, arnd, ankur.a.arora
On Mon, Jan 29, 2024 at 8:21 PM Mihai Carabas <mihai.carabas@oracle.com> wrote:
>
> La 29.01.2024 16:52, Rafael J. Wysocki a scris:
> > On Mon, Jan 29, 2024 at 12:56 PM Mihai Carabas <mihai.carabas@oracle.com> wrote:
> >> cpu_relax on ARM64 does a simple "yield". Thus we replace it with
> >> smp_cond_load_relaxed which basically does a "wfe".
> >>
> >> Suggested-by: Peter Zijlstra <peterz@infradead.org>
> >> Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
> >> ---
> >> drivers/cpuidle/poll_state.c | 14 +++++++++-----
> >> 1 file changed, 9 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c
> >> index 9b6d90a72601..440cd713e39a 100644
> >> --- a/drivers/cpuidle/poll_state.c
> >> +++ b/drivers/cpuidle/poll_state.c
> >> @@ -26,12 +26,16 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev,
> >>
> >> limit = cpuidle_poll_time(drv, dev);
> >>
> >> - while (!need_resched()) {
> >> - cpu_relax();
> >> - if (loop_count++ < POLL_IDLE_RELAX_COUNT)
> >> - continue;
> >> -
> >> + for (;;) {
> >> loop_count = 0;
> >> +
> >> + smp_cond_load_relaxed(¤t_thread_info()->flags,
> >> + (VAL & _TIF_NEED_RESCHED) ||
> >> + (loop_count++ >= POLL_IDLE_RELAX_COUNT));
> > The inner parens are not necessary AFAICS.
>
> Provides better reading. Do you want to remove these?
Whether or not it provides better reading is in the eye of the reader.
We seem to disagree here, because IMO redundant characters don't help
clarity.
> > Also, doesn't this return a value which can be used for checking if
> > _TIF_NEED_RESCHED is set instead of the condition below?
>
> Yes, indeed - should I modify this check? (somehow I wanted to preserve
> the original check)
But you haven't - it goes the other way around now.
In theory, _TIF_NEED_RESCHED may be set in the last iteration, in
which the check below will miss it, won't it?
> >> +
> >> + if (loop_count < POLL_IDLE_RELAX_COUNT)
> >> + break;
> >> +
> >> if (local_clock_noinstr() - time_start > limit) {
> >> dev->poll_time_limit = true;
> >> break;
> >> --
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2024-01-29 19:41 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-29 10:40 [PATCH v3] Enable haltpoll for arm64 Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 1/7] x86: Move ARCH_HAS_CPU_RELAX to arch Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 2/7] x86/kvm: Move haltpoll_want() to be arch defined Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 3/7] governors/haltpoll: Drop kvm_para_available() check Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 4/7] arm64: Select ARCH_HAS_CPU_RELAX Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 5/7] arm64: Define TIF_POLLING_NRFLAG Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 6/7] cpuidle-haltpoll: ARM64 support Mihai Carabas
2024-01-29 10:40 ` [PATCH v3 7/7] cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed Mihai Carabas
2024-01-29 14:52 ` Rafael J. Wysocki
2024-01-29 19:20 ` Mihai Carabas
2024-01-29 19:41 ` Rafael J. Wysocki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®