Commit abcff86d authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman

powerpc/time: Only set CONFIG_ARCH_HAS_SCALED_CPUTIME on PPC64

scaled cputime is only meaningfull when the processor has
SPURR and/or PURR, which means only on PPC64.

Removing it on PPC32 significantly reduces the size of
vtime_account_system() and vtime_account_idle() on an 8xx:

Before:
00000000 l     F .text	000000a8 vtime_delta
00000280 g     F .text	0000010c vtime_account_system
0000038c g     F .text	00000048 vtime_account_idle

After:
(vtime_delta gets inlined inside the two functions)
000001d8 g     F .text	000000a0 vtime_account_system
00000278 g     F .text	00000038 vtime_account_idle

In terms of performance, we also get approximatly 7% improvement on
task switch. The following small benchmark app is run with perf stat:

void *thread(void *arg)
{
	int i;

	for (i = 0; i < atoi((char*)arg); i++)
		pthread_yield();
}

int main(int argc, char **argv)
{
	pthread_t th1, th2;

	pthread_create(&th1, NULL, thread, argv[1]);
	pthread_create(&th2, NULL, thread, argv[1]);
	pthread_join(th1, NULL);
	pthread_join(th2, NULL);

	return 0;
}

Before the patch:

 Performance counter stats for 'chrt -f 98 ./sched 100000' (50 runs):

       8228.476465      task-clock (msec)         #    0.954 CPUs utilized            ( +-  0.23% )
            200004      context-switches          #    0.024 M/sec                    ( +-  0.00% )

After the patch:

 Performance counter stats for 'chrt -f 98 ./sched 100000' (50 runs):

       7649.070444      task-clock (msec)         #    0.955 CPUs utilized            ( +-  0.27% )
            200004      context-switches          #    0.026 M/sec                    ( +-  0.00% )
Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent b38a181c
...@@ -137,7 +137,7 @@ config PPC ...@@ -137,7 +137,7 @@ config PPC
select ARCH_HAS_PMEM_API if PPC64 select ARCH_HAS_PMEM_API if PPC64
select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_MEMBARRIER_CALLBACKS select ARCH_HAS_MEMBARRIER_CALLBACKS
select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC64
select ARCH_HAS_SG_CHAIN select ARCH_HAS_SG_CHAIN
select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION) select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION)
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
......
...@@ -15,8 +15,10 @@ struct cpu_accounting_data { ...@@ -15,8 +15,10 @@ struct cpu_accounting_data {
/* Accumulated cputime values to flush on ticks*/ /* Accumulated cputime values to flush on ticks*/
unsigned long utime; unsigned long utime;
unsigned long stime; unsigned long stime;
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
unsigned long utime_scaled; unsigned long utime_scaled;
unsigned long stime_scaled; unsigned long stime_scaled;
#endif
unsigned long gtime; unsigned long gtime;
unsigned long hardirq_time; unsigned long hardirq_time;
unsigned long softirq_time; unsigned long softirq_time;
...@@ -25,8 +27,10 @@ struct cpu_accounting_data { ...@@ -25,8 +27,10 @@ struct cpu_accounting_data {
/* Internal counters */ /* Internal counters */
unsigned long starttime; /* TB value snapshot */ unsigned long starttime; /* TB value snapshot */
unsigned long starttime_user; /* TB value on exit to usermode */ unsigned long starttime_user; /* TB value on exit to usermode */
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
unsigned long startspurr; /* SPURR value snapshot */ unsigned long startspurr; /* SPURR value snapshot */
unsigned long utime_sspurr; /* ->user_time when ->startspurr set */ unsigned long utime_sspurr; /* ->user_time when ->startspurr set */
#endif
}; };
#endif #endif
...@@ -61,7 +61,6 @@ static inline void arch_vtime_task_switch(struct task_struct *prev) ...@@ -61,7 +61,6 @@ static inline void arch_vtime_task_switch(struct task_struct *prev)
struct cpu_accounting_data *acct0 = get_accounting(prev); struct cpu_accounting_data *acct0 = get_accounting(prev);
acct->starttime = acct0->starttime; acct->starttime = acct0->starttime;
acct->startspurr = acct0->startspurr;
} }
#endif #endif
......
...@@ -176,7 +176,7 @@ static void calc_cputime_factors(void) ...@@ -176,7 +176,7 @@ static void calc_cputime_factors(void)
* Read the SPURR on systems that have it, otherwise the PURR, * Read the SPURR on systems that have it, otherwise the PURR,
* or if that doesn't exist return the timebase value passed in. * or if that doesn't exist return the timebase value passed in.
*/ */
static unsigned long read_spurr(unsigned long tb) static inline unsigned long read_spurr(unsigned long tb)
{ {
if (cpu_has_feature(CPU_FTR_SPURR)) if (cpu_has_feature(CPU_FTR_SPURR))
return mfspr(SPRN_SPURR); return mfspr(SPRN_SPURR);
...@@ -285,7 +285,8 @@ static inline u64 calculate_stolen_time(u64 stop_tb) ...@@ -285,7 +285,8 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
static unsigned long vtime_delta_scaled(struct cpu_accounting_data *acct, static unsigned long vtime_delta_scaled(struct cpu_accounting_data *acct,
unsigned long now, unsigned long stime) unsigned long now, unsigned long stime)
{ {
unsigned long stime_scaled; unsigned long stime_scaled = 0;
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
unsigned long nowscaled, deltascaled; unsigned long nowscaled, deltascaled;
unsigned long utime, utime_scaled; unsigned long utime, utime_scaled;
...@@ -316,6 +317,7 @@ static unsigned long vtime_delta_scaled(struct cpu_accounting_data *acct, ...@@ -316,6 +317,7 @@ static unsigned long vtime_delta_scaled(struct cpu_accounting_data *acct,
} }
} }
acct->utime_scaled += utime_scaled; acct->utime_scaled += utime_scaled;
#endif
return stime_scaled; return stime_scaled;
} }
...@@ -352,7 +354,9 @@ void vtime_account_system(struct task_struct *tsk) ...@@ -352,7 +354,9 @@ void vtime_account_system(struct task_struct *tsk)
if ((tsk->flags & PF_VCPU) && !irq_count()) { if ((tsk->flags & PF_VCPU) && !irq_count()) {
acct->gtime += stime; acct->gtime += stime;
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
acct->utime_scaled += stime_scaled; acct->utime_scaled += stime_scaled;
#endif
} else { } else {
if (hardirq_count()) if (hardirq_count())
acct->hardirq_time += stime; acct->hardirq_time += stime;
...@@ -361,7 +365,9 @@ void vtime_account_system(struct task_struct *tsk) ...@@ -361,7 +365,9 @@ void vtime_account_system(struct task_struct *tsk)
else else
acct->stime += stime; acct->stime += stime;
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
acct->stime_scaled += stime_scaled; acct->stime_scaled += stime_scaled;
#endif
} }
} }
EXPORT_SYMBOL_GPL(vtime_account_system); EXPORT_SYMBOL_GPL(vtime_account_system);
...@@ -378,6 +384,7 @@ void vtime_account_idle(struct task_struct *tsk) ...@@ -378,6 +384,7 @@ void vtime_account_idle(struct task_struct *tsk)
static void vtime_flush_scaled(struct task_struct *tsk, static void vtime_flush_scaled(struct task_struct *tsk,
struct cpu_accounting_data *acct) struct cpu_accounting_data *acct)
{ {
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
if (acct->utime_scaled) if (acct->utime_scaled)
tsk->utimescaled += cputime_to_nsecs(acct->utime_scaled); tsk->utimescaled += cputime_to_nsecs(acct->utime_scaled);
if (acct->stime_scaled) if (acct->stime_scaled)
...@@ -386,6 +393,7 @@ static void vtime_flush_scaled(struct task_struct *tsk, ...@@ -386,6 +393,7 @@ static void vtime_flush_scaled(struct task_struct *tsk,
acct->utime_scaled = 0; acct->utime_scaled = 0;
acct->utime_sspurr = 0; acct->utime_sspurr = 0;
acct->stime_scaled = 0; acct->stime_scaled = 0;
#endif
} }
/* /*
......
...@@ -2454,11 +2454,15 @@ static void dump_one_paca(int cpu) ...@@ -2454,11 +2454,15 @@ static void dump_one_paca(int cpu)
DUMP(p, accounting.utime, "%#-*lx"); DUMP(p, accounting.utime, "%#-*lx");
DUMP(p, accounting.stime, "%#-*lx"); DUMP(p, accounting.stime, "%#-*lx");
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
DUMP(p, accounting.utime_scaled, "%#-*lx"); DUMP(p, accounting.utime_scaled, "%#-*lx");
#endif
DUMP(p, accounting.starttime, "%#-*lx"); DUMP(p, accounting.starttime, "%#-*lx");
DUMP(p, accounting.starttime_user, "%#-*lx"); DUMP(p, accounting.starttime_user, "%#-*lx");
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
DUMP(p, accounting.startspurr, "%#-*lx"); DUMP(p, accounting.startspurr, "%#-*lx");
DUMP(p, accounting.utime_sspurr, "%#-*lx"); DUMP(p, accounting.utime_sspurr, "%#-*lx");
#endif
DUMP(p, accounting.steal_time, "%#-*lx"); DUMP(p, accounting.steal_time, "%#-*lx");
#undef DUMP #undef DUMP
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment