aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2013-07-11 21:10:15 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2013-08-14 11:14:54 -0400
commitb04934061330a4a449cfce703c97d887c3e11cd7 (patch)
tree5f031cb20338cc3972e7339be17046553b186573
parenta5725ac23bf4ff79656ac2c317c323e261327fb3 (diff)
vtime: Optimize full dynticks accounting off case with static keys
If no CPU is in the full dynticks range, we can avoid the full dynticks cputime accounting through generic vtime along with its overhead and use the traditional tick based accounting instead. Let's do this and nope the off case with static keys. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Li Zhong <zhong@linux.vnet.ibm.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Kevin Hilman <khilman@linaro.org>
-rw-r--r--include/linux/context_tracking.h6
-rw-r--r--include/linux/vtime.h70
-rw-r--r--kernel/sched/cputime.c22
3 files changed, 67 insertions, 31 deletions
diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h
index 82ec4870e064..158158704c30 100644
--- a/include/linux/context_tracking.h
+++ b/include/linux/context_tracking.h
@@ -74,8 +74,7 @@ static inline void context_tracking_init(void) { }
74#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN 74#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
75static inline void guest_enter(void) 75static inline void guest_enter(void)
76{ 76{
77 if (static_key_false(&context_tracking_enabled) && 77 if (vtime_accounting_enabled())
78 vtime_accounting_enabled())
79 vtime_guest_enter(current); 78 vtime_guest_enter(current);
80 else 79 else
81 current->flags |= PF_VCPU; 80 current->flags |= PF_VCPU;
@@ -83,8 +82,7 @@ static inline void guest_enter(void)
83 82
84static inline void guest_exit(void) 83static inline void guest_exit(void)
85{ 84{
86 if (static_key_false(&context_tracking_enabled) && 85 if (vtime_accounting_enabled())
87 vtime_accounting_enabled())
88 vtime_guest_exit(current); 86 vtime_guest_exit(current);
89 else 87 else
90 current->flags &= ~PF_VCPU; 88 current->flags &= ~PF_VCPU;
diff --git a/include/linux/vtime.h b/include/linux/vtime.h
index 2ad073915e8c..f5b72b364bda 100644
--- a/include/linux/vtime.h
+++ b/include/linux/vtime.h
@@ -1,22 +1,68 @@
1#ifndef _LINUX_KERNEL_VTIME_H 1#ifndef _LINUX_KERNEL_VTIME_H
2#define _LINUX_KERNEL_VTIME_H 2#define _LINUX_KERNEL_VTIME_H
3 3
4#include <linux/context_tracking_state.h>
4#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 5#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
5#include <asm/vtime.h> 6#include <asm/vtime.h>
6#endif 7#endif
7 8
9
8struct task_struct; 10struct task_struct;
9 11
12/*
13 * vtime_accounting_enabled() definitions/declarations
14 */
15#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
16static inline bool vtime_accounting_enabled(void) { return true; }
17#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
18
19#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
20static inline bool vtime_accounting_enabled(void)
21{
22 if (static_key_false(&context_tracking_enabled)) {
23 if (context_tracking_active())
24 return true;
25 }
26
27 return false;
28}
29#endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */
30
31#ifndef CONFIG_VIRT_CPU_ACCOUNTING
32static inline bool vtime_accounting_enabled(void) { return false; }
33#endif /* !CONFIG_VIRT_CPU_ACCOUNTING */
34
35
36/*
37 * Common vtime APIs
38 */
10#ifdef CONFIG_VIRT_CPU_ACCOUNTING 39#ifdef CONFIG_VIRT_CPU_ACCOUNTING
40
41#ifdef __ARCH_HAS_VTIME_TASK_SWITCH
11extern void vtime_task_switch(struct task_struct *prev); 42extern void vtime_task_switch(struct task_struct *prev);
43#else
44extern void vtime_common_task_switch(struct task_struct *prev);
45static inline void vtime_task_switch(struct task_struct *prev)
46{
47 if (vtime_accounting_enabled())
48 vtime_common_task_switch(prev);
49}
50#endif /* __ARCH_HAS_VTIME_TASK_SWITCH */
51
12extern void vtime_account_system(struct task_struct *tsk); 52extern void vtime_account_system(struct task_struct *tsk);
13extern void vtime_account_idle(struct task_struct *tsk); 53extern void vtime_account_idle(struct task_struct *tsk);
14extern void vtime_account_user(struct task_struct *tsk); 54extern void vtime_account_user(struct task_struct *tsk);
15extern void vtime_account_irq_enter(struct task_struct *tsk);
16 55
17#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 56#ifdef __ARCH_HAS_VTIME_ACCOUNT
18static inline bool vtime_accounting_enabled(void) { return true; } 57extern void vtime_account_irq_enter(struct task_struct *tsk);
19#endif 58#else
59extern void vtime_common_account_irq_enter(struct task_struct *tsk);
60static inline void vtime_account_irq_enter(struct task_struct *tsk)
61{
62 if (vtime_accounting_enabled())
63 vtime_common_account_irq_enter(tsk);
64}
65#endif /* __ARCH_HAS_VTIME_ACCOUNT */
20 66
21#else /* !CONFIG_VIRT_CPU_ACCOUNTING */ 67#else /* !CONFIG_VIRT_CPU_ACCOUNTING */
22 68
@@ -24,14 +70,20 @@ static inline void vtime_task_switch(struct task_struct *prev) { }
24static inline void vtime_account_system(struct task_struct *tsk) { } 70static inline void vtime_account_system(struct task_struct *tsk) { }
25static inline void vtime_account_user(struct task_struct *tsk) { } 71static inline void vtime_account_user(struct task_struct *tsk) { }
26static inline void vtime_account_irq_enter(struct task_struct *tsk) { } 72static inline void vtime_account_irq_enter(struct task_struct *tsk) { }
27static inline bool vtime_accounting_enabled(void) { return false; } 73#endif /* !CONFIG_VIRT_CPU_ACCOUNTING */
28#endif
29 74
30#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN 75#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
31extern void arch_vtime_task_switch(struct task_struct *tsk); 76extern void arch_vtime_task_switch(struct task_struct *tsk);
32extern void vtime_account_irq_exit(struct task_struct *tsk); 77extern void vtime_gen_account_irq_exit(struct task_struct *tsk);
33extern bool vtime_accounting_enabled(void); 78
79static inline void vtime_account_irq_exit(struct task_struct *tsk)
80{
81 if (vtime_accounting_enabled())
82 vtime_gen_account_irq_exit(tsk);
83}
84
34extern void vtime_user_enter(struct task_struct *tsk); 85extern void vtime_user_enter(struct task_struct *tsk);
86
35static inline void vtime_user_exit(struct task_struct *tsk) 87static inline void vtime_user_exit(struct task_struct *tsk)
36{ 88{
37 vtime_account_user(tsk); 89 vtime_account_user(tsk);
@@ -39,7 +91,7 @@ static inline void vtime_user_exit(struct task_struct *tsk)
39extern void vtime_guest_enter(struct task_struct *tsk); 91extern void vtime_guest_enter(struct task_struct *tsk);
40extern void vtime_guest_exit(struct task_struct *tsk); 92extern void vtime_guest_exit(struct task_struct *tsk);
41extern void vtime_init_idle(struct task_struct *tsk, int cpu); 93extern void vtime_init_idle(struct task_struct *tsk, int cpu);
42#else 94#else /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN */
43static inline void vtime_account_irq_exit(struct task_struct *tsk) 95static inline void vtime_account_irq_exit(struct task_struct *tsk)
44{ 96{
45 /* On hard|softirq exit we always account to hard|softirq cputime */ 97 /* On hard|softirq exit we always account to hard|softirq cputime */
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index b62d5c027c7e..0831b06aab97 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -378,11 +378,8 @@ static inline void irqtime_account_process_tick(struct task_struct *p, int user_
378#ifdef CONFIG_VIRT_CPU_ACCOUNTING 378#ifdef CONFIG_VIRT_CPU_ACCOUNTING
379 379
380#ifndef __ARCH_HAS_VTIME_TASK_SWITCH 380#ifndef __ARCH_HAS_VTIME_TASK_SWITCH
381void vtime_task_switch(struct task_struct *prev) 381void vtime_common_task_switch(struct task_struct *prev)
382{ 382{
383 if (!vtime_accounting_enabled())
384 return;
385
386 if (is_idle_task(prev)) 383 if (is_idle_task(prev))
387 vtime_account_idle(prev); 384 vtime_account_idle(prev);
388 else 385 else
@@ -404,11 +401,8 @@ void vtime_task_switch(struct task_struct *prev)
404 * vtime_account(). 401 * vtime_account().
405 */ 402 */
406#ifndef __ARCH_HAS_VTIME_ACCOUNT 403#ifndef __ARCH_HAS_VTIME_ACCOUNT
407void vtime_account_irq_enter(struct task_struct *tsk) 404void vtime_common_account_irq_enter(struct task_struct *tsk)
408{ 405{
409 if (!vtime_accounting_enabled())
410 return;
411
412 if (!in_interrupt()) { 406 if (!in_interrupt()) {
413 /* 407 /*
414 * If we interrupted user, context_tracking_in_user() 408 * If we interrupted user, context_tracking_in_user()
@@ -428,7 +422,7 @@ void vtime_account_irq_enter(struct task_struct *tsk)
428 } 422 }
429 vtime_account_system(tsk); 423 vtime_account_system(tsk);
430} 424}
431EXPORT_SYMBOL_GPL(vtime_account_irq_enter); 425EXPORT_SYMBOL_GPL(vtime_common_account_irq_enter);
432#endif /* __ARCH_HAS_VTIME_ACCOUNT */ 426#endif /* __ARCH_HAS_VTIME_ACCOUNT */
433#endif /* CONFIG_VIRT_CPU_ACCOUNTING */ 427#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
434 428
@@ -669,11 +663,8 @@ void vtime_account_system(struct task_struct *tsk)
669 write_sequnlock(&tsk->vtime_seqlock); 663 write_sequnlock(&tsk->vtime_seqlock);
670} 664}
671 665
672void vtime_account_irq_exit(struct task_struct *tsk) 666void vtime_gen_account_irq_exit(struct task_struct *tsk)
673{ 667{
674 if (!vtime_accounting_enabled())
675 return;
676
677 write_seqlock(&tsk->vtime_seqlock); 668 write_seqlock(&tsk->vtime_seqlock);
678 if (context_tracking_in_user()) 669 if (context_tracking_in_user())
679 tsk->vtime_snap_whence = VTIME_USER; 670 tsk->vtime_snap_whence = VTIME_USER;
@@ -732,11 +723,6 @@ void vtime_account_idle(struct task_struct *tsk)
732 account_idle_time(delta_cpu); 723 account_idle_time(delta_cpu);
733} 724}
734 725
735bool vtime_accounting_enabled(void)
736{
737 return context_tracking_active();
738}
739
740void arch_vtime_task_switch(struct task_struct *prev) 726void arch_vtime_task_switch(struct task_struct *prev)
741{ 727{
742 write_seqlock(&prev->vtime_seqlock); 728 write_seqlock(&prev->vtime_seqlock);