diff options
| author | Heiko Carstens <hca@linux.ibm.com> | 2026-05-13 16:01:28 +0200 |
|---|---|---|
| committer | Alexander Gordeev <agordeev@linux.ibm.com> | 2026-06-15 16:33:40 +0200 |
| commit | 670e057744e0cc8047bf96d15d18c46e16ae2e93 (patch) | |
| tree | 9cf364ebd26c84e9208ecc8f5febe224d71645b8 /kernel | |
| parent | 4fe307f0f5c1fa6afff9175f59930dcd39ee99fd (diff) | |
| download | linux-670e057744e0cc8047bf96d15d18c46e16ae2e93.tar.gz linux-670e057744e0cc8047bf96d15d18c46e16ae2e93.zip | |
s390/idle: Provide arch specific kcpustat_field_idle()/kcpustat_field_iowait()
The former s390 specific arch_cpu_idle_time() implementation was
removed, since its implementation was racy and reported idle time
could go backwards [1].
However this removal was not necessary, since independently of the s390
architecture specific races there exists the iowait counter update race,
which can also lead to reported idle time going backwards [2].
With Frederic Weisbecker's recent cpu idle time accounting refactoring
kernel_cpustat got a sequence counter. Use this to implement s390 specific
variants of kcpustat_field_idle() and kcpustat_field_iowait(). This is
logically a revert of [1] and moves cpu idle time accounting back into s390
architecture code, which is also more precise than the dyntick idle time
accounting by nohz/scheduler.
For comparing cross cpu time stamps it is necessary to use the stcke
instead of the stckf instruction in irq entry path. Furthermore this
open-codes a sequence lock in assembler and C code, which is required to
update the irq entry time stamp to the per cpu idle_data structure in a
race free manner.
[1] commit be76ea614460 ("s390/idle: remove arch_cpu_idle_time() and corresponding code")
[2] commit ead70b752373 ("timers/nohz: Add a comment about broken iowait counter update race")
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Acked-by: Frederic Weisbecker <frederic@kernel.org>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched/cputime.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 244b57417240..ed49a1e23d17 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -421,7 +421,7 @@ static inline void irqtime_account_process_tick(struct task_struct *p, int user_ int nr_ticks) { } #endif /* !CONFIG_IRQ_TIME_ACCOUNTING */ -#ifdef CONFIG_NO_HZ_COMMON +#if defined(CONFIG_NO_HZ_COMMON) && !defined(CONFIG_HAVE_VIRT_CPU_ACCOUNTING_IDLE) static void kcpustat_idle_stop(struct kernel_cpustat *kc, u64 now) { u64 *cpustat = kc->cpustat; @@ -560,7 +560,7 @@ static u64 kcpustat_field_dyntick(int cpu, enum cpu_usage_stat idx, { return kcpustat_cpu(cpu).cpustat[idx]; } -#endif /* CONFIG_NO_HZ_COMMON */ +#endif /* CONFIG_NO_HZ_COMMON && !CONFIG_HAVE_VIRT_CPU_ACCOUNTING_IDLE */ static u64 get_cpu_sleep_time_us(int cpu, enum cpu_usage_stat idx, bool compute_delta, u64 *last_update_time) |
