[RFC PATCH v1] powerpc/accounting: do not account system time on transition to user.

Nicholas Piggin npiggin at gmail.com
Tue Feb 19 16:41:38 AEDT 2019


Christophe Leroy's on February 9, 2019 12:40 am:
> Time spent in kernel mode don't need to be accounted on transition
> to user space. As far as the time spent in user is known, it
> is possible to calculate the time spent in kernel by substracting
> the time spent in user.
> 
> To do so, this patch modifies vtime_delta() to substract the
> time spent in user since the last call to vtime_delta().
> 
> This patch gives a 2% improvment of null_syscall() selftest on a 83xx.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy at c-s.fr>

This looks like a clever little optimization, although I don't know
this time accounting code very well.

> ---
> But surprisingly, this patch degrades the null_syscall selftest by 20% on the 8xx. Any idea of the reason ?

I don't know microarchitecture of any of those CPUs I'm afraid.
On the 64s CPUs, mftb is what hurts.

> 
>  arch/powerpc/include/asm/accounting.h | 1 +
>  arch/powerpc/include/asm/ppc_asm.h    | 8 +-------
>  arch/powerpc/kernel/asm-offsets.c     | 8 ++------
>  arch/powerpc/kernel/time.c            | 4 +++-
>  4 files changed, 7 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/accounting.h b/arch/powerpc/include/asm/accounting.h
> index c607c5d835cc..2f1ff5f9fd7a 100644
> --- a/arch/powerpc/include/asm/accounting.h
> +++ b/arch/powerpc/include/asm/accounting.h
> @@ -27,6 +27,7 @@ struct cpu_accounting_data {
>  	/* Internal counters */
>  	unsigned long starttime;	/* TB value snapshot */
>  	unsigned long starttime_user;	/* TB value on exit to usermode */
> +	unsigned long utime_asm;
>  #ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
>  	unsigned long startspurr;	/* SPURR value snapshot */
>  	unsigned long utime_sspurr;	/* ->user_time when ->startspurr set */
> diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
> index e0637730a8e7..be17d570d484 100644
> --- a/arch/powerpc/include/asm/ppc_asm.h
> +++ b/arch/powerpc/include/asm/ppc_asm.h
> @@ -28,9 +28,8 @@
>  #define ACCOUNT_STOLEN_TIME
>  #else
>  #define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb)				\
> -	MFTB(ra);			/* get timebase */		\
>  	PPC_LL	rb, ACCOUNT_STARTTIME_USER(ptr);			\
> -	PPC_STL	ra, ACCOUNT_STARTTIME(ptr);				\
> +	MFTB(ra);			/* get timebase */		\
>  	subf	rb,rb,ra;		/* subtract start value */	\
>  	PPC_LL	ra, ACCOUNT_USER_TIME(ptr);				\
>  	add	ra,ra,rb;		/* add on to user time */	\
> @@ -38,12 +37,7 @@
>  
>  #define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb)				\
>  	MFTB(ra);			/* get timebase */		\
> -	PPC_LL	rb, ACCOUNT_STARTTIME(ptr);				\
>  	PPC_STL	ra, ACCOUNT_STARTTIME_USER(ptr);			\
> -	subf	rb,rb,ra;		/* subtract start value */	\
> -	PPC_LL	ra, ACCOUNT_SYSTEM_TIME(ptr);				\
> -	add	ra,ra,rb;		/* add on to system time */	\
> -	PPC_STL	ra, ACCOUNT_SYSTEM_TIME(ptr)
>  
>  #ifdef CONFIG_PPC_SPLPAR
>  #define ACCOUNT_STOLEN_TIME						\
> diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
> index 7a1b93c5af63..f2ba7735f56f 100644
> --- a/arch/powerpc/kernel/asm-offsets.c
> +++ b/arch/powerpc/kernel/asm-offsets.c
> @@ -260,19 +260,15 @@ int main(void)
>  	OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id);
>  	OFFSET(PACAKEXECSTATE, paca_struct, kexec_state);
>  	OFFSET(PACA_DSCR_DEFAULT, paca_struct, dscr_default);
> -	OFFSET(ACCOUNT_STARTTIME, paca_struct, accounting.starttime);
>  	OFFSET(ACCOUNT_STARTTIME_USER, paca_struct, accounting.starttime_user);
> -	OFFSET(ACCOUNT_USER_TIME, paca_struct, accounting.utime);
> -	OFFSET(ACCOUNT_SYSTEM_TIME, paca_struct, accounting.stime);
> +	OFFSET(ACCOUNT_USER_TIME, paca_struct, accounting.utime_asm);
>  	OFFSET(PACA_TRAP_SAVE, paca_struct, trap_save);
>  	OFFSET(PACA_NAPSTATELOST, paca_struct, nap_state_lost);
>  	OFFSET(PACA_SPRG_VDSO, paca_struct, sprg_vdso);
>  #else /* CONFIG_PPC64 */
>  #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
> -	OFFSET(ACCOUNT_STARTTIME, thread_info, accounting.starttime);
>  	OFFSET(ACCOUNT_STARTTIME_USER, thread_info, accounting.starttime_user);
> -	OFFSET(ACCOUNT_USER_TIME, thread_info, accounting.utime);
> -	OFFSET(ACCOUNT_SYSTEM_TIME, thread_info, accounting.stime);
> +	OFFSET(ACCOUNT_USER_TIME, thread_info, accounting.utime_asm);
>  #endif
>  #endif /* CONFIG_PPC64 */
>  
> diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
> index bc0503ef9c9c..79420643b45f 100644
> --- a/arch/powerpc/kernel/time.c
> +++ b/arch/powerpc/kernel/time.c
> @@ -331,8 +331,10 @@ static unsigned long vtime_delta(struct task_struct *tsk,
>  	WARN_ON_ONCE(!irqs_disabled());
>  
>  	now = mftb();
> -	stime = now - acct->starttime;
> +	stime = now - acct->starttime - acct->utime_asm;
>  	acct->starttime = now;
> +	acct->utime += acct->utime_asm;
> +	acct->utime_asm = 0;
>  
>  	*stime_scaled = vtime_delta_scaled(acct, now, stime);
>  
> -- 
> 2.13.3
> 
> 


More information about the Linuxppc-dev mailing list