summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorStian Halseth <stian@itx.no>2026-10-07 16:29:50 +0200
committerPeter Zijlstra <peterz@infradead.org>2026-10-16 09:49:03 +0200
commit96a494c9cfd8f4bb7b1a7a70275426db71cf98aa (patch)
treea4bcb7d5a6850ee0bf4f64a52a45f01800fb3500 /include/linux
parent6f88f6cbb0472a8481ba560578a1d7c8d802eba7 (diff)
downloadlinux-96a494c9cfd8f4bb7b1a7a70275426db71cf98aa.tar.gz
linux-96a494c9cfd8f4bb7b1a7a70275426db71cf98aa.zip
sched/cputime: Don't account idle time twice after dyntick-idle
On idle exit the dyntick-idle accounting accounts the time up to now, then the tick is restarted on its old period. The first tick accounts a whole TICK_NSEC to whatever runs, although the part of that period before the idle exit has just been accounted as idle time, or with IRQ_TIME_ACCOUNTING as IRQ time. That is up to a full tick per idle exit, and /proc/stat reports more idle time than wall time. Record how much of the current tick period dyntick-idle has accounted, and leave it out of the tick that ends the period. Fixes: cf6444c3e1bb7 ("tick/sched: Unify idle cputime accounting") Signed-off-by: Stian Halseth <stian@itx.no> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Frederic Weisbecker <frederic@kernel.org> Link: https://lore.kernel.org/all/20261004142724.3896396-1-stian@itx.no/ Link: https://patch.msgid.link/20261007142950.547604-1-stian@itx.no
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/kernel_stat.h7
1 files changed, 5 insertions, 2 deletions
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index c1e85550bf12..9f0f91dc8d7d 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -40,6 +40,9 @@ struct kernel_cpustat {
seqcount_t idle_sleeptime_seq;
u64 idle_entrytime;
u64 idle_stealtime[2];
+ u64 idle_dyntick_entry;
+ u64 idle_tick_period;
+ u64 idle_tick_overlap;
#endif
u64 cpustat[NR_STATS];
};
@@ -111,7 +114,7 @@ static inline unsigned long kstat_cpu_irqs_sum(unsigned int cpu)
#ifdef CONFIG_HAVE_VIRT_CPU_ACCOUNTING_IDLE
static inline void kcpustat_dyntick_start(u64 now) { }
-static inline void kcpustat_dyntick_stop(u64 now) { }
+static inline void kcpustat_dyntick_stop(u64 now, u64 tick_start) { }
static inline void kcpustat_irq_enter(u64 now) { }
static inline void kcpustat_irq_exit(u64 now) { }
static inline bool kcpustat_idle_dyntick(void) { return false; }
@@ -132,7 +135,7 @@ static inline u64 kcpustat_field_iowait(int cpu)
#else /* !CONFIG_HAVE_VIRT_CPU_ACCOUNTING_IDLE */
extern void kcpustat_dyntick_start(u64 now);
-extern void kcpustat_dyntick_stop(u64 now);
+extern void kcpustat_dyntick_stop(u64 now, u64 tick_start);
extern void kcpustat_irq_enter(u64 now);
extern void kcpustat_irq_exit(u64 now);
extern u64 kcpustat_field_idle(int cpu);