aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2013-07-09 20:44:35 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2013-08-14 11:14:45 -0400
commitad65782fba507d91a0a98f519b59e79cac1b474c (patch)
tree72e075f00818a0e29bc0874a0ce9ae48c5784614
parent65f382fd0c8fa483713c0971de9f1dfb4cf1ad9c (diff)
context_tracking: Optimize main APIs off case with static key
Optimize user and exception entry/exit APIs with static keys. This minimize the overhead for those who enable CONFIG_NO_HZ_FULL without always using it. Having no range passed to nohz_full= should result in the probes to be nopped (at least we hope so...). If this proves not be enough in the long term, we'll need to bring an exception slow path by re-routing the exception handlers. 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.h27
-rw-r--r--kernel/context_tracking.c12
2 files changed, 28 insertions, 11 deletions
diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h
index c138c24bad1a..38ab60b3f3a6 100644
--- a/include/linux/context_tracking.h
+++ b/include/linux/context_tracking.h
@@ -38,23 +38,40 @@ static inline bool context_tracking_active(void)
38 38
39extern void context_tracking_cpu_set(int cpu); 39extern void context_tracking_cpu_set(int cpu);
40 40
41extern void user_enter(void); 41extern void context_tracking_user_enter(void);
42extern void user_exit(void); 42extern void context_tracking_user_exit(void);
43
44static inline void user_enter(void)
45{
46 if (static_key_false(&context_tracking_enabled))
47 context_tracking_user_enter();
48
49}
50static inline void user_exit(void)
51{
52 if (static_key_false(&context_tracking_enabled))
53 context_tracking_user_exit();
54}
43 55
44static inline enum ctx_state exception_enter(void) 56static inline enum ctx_state exception_enter(void)
45{ 57{
46 enum ctx_state prev_ctx; 58 enum ctx_state prev_ctx;
47 59
60 if (!static_key_false(&context_tracking_enabled))
61 return 0;
62
48 prev_ctx = this_cpu_read(context_tracking.state); 63 prev_ctx = this_cpu_read(context_tracking.state);
49 user_exit(); 64 context_tracking_user_exit();
50 65
51 return prev_ctx; 66 return prev_ctx;
52} 67}
53 68
54static inline void exception_exit(enum ctx_state prev_ctx) 69static inline void exception_exit(enum ctx_state prev_ctx)
55{ 70{
56 if (prev_ctx == IN_USER) 71 if (static_key_false(&context_tracking_enabled)) {
57 user_enter(); 72 if (prev_ctx == IN_USER)
73 context_tracking_user_enter();
74 }
58} 75}
59 76
60extern void context_tracking_task_switch(struct task_struct *prev, 77extern void context_tracking_task_switch(struct task_struct *prev,
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c
index 839d377d0da5..6e89e094c80e 100644
--- a/kernel/context_tracking.c
+++ b/kernel/context_tracking.c
@@ -33,15 +33,15 @@ void context_tracking_cpu_set(int cpu)
33} 33}
34 34
35/** 35/**
36 * user_enter - Inform the context tracking that the CPU is going to 36 * context_tracking_user_enter - Inform the context tracking that the CPU is going to
37 * enter userspace mode. 37 * enter userspace mode.
38 * 38 *
39 * This function must be called right before we switch from the kernel 39 * This function must be called right before we switch from the kernel
40 * to userspace, when it's guaranteed the remaining kernel instructions 40 * to userspace, when it's guaranteed the remaining kernel instructions
41 * to execute won't use any RCU read side critical section because this 41 * to execute won't use any RCU read side critical section because this
42 * function sets RCU in extended quiescent state. 42 * function sets RCU in extended quiescent state.
43 */ 43 */
44void user_enter(void) 44void context_tracking_user_enter(void)
45{ 45{
46 unsigned long flags; 46 unsigned long flags;
47 47
@@ -131,8 +131,8 @@ EXPORT_SYMBOL_GPL(preempt_schedule_context);
131#endif /* CONFIG_PREEMPT */ 131#endif /* CONFIG_PREEMPT */
132 132
133/** 133/**
134 * user_exit - Inform the context tracking that the CPU is 134 * context_tracking_user_exit - Inform the context tracking that the CPU is
135 * exiting userspace mode and entering the kernel. 135 * exiting userspace mode and entering the kernel.
136 * 136 *
137 * This function must be called after we entered the kernel from userspace 137 * This function must be called after we entered the kernel from userspace
138 * before any use of RCU read side critical section. This potentially include 138 * before any use of RCU read side critical section. This potentially include
@@ -141,7 +141,7 @@ EXPORT_SYMBOL_GPL(preempt_schedule_context);
141 * This call supports re-entrancy. This way it can be called from any exception 141 * This call supports re-entrancy. This way it can be called from any exception
142 * handler without needing to know if we came from userspace or not. 142 * handler without needing to know if we came from userspace or not.
143 */ 143 */
144void user_exit(void) 144void context_tracking_user_exit(void)
145{ 145{
146 unsigned long flags; 146 unsigned long flags;
147 147