* [PATCH v2 1/5] s390/tick: Remove CIF_NOHZ_DELAY flag
2026-06-09 13:24 [PATCH v2 0/5] s390/idle: CPU idle driver Mete Durlu
@ 2026-06-09 13:24 ` Mete Durlu
2026-06-09 13:24 ` [PATCH v2 2/5] tick: Remove arch_needs_cpu Mete Durlu
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Mete Durlu @ 2026-06-09 13:24 UTC (permalink / raw)
To: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Anna-Maria Behnsen, Frederic Weisbecker, Ingo Molnar,
Thomas Gleixner, Rafael J. Wysocki, Daniel Lezcano,
Christian Loehle
Cc: Mete Durlu, Christian Borntraeger, Ilya Leoshkevich, linux-s390,
linux-kernel, linux-pm
Remove obsolete tick delay heuristic [1]. The upcoming cpuidle driver
handles frequent sleep/wakeup cycles more effectively.
[1] https://lore.kernel.org/all/20090929122533.402715150@de.ibm.com/
Suggested-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
---
arch/s390/include/asm/processor.h | 4 ----
arch/s390/kernel/idle.c | 1 -
arch/s390/kernel/irq.c | 4 ----
arch/s390/kernel/smp.c | 1 -
4 files changed, 10 deletions(-)
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 78195ee5e99f..3666198cc364 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -14,12 +14,10 @@
#include <linux/bits.h>
-#define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */
#define CIF_ENABLED_WAIT 5 /* in enabled wait state */
#define CIF_MCCK_GUEST 6 /* machine check happening in guest */
#define CIF_DEDICATED_CPU 7 /* this CPU is dedicated */
-#define _CIF_NOHZ_DELAY BIT(CIF_NOHZ_DELAY)
#define _CIF_ENABLED_WAIT BIT(CIF_ENABLED_WAIT)
#define _CIF_MCCK_GUEST BIT(CIF_MCCK_GUEST)
#define _CIF_DEDICATED_CPU BIT(CIF_DEDICATED_CPU)
@@ -96,8 +94,6 @@ static __always_inline bool test_cpu_flag_of(int flag, int cpu)
return test_bit(flag, &per_cpu(pcpu_devices, cpu).flags);
}
-#define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY)
-
static inline void get_cpu_id(struct cpuid *ptr)
{
asm volatile("stidp %0" : "=Q" (*ptr));
diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c
index 1f1b06b6b4ef..8c63f440da2e 100644
--- a/arch/s390/kernel/idle.c
+++ b/arch/s390/kernel/idle.c
@@ -42,7 +42,6 @@ void noinstr arch_cpu_idle(void)
/* Wait for external, I/O or machine check interrupt. */
psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT |
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
- clear_cpu_flag(CIF_NOHZ_DELAY);
set_cpu_flag(CIF_ENABLED_WAIT);
if (smp_cpu_mtid)
stcctm(MT_DIAG, smp_cpu_mtid, (u64 *)&idle->mt_cycles_enter);
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index d10a17e6531d..61d17954c34c 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -161,7 +161,6 @@ void noinstr do_io_irq(struct pt_regs *regs)
if (from_idle)
account_idle_time_irq();
- set_cpu_flag(CIF_NOHZ_DELAY);
do {
regs->tpi_info = get_lowcore()->tpi_info;
if (get_lowcore()->tpi_info.adapter_IO)
@@ -358,9 +357,6 @@ static irqreturn_t do_ext_interrupt(int irq, void *dummy)
int index;
ext_code.int_code = regs->int_code;
- if (ext_code.code != EXT_IRQ_CLK_COMP)
- set_cpu_flag(CIF_NOHZ_DELAY);
-
index = ext_hash(ext_code.code);
rcu_read_lock();
hlist_for_each_entry_rcu(p, &ext_int_hash[index], entry) {
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 50bb499cf3e5..cd5ccbe3a18d 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -910,7 +910,6 @@ int __cpu_disable(void)
cregs[6].val &= ~0xff000000UL; /* disable all I/O interrupts */
cregs[14].val &= ~0x1f000000UL; /* disable most machine checks */
__local_ctl_load(0, 15, cregs);
- clear_cpu_flag(CIF_NOHZ_DELAY);
return 0;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 2/5] tick: Remove arch_needs_cpu
2026-06-09 13:24 [PATCH v2 0/5] s390/idle: CPU idle driver Mete Durlu
2026-06-09 13:24 ` [PATCH v2 1/5] s390/tick: Remove CIF_NOHZ_DELAY flag Mete Durlu
@ 2026-06-09 13:24 ` Mete Durlu
2026-06-09 15:16 ` Thomas Gleixner
2026-06-09 13:24 ` [PATCH v2 3/5] s390: Enable TIF_POLLING_NRFLAG Mete Durlu
` (4 subsequent siblings)
6 siblings, 1 reply; 9+ messages in thread
From: Mete Durlu @ 2026-06-09 13:24 UTC (permalink / raw)
To: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Anna-Maria Behnsen, Frederic Weisbecker, Ingo Molnar,
Thomas Gleixner, Rafael J. Wysocki, Daniel Lezcano,
Christian Loehle
Cc: Mete Durlu, Christian Borntraeger, Ilya Leoshkevich, linux-s390,
linux-kernel, linux-pm
Remove unused arch_needs_cpu() hook. No architectures use it after
s390 removed its use case.
Suggested-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
---
include/linux/tick.h | 3 ---
kernel/time/tick-sched.c | 7 +++----
2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 738007d6f577..0f6757f81839 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -44,9 +44,6 @@ static inline void tick_unfreeze(void) { }
#ifdef CONFIG_TICK_ONESHOT
extern void tick_irq_enter(void);
-# ifndef arch_needs_cpu
-# define arch_needs_cpu() (0)
-# endif
# else
static inline void tick_irq_enter(void) { }
#endif
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index cbbb87a0c6e7..cee18999d818 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -943,8 +943,7 @@ static ktime_t tick_nohz_next_event(struct tick_sched *ts, int cpu)
ts->timer_expires_base = basemono;
/*
- * Keep the periodic tick, when RCU, architecture or irq_work
- * requests it.
+ * Keep the periodic tick, when RCU or irq_work requests it.
* Aside of that, check whether the local timer softirq is
* pending. If so, its a bad idea to call get_next_timer_interrupt(),
* because there is an already expired timer, so it will request
@@ -952,8 +951,8 @@ static ktime_t tick_nohz_next_event(struct tick_sched *ts, int cpu)
* minimal delta, which brings us back to this place
* immediately. Lather, rinse and repeat...
*/
- if (rcu_needs_cpu() || arch_needs_cpu() ||
- irq_work_needs_cpu() || local_timer_softirq_pending()) {
+ if (rcu_needs_cpu() || irq_work_needs_cpu() ||
+ local_timer_softirq_pending()) {
next_tick = basemono + TICK_NSEC;
} else {
/*
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v2 2/5] tick: Remove arch_needs_cpu
2026-06-09 13:24 ` [PATCH v2 2/5] tick: Remove arch_needs_cpu Mete Durlu
@ 2026-06-09 15:16 ` Thomas Gleixner
0 siblings, 0 replies; 9+ messages in thread
From: Thomas Gleixner @ 2026-06-09 15:16 UTC (permalink / raw)
To: Mete Durlu, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Sven Schnelle, Anna-Maria Behnsen, Frederic Weisbecker,
Ingo Molnar, Rafael J. Wysocki, Daniel Lezcano, Christian Loehle
Cc: Mete Durlu, Christian Borntraeger, Ilya Leoshkevich, linux-s390,
linux-kernel, linux-pm
On Tue, Jun 09 2026 at 15:24, Mete Durlu wrote:
> Remove unused arch_needs_cpu() hook. No architectures use it after
> s390 removed its use case.
>
> Suggested-by: Heiko Carstens <hca@linux.ibm.com>
> Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 3/5] s390: Enable TIF_POLLING_NRFLAG
2026-06-09 13:24 [PATCH v2 0/5] s390/idle: CPU idle driver Mete Durlu
2026-06-09 13:24 ` [PATCH v2 1/5] s390/tick: Remove CIF_NOHZ_DELAY flag Mete Durlu
2026-06-09 13:24 ` [PATCH v2 2/5] tick: Remove arch_needs_cpu Mete Durlu
@ 2026-06-09 13:24 ` Mete Durlu
2026-06-09 13:24 ` [PATCH v2 4/5] s390/idle: Introduce cpuidle for s390 Mete Durlu
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Mete Durlu @ 2026-06-09 13:24 UTC (permalink / raw)
To: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Anna-Maria Behnsen, Frederic Weisbecker, Ingo Molnar,
Thomas Gleixner, Rafael J. Wysocki, Daniel Lezcano,
Christian Loehle
Cc: Mete Durlu, Christian Borntraeger, Ilya Leoshkevich, linux-s390,
linux-kernel, linux-pm
Enable TIF_POLLING_NRFLAG to support idle polling state in the
upcoming cpuidle driver.
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
---
arch/s390/include/asm/thread_info.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index 6a548a819400..2554cef3a6a5 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -61,6 +61,7 @@ void arch_setup_new_exec(void);
*/
#define HAVE_TIF_NEED_RESCHED_LAZY
#define HAVE_TIF_RESTORE_SIGMASK
+#define HAVE_TIF_POLLING_NRFLAG
#include <asm-generic/thread_info_tif.h>
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 4/5] s390/idle: Introduce cpuidle for s390
2026-06-09 13:24 [PATCH v2 0/5] s390/idle: CPU idle driver Mete Durlu
` (2 preceding siblings ...)
2026-06-09 13:24 ` [PATCH v2 3/5] s390: Enable TIF_POLLING_NRFLAG Mete Durlu
@ 2026-06-09 13:24 ` Mete Durlu
2026-06-09 13:24 ` [PATCH v2 5/5] s390/configs: Enable cpuidle driver on s390 Mete Durlu
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Mete Durlu @ 2026-06-09 13:24 UTC (permalink / raw)
To: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Anna-Maria Behnsen, Frederic Weisbecker, Ingo Molnar,
Thomas Gleixner, Rafael J. Wysocki, Daniel Lezcano,
Christian Loehle
Cc: Mete Durlu, Christian Borntraeger, Ilya Leoshkevich, linux-s390,
linux-kernel, linux-pm
Introduce generic cpuidle driver on s390. Use a two stage approach to
handle idle scenarios and use TEO governor for idle stage selection.
Two stages are, from shallow to deep, idle polling and enabled wait.
Suggested-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Suggested-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
---
MAINTAINERS | 8 ++++
arch/s390/Kconfig | 5 ++
drivers/cpuidle/Kconfig | 5 ++
drivers/cpuidle/Kconfig.s390 | 11 +++++
drivers/cpuidle/Makefile | 4 ++
drivers/cpuidle/cpuidle-s390.c | 104 +++++++++++++++++++++++++++++++++++++++++
6 files changed, 137 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index e035a3be797c..127e32c5fb4e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6766,6 +6766,13 @@ L: linux-riscv@lists.infradead.org
S: Maintained
F: drivers/cpuidle/cpuidle-riscv-sbi.c
+CPUIDLE DRIVER - S390
+M: Mete Durlu <meted@linux.ibm.com>
+L: linux-pm@vger.kernel.org
+L: linux-s390@vger.kernel.org
+S: Maintained
+F: drivers/cpuidle/cpuidle-s390.c
+
CPUMASK API [RUST]
M: Viresh Kumar <viresh.kumar@linaro.org>
R: Yury Norov <yury.norov@gmail.com>
@@ -23497,6 +23504,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git
F: Documentation/driver-api/s390-drivers.rst
F: Documentation/arch/s390/
F: arch/s390/
+F: drivers/cpuidle/cpuidle-s390.c
F: drivers/s390/
F: drivers/watchdog/diag288_wdt.c
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index ecbcbb781e40..8548f5b6b247 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -20,6 +20,9 @@ config ARCH_HAS_ILOG2_U64
config ARCH_PROC_KCORE_TEXT
def_bool y
+config ARCH_HAS_CPU_RELAX
+ def_bool y
+
config GENERIC_HWEIGHT
def_bool !HAVE_MARCH_Z196_FEATURES
@@ -708,6 +711,8 @@ config KERNEL_IMAGE_BASE
endmenu
+source "drivers/cpuidle/Kconfig"
+
menu "Memory setup"
config ARCH_SPARSEMEM_ENABLE
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index d6d8386d3f02..00e2562041fd 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -71,6 +71,11 @@ depends on RISCV
source "drivers/cpuidle/Kconfig.riscv"
endmenu
+menu "S390 CPU Idle Drivers"
+depends on S390
+source "drivers/cpuidle/Kconfig.s390"
+endmenu
+
config HALTPOLL_CPUIDLE
tristate "Halt poll cpuidle driver"
depends on X86 && KVM_GUEST
diff --git a/drivers/cpuidle/Kconfig.s390 b/drivers/cpuidle/Kconfig.s390
new file mode 100644
index 000000000000..0b170d9a190b
--- /dev/null
+++ b/drivers/cpuidle/Kconfig.s390
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# S390 CPU Idle drivers
+#
+
+config S390_CPUIDLE
+ bool "S390 CPU idle driver"
+ default y
+ help
+ Select this option to enable processor idle state management
+ through cpuidle subsystem.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 1de9e92c5b0f..88cbc2a7aea8 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -42,3 +42,7 @@ obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o
###############################################################################
# RISC-V drivers
obj-$(CONFIG_RISCV_SBI_CPUIDLE) += cpuidle-riscv-sbi.o
+
+###############################################################################
+# S390 drivers
+obj-$(CONFIG_S390_CPUIDLE) += cpuidle-s390.o
diff --git a/drivers/cpuidle/cpuidle-s390.c b/drivers/cpuidle/cpuidle-s390.c
new file mode 100644
index 000000000000..58b738ea0150
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-s390.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * s390 generic CPU idle driver.
+ *
+ * Copyright IBM Corp. 2026
+ */
+
+#define pr_fmt(fmt) "CPUidle s390: " fmt
+
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu.h>
+#include <linux/sched/clock.h>
+
+static __cpuidle int s390_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ arch_cpu_idle();
+ return index;
+}
+
+static struct cpuidle_driver s390_cpuidle_driver = {
+ .cpumask = (struct cpumask *)cpu_present_mask,
+ .name = "s390-idle",
+ .governor = "teo",
+ .states = {
+ { /* entry 0 is for polling */},
+ {
+ .enter = s390_enter_idle,
+ .name = "IDLE",
+ .desc = "ENABLED WAIT",
+ },
+ },
+ .safe_state_index = 0,
+ .state_count = 2,
+};
+
+static int s390_cpuidle_cpu_online(unsigned int cpu)
+{
+ struct cpuidle_device *dev = &per_cpu(cpuidle_dev, cpu);
+ int rc;
+
+ if (dev->registered) {
+ cpuidle_pause_and_lock();
+ rc = cpuidle_enable_device(dev);
+ cpuidle_resume_and_unlock();
+ if (rc)
+ pr_err("Failed to enable cpuidle device on cpu %u\n", cpu);
+ } else {
+ dev->cpu = cpu;
+ rc = cpuidle_register_device(dev);
+ if (rc)
+ pr_err("Failed to register cpuidle driver on cpu %u\n", cpu);
+ }
+ return rc;
+}
+
+static int s390_cpuidle_cpu_dead(unsigned int cpu)
+{
+ struct cpuidle_device *dev = &per_cpu(cpuidle_dev, cpu);
+
+ if (!dev->registered)
+ return 0;
+ cpuidle_pause_and_lock();
+ cpuidle_disable_device(dev);
+ cpuidle_resume_and_unlock();
+ return 0;
+}
+
+static void __init s390_cpuidle_ew_tune(void)
+{
+ struct cpuidle_state *state = &s390_cpuidle_driver.states[1];
+
+ if (machine_is_lpar()) {
+ state->target_residency = 5;
+ state->exit_latency = 5;
+ } else {
+ state->target_residency = 1;
+ state->exit_latency = 1;
+ }
+}
+
+static int __init s390_cpuidle_init(void)
+{
+ int rc;
+
+ s390_cpuidle_ew_tune();
+ cpuidle_poll_state_init(&s390_cpuidle_driver);
+ rc = cpuidle_register(&s390_cpuidle_driver, NULL);
+ if (rc)
+ return rc;
+ rc = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
+ "cpuidle/s390:online",
+ s390_cpuidle_cpu_online,
+ s390_cpuidle_cpu_dead);
+ if (rc < 0) {
+ cpuidle_unregister(&s390_cpuidle_driver);
+ pr_err("Failed to allocate hotplug state: cpuidle/s390:online\n");
+ return rc;
+ }
+ return 0;
+}
+device_initcall(s390_cpuidle_init);
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 5/5] s390/configs: Enable cpuidle driver on s390
2026-06-09 13:24 [PATCH v2 0/5] s390/idle: CPU idle driver Mete Durlu
` (3 preceding siblings ...)
2026-06-09 13:24 ` [PATCH v2 4/5] s390/idle: Introduce cpuidle for s390 Mete Durlu
@ 2026-06-09 13:24 ` Mete Durlu
2026-06-09 14:11 ` [PATCH v2 0/5] s390/idle: CPU idle driver Heiko Carstens
2026-06-09 15:47 ` Christian Loehle
6 siblings, 0 replies; 9+ messages in thread
From: Mete Durlu @ 2026-06-09 13:24 UTC (permalink / raw)
To: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Anna-Maria Behnsen, Frederic Weisbecker, Ingo Molnar,
Thomas Gleixner, Rafael J. Wysocki, Daniel Lezcano,
Christian Loehle
Cc: Mete Durlu, Christian Borntraeger, Ilya Leoshkevich, linux-s390,
linux-kernel, linux-pm
Enable cpuidle infrastructure, teo governor and s390 cpuidle driver by
default. They can be disabled via config options before compile or via
setting cpuidle.off kernel commandline option. When cpuidle.off=1 set,
given architecture's specific implementation is used as a fallback without
any governor or idle state support.
During runtime individual states of cpuidle driver can also be disabled
via sysfs attributes.
Ex:
echo 1 > /sys/devices/system/cpu<N>/cpuidle/state<M>/disable
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
---
arch/s390/configs/debug_defconfig | 2 ++
arch/s390/configs/defconfig | 2 ++
2 files changed, 4 insertions(+)
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index 730c90b4a876..39f2c56bd29d 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -29,6 +29,8 @@ CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_TEO=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index dd5fc1426c88..723ce48ce8d1 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -27,6 +27,8 @@ CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_TEO=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v2 0/5] s390/idle: CPU idle driver
2026-06-09 13:24 [PATCH v2 0/5] s390/idle: CPU idle driver Mete Durlu
` (4 preceding siblings ...)
2026-06-09 13:24 ` [PATCH v2 5/5] s390/configs: Enable cpuidle driver on s390 Mete Durlu
@ 2026-06-09 14:11 ` Heiko Carstens
2026-06-09 15:47 ` Christian Loehle
6 siblings, 0 replies; 9+ messages in thread
From: Heiko Carstens @ 2026-06-09 14:11 UTC (permalink / raw)
To: Mete Durlu
Cc: Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Anna-Maria Behnsen, Frederic Weisbecker, Ingo Molnar,
Thomas Gleixner, Rafael J. Wysocki, Daniel Lezcano,
Christian Loehle, Christian Borntraeger, Ilya Leoshkevich,
linux-s390, linux-kernel, linux-pm
On Tue, Jun 09, 2026 at 03:24:20PM +0200, Mete Durlu wrote:
> v1 -> v2:
>
> * Add idle driver enteries to MAINTAINERS file (Christian Loehle)
> * Remove extra line break left in drivers/cpuidle/Kconfig.s390
> (Christian Loehle)
>
> This patch series introduces a CPU idle driver for s390
> architecture that leverages the existing cpu idle infrastructure and
> TEO (Timer Events Oriented) governor to optimize idle state selection
> based on timer events and interrupt patterns.
...
> Mete Durlu (5):
> s390/tick: Remove CIF_NOHZ_DELAY flag
> tick: Remove arch_needs_cpu
> s390: Enable TIF_POLLING_NRFLAG
> s390/idle: Introduce cpuidle for s390
> s390/configs: Enable cpuidle driver on s390
>
> MAINTAINERS | 8 +++
> arch/s390/Kconfig | 5 ++
> arch/s390/configs/debug_defconfig | 2 +
> arch/s390/configs/defconfig | 2 +
> arch/s390/include/asm/processor.h | 4 --
> arch/s390/include/asm/thread_info.h | 1 +
> arch/s390/kernel/idle.c | 1 -
> arch/s390/kernel/irq.c | 4 --
> arch/s390/kernel/smp.c | 1 -
> drivers/cpuidle/Kconfig | 5 ++
> drivers/cpuidle/Kconfig.s390 | 11 ++++
> drivers/cpuidle/Makefile | 4 ++
> drivers/cpuidle/cpuidle-s390.c | 104 ++++++++++++++++++++++++++++++++++++
> include/linux/tick.h | 3 --
> kernel/time/tick-sched.c | 7 ++-
> 15 files changed, 145 insertions(+), 17 deletions(-)
Looks all good to me.
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH v2 0/5] s390/idle: CPU idle driver
2026-06-09 13:24 [PATCH v2 0/5] s390/idle: CPU idle driver Mete Durlu
` (5 preceding siblings ...)
2026-06-09 14:11 ` [PATCH v2 0/5] s390/idle: CPU idle driver Heiko Carstens
@ 2026-06-09 15:47 ` Christian Loehle
6 siblings, 0 replies; 9+ messages in thread
From: Christian Loehle @ 2026-06-09 15:47 UTC (permalink / raw)
To: Mete Durlu, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Sven Schnelle, Anna-Maria Behnsen, Frederic Weisbecker,
Ingo Molnar, Thomas Gleixner, Rafael J. Wysocki, Daniel Lezcano
Cc: Christian Borntraeger, Ilya Leoshkevich, linux-s390, linux-kernel,
linux-pm
On 6/9/26 14:24, Mete Durlu wrote:
> v1 -> v2:
>
> * Add idle driver enteries to MAINTAINERS file (Christian Loehle)
> * Remove extra line break left in drivers/cpuidle/Kconfig.s390
> (Christian Loehle)
>
> This patch series introduces a CPU idle driver for s390
> architecture that leverages the existing cpu idle infrastructure and
> TEO (Timer Events Oriented) governor to optimize idle state selection
> based on timer events and interrupt patterns.
So if (according to v1) there's no data (yet) that teo is much preferred,
I would remove all mentions of it in code and patch descriptions?
A cpuidle driver requiring a specific governor sort-of violates the
abstraction.
In case teo does work much better for you, which I wouldn't doubt for
a second from what your system looks like, it would be nice to present
some data on it. Additionally I think setting it in the defconfig alone
is probably enough?
>
> - Implementation Overview
> -----------------------------------------------------------------------
>
> The driver implements two idle states;
>
> **Polling Idle (shallow state)**
> - Busy-loop implementation that prevents SIE-exit during short idle periods
> - Zero exit latency, optimized for latency-sensitive workloads
> - Maintains CPU with the guest, improving response times
>
> **Enabled Wait (deep state)**
> - Traditional EW state that signals hypervisor availability
> - Higher exit latency but more efficient for longer idle periods
>
> The TEO governor dynamically selects between these states by monitoring
> next timer interrupts and system interrupt frequency, choosing the most
> appropriate idle state for each situation.
>
> - Performance Benefits
> -----------------------------------------------------------------------
>
> Benchmark results across LPAR, KVM, and z/VM guests demonstrate significant
> improvements for latency-sensitive and scheduler-intensive workloads:
>
> ```
> Benchmark | LPAR | z/VM | KVM |
> -----------------------------------------
> cyclictest | +45% | +50% | +30% |
> hackbench | +5% | +12% | - |
> pgbench | +2% | +15% | +2% |
> uperf | +50%* | +-5% | +-5% |
> ```
>
> *Single-threaded uperf scenarios show 50-70% improvements on LPAR.
> Multi-threaded results show slight improvements overall.
>
> Additionally, fio and ioping tests show latency distribution shifts toward
> lower values with reduced minimum and average latencies.
>
> - Configuration
> -----------------------------------------------------------------------
>
> Idle state parameters are tuned per hypervisor type after benchmarks:
>
> **LPAR:**
> - Polling: 5us target residency, 0us exit latency
> - EW: 5us target residency, 5us exit latency
>
> **KVM/z/VM:**
> - Polling: 1us target residency, 0us exit latency
> - EW: 1us target residency, 1us exit latency
>
I think this would also be useful in cpuidle-s390.c in particular the
different residency+latency values for LPAR and KVM/z/VM and what they aim
to achieve for you.
Additionally polling is initialised to 0/0 by poll_state.c, so I don't know
where you're taking these values from?
^ permalink raw reply [flat|nested] 9+ messages in thread