diff options
author | Christophe Leroy <christophe.leroy@c-s.fr> | 2018-08-02 03:53:59 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2018-10-19 22:26:47 -0400 |
commit | abcff86df2d2ec0a0ca9470fa5d2a184af18928a (patch) | |
tree | 75fa912a58d6371828a653a393d7b766d0d4649b | |
parent | b38a181c11d0b5e84b40732dbb06cc9d68140d60 (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/Kconfig | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/accounting.h | 4 | ||||
-rw-r--r-- | arch/powerpc/include/asm/cputime.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/time.c | 12 | ||||
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 4 |
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 | */ |
179 | static unsigned long read_spurr(unsigned long tb) | 179 | static 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) | |||
285 | static unsigned long vtime_delta_scaled(struct cpu_accounting_data *acct, | 285 | static 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 | } |
367 | EXPORT_SYMBOL_GPL(vtime_account_system); | 373 | EXPORT_SYMBOL_GPL(vtime_account_system); |
@@ -378,6 +384,7 @@ void vtime_account_idle(struct task_struct *tsk) | |||
378 | static void vtime_flush_scaled(struct task_struct *tsk, | 384 | static 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 | ||