aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@c-s.fr>2018-08-02 03:53:59 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2018-10-19 22:26:47 -0400
commitabcff86df2d2ec0a0ca9470fa5d2a184af18928a (patch)
tree75fa912a58d6371828a653a393d7b766d0d4649b
parentb38a181c11d0b5e84b40732dbb06cc9d68140d60 (diff)
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: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/include/asm/accounting.h4
-rw-r--r--arch/powerpc/include/asm/cputime.h1
-rw-r--r--arch/powerpc/kernel/time.c12
-rw-r--r--arch/powerpc/xmon/xmon.c4
5 files changed, 19 insertions, 4 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 076e05ae9b04..e84943d24e5c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -137,7 +137,7 @@ config PPC
137 select ARCH_HAS_PMEM_API if PPC64 137 select ARCH_HAS_PMEM_API if PPC64
138 select ARCH_HAS_PTE_SPECIAL 138 select ARCH_HAS_PTE_SPECIAL
139 select ARCH_HAS_MEMBARRIER_CALLBACKS 139 select ARCH_HAS_MEMBARRIER_CALLBACKS
140 select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE 140 select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC64
141 select ARCH_HAS_SG_CHAIN 141 select ARCH_HAS_SG_CHAIN
142 select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION) 142 select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION)
143 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST 143 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
diff --git a/arch/powerpc/include/asm/accounting.h b/arch/powerpc/include/asm/accounting.h
index 3abcf98ed2e0..c607c5d835cc 100644
--- a/arch/powerpc/include/asm/accounting.h
+++ b/arch/powerpc/include/asm/accounting.h
@@ -15,8 +15,10 @@ struct cpu_accounting_data {
15 /* Accumulated cputime values to flush on ticks*/ 15 /* Accumulated cputime values to flush on ticks*/
16 unsigned long utime; 16 unsigned long utime;
17 unsigned long stime; 17 unsigned long stime;
18#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
18 unsigned long utime_scaled; 19 unsigned long utime_scaled;
19 unsigned long stime_scaled; 20 unsigned long stime_scaled;
21#endif
20 unsigned long gtime; 22 unsigned long gtime;
21 unsigned long hardirq_time; 23 unsigned long hardirq_time;
22 unsigned long softirq_time; 24 unsigned long softirq_time;
@@ -25,8 +27,10 @@ struct cpu_accounting_data {
25 /* Internal counters */ 27 /* Internal counters */
26 unsigned long starttime; /* TB value snapshot */ 28 unsigned long starttime; /* TB value snapshot */
27 unsigned long starttime_user; /* TB value on exit to usermode */ 29 unsigned long starttime_user; /* TB value on exit to usermode */
30#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
28 unsigned long startspurr; /* SPURR value snapshot */ 31 unsigned long startspurr; /* SPURR value snapshot */
29 unsigned long utime_sspurr; /* ->user_time when ->startspurr set */ 32 unsigned long utime_sspurr; /* ->user_time when ->startspurr set */
33#endif
30}; 34};
31 35
32#endif 36#endif
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
index 133672744b2e..ae73dc8da2d4 100644
--- a/arch/powerpc/include/asm/cputime.h
+++ b/arch/powerpc/include/asm/cputime.h
@@ -61,7 +61,6 @@ static inline void arch_vtime_task_switch(struct task_struct *prev)
61 struct cpu_accounting_data *acct0 = get_accounting(prev); 61 struct cpu_accounting_data *acct0 = get_accounting(prev);
62 62
63 acct->starttime = acct0->starttime; 63 acct->starttime = acct0->starttime;
64 acct->startspurr = acct0->startspurr;
65} 64}
66#endif 65#endif
67 66
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index cf0d5c2834d0..9289fac75af7 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -176,7 +176,7 @@ static void calc_cputime_factors(void)
176 * Read the SPURR on systems that have it, otherwise the PURR, 176 * Read the SPURR on systems that have it, otherwise the PURR,
177 * or if that doesn't exist return the timebase value passed in. 177 * or if that doesn't exist return the timebase value passed in.
178 */ 178 */
179static unsigned long read_spurr(unsigned long tb) 179static inline unsigned long read_spurr(unsigned long tb)
180{ 180{
181 if (cpu_has_feature(CPU_FTR_SPURR)) 181 if (cpu_has_feature(CPU_FTR_SPURR))
182 return mfspr(SPRN_SPURR); 182 return mfspr(SPRN_SPURR);
@@ -285,7 +285,8 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
285static unsigned long vtime_delta_scaled(struct cpu_accounting_data *acct, 285static unsigned long vtime_delta_scaled(struct cpu_accounting_data *acct,
286 unsigned long now, unsigned long stime) 286 unsigned long now, unsigned long stime)
287{ 287{
288 unsigned long stime_scaled; 288 unsigned long stime_scaled = 0;
289#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
289 unsigned long nowscaled, deltascaled; 290 unsigned long nowscaled, deltascaled;
290 unsigned long utime, utime_scaled; 291 unsigned long utime, utime_scaled;
291 292
@@ -316,6 +317,7 @@ static unsigned long vtime_delta_scaled(struct cpu_accounting_data *acct,
316 } 317 }
317 } 318 }
318 acct->utime_scaled += utime_scaled; 319 acct->utime_scaled += utime_scaled;
320#endif
319 321
320 return stime_scaled; 322 return stime_scaled;
321} 323}
@@ -352,7 +354,9 @@ void vtime_account_system(struct task_struct *tsk)
352 354
353 if ((tsk->flags & PF_VCPU) && !irq_count()) { 355 if ((tsk->flags & PF_VCPU) && !irq_count()) {
354 acct->gtime += stime; 356 acct->gtime += stime;
357#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
355 acct->utime_scaled += stime_scaled; 358 acct->utime_scaled += stime_scaled;
359#endif
356 } else { 360 } else {
357 if (hardirq_count()) 361 if (hardirq_count())
358 acct->hardirq_time += stime; 362 acct->hardirq_time += stime;
@@ -361,7 +365,9 @@ void vtime_account_system(struct task_struct *tsk)
361 else 365 else
362 acct->stime += stime; 366 acct->stime += stime;
363 367
368#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
364 acct->stime_scaled += stime_scaled; 369 acct->stime_scaled += stime_scaled;
370#endif
365 } 371 }
366} 372}
367EXPORT_SYMBOL_GPL(vtime_account_system); 373EXPORT_SYMBOL_GPL(vtime_account_system);
@@ -378,6 +384,7 @@ void vtime_account_idle(struct task_struct *tsk)
378static void vtime_flush_scaled(struct task_struct *tsk, 384static void vtime_flush_scaled(struct task_struct *tsk,
379 struct cpu_accounting_data *acct) 385 struct cpu_accounting_data *acct)
380{ 386{
387#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
381 if (acct->utime_scaled) 388 if (acct->utime_scaled)
382 tsk->utimescaled += cputime_to_nsecs(acct->utime_scaled); 389 tsk->utimescaled += cputime_to_nsecs(acct->utime_scaled);
383 if (acct->stime_scaled) 390 if (acct->stime_scaled)
@@ -386,6 +393,7 @@ static void vtime_flush_scaled(struct task_struct *tsk,
386 acct->utime_scaled = 0; 393 acct->utime_scaled = 0;
387 acct->utime_sspurr = 0; 394 acct->utime_sspurr = 0;
388 acct->stime_scaled = 0; 395 acct->stime_scaled = 0;
396#endif
389} 397}
390 398
391/* 399/*
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 58e67b67a97c..36b8dc47a3c3 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2454,11 +2454,15 @@ static void dump_one_paca(int cpu)
2454 2454
2455 DUMP(p, accounting.utime, "%#-*lx"); 2455 DUMP(p, accounting.utime, "%#-*lx");
2456 DUMP(p, accounting.stime, "%#-*lx"); 2456 DUMP(p, accounting.stime, "%#-*lx");
2457#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2457 DUMP(p, accounting.utime_scaled, "%#-*lx"); 2458 DUMP(p, accounting.utime_scaled, "%#-*lx");
2459#endif
2458 DUMP(p, accounting.starttime, "%#-*lx"); 2460 DUMP(p, accounting.starttime, "%#-*lx");
2459 DUMP(p, accounting.starttime_user, "%#-*lx"); 2461 DUMP(p, accounting.starttime_user, "%#-*lx");
2462#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2460 DUMP(p, accounting.startspurr, "%#-*lx"); 2463 DUMP(p, accounting.startspurr, "%#-*lx");
2461 DUMP(p, accounting.utime_sspurr, "%#-*lx"); 2464 DUMP(p, accounting.utime_sspurr, "%#-*lx");
2465#endif
2462 DUMP(p, accounting.steal_time, "%#-*lx"); 2466 DUMP(p, accounting.steal_time, "%#-*lx");
2463#undef DUMP 2467#undef DUMP
2464 2468