[PATCH 04/15] powerpc/time: Prepare to stop elapsing in dynticks-idle
Christophe Leroy (CS GROUP)
chleroy at kernel.org
Thu Feb 26 04:53:50 AEDT 2026
Le 16/01/2026 à 15:51, Frederic Weisbecker a écrit :
> Currently the tick subsystem stores the idle cputime accounting in
> private fields, allowing cohabitation with architecture idle vtime
> accounting. The former is fetched on online CPUs, the latter on offline
> CPUs.
>
> For consolidation purpose, architecture vtime accounting will continue
> to account the cputime but will make a break when the idle tick is
> stopped. The dyntick cputime accounting will then be relayed by the tick
> subsystem so that the idle cputime is still seen advancing coherently
> even when the tick isn't there to flush the idle vtime.
>
> Prepare for that and introduce three new APIs which will be used in
> subsequent patches:
>
> _ vtime_dynticks_start() is deemed to be called when idle enters in
> dyntick mode. The idle cputime that elapsed so far is accumulated.
>
> - vtime_dynticks_stop() is deemed to be called when idle exits from
> dyntick mode. The vtime entry clocks are fast-forward to current time
> so that idle accounting restarts elapsing from now.
>
> - vtime_reset() is deemed to be called from dynticks idle IRQ entry to
> fast-forward the clock to current time so that the IRQ time is still
> accounted by vtime while nohz cputime is paused.
>
> Also accumulated vtime won't be flushed from dyntick-idle ticks to avoid
> accounting twice the idle cputime, along with nohz accounting.
>
> Signed-off-by: Frederic Weisbecker <frederic at kernel.org>
> ---
> arch/powerpc/kernel/time.c | 41 ++++++++++++++++++++++++++++++++++++++
> include/linux/vtime.h | 6 ++++++
> 2 files changed, 47 insertions(+)
>
> diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
> index 4bbeb8644d3d..9b3167274653 100644
> --- a/arch/powerpc/kernel/time.c
> +++ b/arch/powerpc/kernel/time.c
> @@ -376,6 +376,47 @@ void vtime_task_switch(struct task_struct *prev)
> acct->starttime = acct0->starttime;
> }
> }
> +
> +#ifdef CONFIG_NO_HZ_COMMON
> +/**
> + * vtime_reset - Fast forward vtime entry clocks
> + *
> + * Called from dynticks idle IRQ entry to fast-forward the clocks to current time
> + * so that the IRQ time is still accounted by vtime while nohz cputime is paused.
> + */
> +void vtime_reset(void)
> +{
> + struct cpu_accounting_data *acct = get_accounting(current);
> +
> + acct->starttime = mftb();
> +#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
> + acct->startspurr = read_spurr(now);
'now' doesn't exist.
> +#endif
> +}
> +
> +/**
> + * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
> + *
> + * Called when idle enters in dyntick mode. The idle cputime that elapsed so far
> + * is accumulated and the tick subsystem takes over the idle cputime accounting.
> + */
> +void vtime_dyntick_start(void)
> +{
> + vtime_account_idle(current);
> +}
> +
> +/**
> + * vtime_dyntick_stop - Inform vtime about exit from idle-dynticks
> + *
> + * Called when idle exits from dyntick mode. The vtime entry clocks are
> + * fast-forward to current time so that idle accounting restarts elapsing from
> + * now.
> + */
> +void vtime_dyntick_stop(void)
> +{
> + vtime_reset();
> +}
> +#endif /* CONFIG_NO_HZ_COMMON */
> #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
>
> void __no_kcsan __delay(unsigned long loops)
> diff --git a/include/linux/vtime.h b/include/linux/vtime.h
> index 737930f66c3e..10cdb08f960b 100644
> --- a/include/linux/vtime.h
> +++ b/include/linux/vtime.h
> @@ -37,11 +37,17 @@ extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset);
> extern void vtime_account_softirq(struct task_struct *tsk);
> extern void vtime_account_hardirq(struct task_struct *tsk);
> extern void vtime_flush(struct task_struct *tsk);
> +extern void vtime_reset(void);
> +extern void vtime_dyntick_start(void);
> +extern void vtime_dyntick_stop(void);
extern keyword is pointless for function prototypes, we should refrain
to add new ones.
> #else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
> static inline void vtime_account_irq(struct task_struct *tsk, unsigned int offset) { }
> static inline void vtime_account_softirq(struct task_struct *tsk) { }
> static inline void vtime_account_hardirq(struct task_struct *tsk) { }
> static inline void vtime_flush(struct task_struct *tsk) { }
> +static inline void vtime_reset(void) { }
> +static inline void vtime_dyntick_start(void) { }
> +extern inline void vtime_dyntick_stop(void) { }
Why extern for that one ?
> #endif
>
> /*
More information about the Linuxppc-dev
mailing list