diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2013-07-12 13:02:30 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2013-08-12 18:40:44 -0400 |
commit | 2d854e5738cded368a0759f85b1197f5c044513d (patch) | |
tree | 14d2353e1dd594e9b695c250e3955c1da1eaf102 /include/linux/context_tracking.h | |
parent | fbb00b568bc93073452d2a0f9f06e7c33d16eece (diff) |
context_tracing: Fix guest accounting with native vtime
1) If context tracking is enabled with native vtime accounting (which
combo is useless except for dev testing), we call vtime_guest_enter()
and vtime_guest_exit() on host <-> guest switches. But those are stubs
in this configurations. As a result, cputime is not correctly flushed
on kvm context switches.
2) If context tracking runs but is disabled on some CPUs, those
CPUs end up calling __guest_enter/__guest_exit which in turn
call vtime_account_system(). We don't want to call this because we
run in tick based accounting for these CPUs.
Refactor the guest_enter/guest_exit code such that all combinations
finally work.
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>
Diffstat (limited to 'include/linux/context_tracking.h')
-rw-r--r-- | include/linux/context_tracking.h | 52 |
1 files changed, 22 insertions, 30 deletions
diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h index fc09d7b0dacf..5984f2556d13 100644 --- a/include/linux/context_tracking.h +++ b/include/linux/context_tracking.h | |||
@@ -20,25 +20,6 @@ struct context_tracking { | |||
20 | } state; | 20 | } state; |
21 | }; | 21 | }; |
22 | 22 | ||
23 | static inline void __guest_enter(void) | ||
24 | { | ||
25 | /* | ||
26 | * This is running in ioctl context so we can avoid | ||
27 | * the call to vtime_account() with its unnecessary idle check. | ||
28 | */ | ||
29 | vtime_account_system(current); | ||
30 | current->flags |= PF_VCPU; | ||
31 | } | ||
32 | |||
33 | static inline void __guest_exit(void) | ||
34 | { | ||
35 | /* | ||
36 | * This is running in ioctl context so we can avoid | ||
37 | * the call to vtime_account() with its unnecessary idle check. | ||
38 | */ | ||
39 | vtime_account_system(current); | ||
40 | current->flags &= ~PF_VCPU; | ||
41 | } | ||
42 | 23 | ||
43 | #ifdef CONFIG_CONTEXT_TRACKING | 24 | #ifdef CONFIG_CONTEXT_TRACKING |
44 | DECLARE_PER_CPU(struct context_tracking, context_tracking); | 25 | DECLARE_PER_CPU(struct context_tracking, context_tracking); |
@@ -56,9 +37,6 @@ static inline bool context_tracking_active(void) | |||
56 | extern void user_enter(void); | 37 | extern void user_enter(void); |
57 | extern void user_exit(void); | 38 | extern void user_exit(void); |
58 | 39 | ||
59 | extern void guest_enter(void); | ||
60 | extern void guest_exit(void); | ||
61 | |||
62 | static inline enum ctx_state exception_enter(void) | 40 | static inline enum ctx_state exception_enter(void) |
63 | { | 41 | { |
64 | enum ctx_state prev_ctx; | 42 | enum ctx_state prev_ctx; |
@@ -81,21 +59,35 @@ extern void context_tracking_task_switch(struct task_struct *prev, | |||
81 | static inline bool context_tracking_in_user(void) { return false; } | 59 | static inline bool context_tracking_in_user(void) { return false; } |
82 | static inline void user_enter(void) { } | 60 | static inline void user_enter(void) { } |
83 | static inline void user_exit(void) { } | 61 | static inline void user_exit(void) { } |
62 | static inline enum ctx_state exception_enter(void) { return 0; } | ||
63 | static inline void exception_exit(enum ctx_state prev_ctx) { } | ||
64 | static inline void context_tracking_task_switch(struct task_struct *prev, | ||
65 | struct task_struct *next) { } | ||
66 | #endif /* !CONFIG_CONTEXT_TRACKING */ | ||
84 | 67 | ||
68 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN | ||
69 | extern void guest_enter(void); | ||
70 | extern void guest_exit(void); | ||
71 | #else | ||
85 | static inline void guest_enter(void) | 72 | static inline void guest_enter(void) |
86 | { | 73 | { |
87 | __guest_enter(); | 74 | /* |
75 | * This is running in ioctl context so we can avoid | ||
76 | * the call to vtime_account() with its unnecessary idle check. | ||
77 | */ | ||
78 | vtime_account_system(current); | ||
79 | current->flags |= PF_VCPU; | ||
88 | } | 80 | } |
89 | 81 | ||
90 | static inline void guest_exit(void) | 82 | static inline void guest_exit(void) |
91 | { | 83 | { |
92 | __guest_exit(); | 84 | /* |
85 | * This is running in ioctl context so we can avoid | ||
86 | * the call to vtime_account() with its unnecessary idle check. | ||
87 | */ | ||
88 | vtime_account_system(current); | ||
89 | current->flags &= ~PF_VCPU; | ||
93 | } | 90 | } |
94 | 91 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */ | |
95 | static inline enum ctx_state exception_enter(void) { return 0; } | ||
96 | static inline void exception_exit(enum ctx_state prev_ctx) { } | ||
97 | static inline void context_tracking_task_switch(struct task_struct *prev, | ||
98 | struct task_struct *next) { } | ||
99 | #endif /* !CONFIG_CONTEXT_TRACKING */ | ||
100 | 92 | ||
101 | #endif | 93 | #endif |