aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2012-07-20 11:04:44 -0400
committerSteven Rostedt <rostedt@goodmis.org>2012-07-31 10:29:52 -0400
commit4740974a6844156c14d741b0080b59d275679a23 (patch)
tree7272f577c74a185d9fe037a424d0401e4ec7c126 /kernel/trace
parent5767cfeaa9ec7b67c802143394f3ad9f8b174eb8 (diff)
ftrace: Add default recursion protection for function tracing
As more users of the function tracer utility are being added, they do not always add the necessary recursion protection. To protect from function recursion due to tracing, if the callback ftrace_ops does not specifically specify that it protects against recursion (by setting the FTRACE_OPS_FL_RECURSION_SAFE flag), the list operation will be called by the mcount trampoline which adds recursion protection. If the flag is set, then the function will be called directly with no extra protection. Note, the list operation is called if more than one function callback is registered, or if the arch does not support all of the function tracer features. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/ftrace.c10
-rw-r--r--kernel/trace/trace_events.c1
-rw-r--r--kernel/trace/trace_functions.c4
-rw-r--r--kernel/trace/trace_irqsoff.c2
-rw-r--r--kernel/trace/trace_sched_wakeup.c2
-rw-r--r--kernel/trace/trace_selftest.c7
-rw-r--r--kernel/trace/trace_stack.c1
7 files changed, 19 insertions, 8 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index c55f7e274613..ad765b4ba426 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -66,6 +66,7 @@
66 66
67static struct ftrace_ops ftrace_list_end __read_mostly = { 67static struct ftrace_ops ftrace_list_end __read_mostly = {
68 .func = ftrace_stub, 68 .func = ftrace_stub,
69 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
69}; 70};
70 71
71/* ftrace_enabled is a method to turn ftrace on or off */ 72/* ftrace_enabled is a method to turn ftrace on or off */
@@ -221,12 +222,13 @@ static void update_ftrace_function(void)
221 222
222 /* 223 /*
223 * If we are at the end of the list and this ops is 224 * If we are at the end of the list and this ops is
224 * not dynamic and the arch supports passing ops, then have the 225 * recursion safe and not dynamic and the arch supports passing ops,
225 * mcount trampoline call the function directly. 226 * then have the mcount trampoline call the function directly.
226 */ 227 */
227 if (ftrace_ops_list == &ftrace_list_end || 228 if (ftrace_ops_list == &ftrace_list_end ||
228 (ftrace_ops_list->next == &ftrace_list_end && 229 (ftrace_ops_list->next == &ftrace_list_end &&
229 !(ftrace_ops_list->flags & FTRACE_OPS_FL_DYNAMIC) && 230 !(ftrace_ops_list->flags & FTRACE_OPS_FL_DYNAMIC) &&
231 (ftrace_ops_list->flags & FTRACE_OPS_FL_RECURSION_SAFE) &&
230 !FTRACE_FORCE_LIST_FUNC)) { 232 !FTRACE_FORCE_LIST_FUNC)) {
231 /* Set the ftrace_ops that the arch callback uses */ 233 /* Set the ftrace_ops that the arch callback uses */
232 if (ftrace_ops_list == &global_ops) 234 if (ftrace_ops_list == &global_ops)
@@ -867,6 +869,7 @@ static void unregister_ftrace_profiler(void)
867#else 869#else
868static struct ftrace_ops ftrace_profile_ops __read_mostly = { 870static struct ftrace_ops ftrace_profile_ops __read_mostly = {
869 .func = function_profile_call, 871 .func = function_profile_call,
872 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
870}; 873};
871 874
872static int register_ftrace_profiler(void) 875static int register_ftrace_profiler(void)
@@ -1049,6 +1052,7 @@ static struct ftrace_ops global_ops = {
1049 .func = ftrace_stub, 1052 .func = ftrace_stub,
1050 .notrace_hash = EMPTY_HASH, 1053 .notrace_hash = EMPTY_HASH,
1051 .filter_hash = EMPTY_HASH, 1054 .filter_hash = EMPTY_HASH,
1055 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
1052}; 1056};
1053 1057
1054static DEFINE_MUTEX(ftrace_regex_lock); 1058static DEFINE_MUTEX(ftrace_regex_lock);
@@ -3967,6 +3971,7 @@ void __init ftrace_init(void)
3967 3971
3968static struct ftrace_ops global_ops = { 3972static struct ftrace_ops global_ops = {
3969 .func = ftrace_stub, 3973 .func = ftrace_stub,
3974 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
3970}; 3975};
3971 3976
3972static int __init ftrace_nodyn_init(void) 3977static int __init ftrace_nodyn_init(void)
@@ -4023,6 +4028,7 @@ ftrace_ops_control_func(unsigned long ip, unsigned long parent_ip,
4023 4028
4024static struct ftrace_ops control_ops = { 4029static struct ftrace_ops control_ops = {
4025 .func = ftrace_ops_control_func, 4030 .func = ftrace_ops_control_func,
4031 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
4026}; 4032};
4027 4033
4028static inline void 4034static inline void
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 8c6696833686..6825d833a257 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -1721,6 +1721,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip,
1721static struct ftrace_ops trace_ops __initdata = 1721static struct ftrace_ops trace_ops __initdata =
1722{ 1722{
1723 .func = function_test_events_call, 1723 .func = function_test_events_call,
1724 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
1724}; 1725};
1725 1726
1726static __init void event_trace_self_test_with_function(void) 1727static __init void event_trace_self_test_with_function(void)
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 5675ebd541f0..fdff65dff1bb 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -153,13 +153,13 @@ function_stack_trace_call(unsigned long ip, unsigned long parent_ip,
153static struct ftrace_ops trace_ops __read_mostly = 153static struct ftrace_ops trace_ops __read_mostly =
154{ 154{
155 .func = function_trace_call, 155 .func = function_trace_call,
156 .flags = FTRACE_OPS_FL_GLOBAL, 156 .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
157}; 157};
158 158
159static struct ftrace_ops trace_stack_ops __read_mostly = 159static struct ftrace_ops trace_stack_ops __read_mostly =
160{ 160{
161 .func = function_stack_trace_call, 161 .func = function_stack_trace_call,
162 .flags = FTRACE_OPS_FL_GLOBAL, 162 .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
163}; 163};
164 164
165/* Our two options */ 165/* Our two options */
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index c7a9ba936de6..d98ee8283b29 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -154,7 +154,7 @@ irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip,
154static struct ftrace_ops trace_ops __read_mostly = 154static struct ftrace_ops trace_ops __read_mostly =
155{ 155{
156 .func = irqsoff_tracer_call, 156 .func = irqsoff_tracer_call,
157 .flags = FTRACE_OPS_FL_GLOBAL, 157 .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
158}; 158};
159#endif /* CONFIG_FUNCTION_TRACER */ 159#endif /* CONFIG_FUNCTION_TRACER */
160 160
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index 7547e36d483e..02170c00c413 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -130,7 +130,7 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip,
130static struct ftrace_ops trace_ops __read_mostly = 130static struct ftrace_ops trace_ops __read_mostly =
131{ 131{
132 .func = wakeup_tracer_call, 132 .func = wakeup_tracer_call,
133 .flags = FTRACE_OPS_FL_GLOBAL, 133 .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
134}; 134};
135#endif /* CONFIG_FUNCTION_TRACER */ 135#endif /* CONFIG_FUNCTION_TRACER */
136 136
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index add37e019fd0..1fb6da85ff8b 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -148,19 +148,22 @@ static void trace_selftest_test_dyn_func(unsigned long ip,
148 148
149static struct ftrace_ops test_probe1 = { 149static struct ftrace_ops test_probe1 = {
150 .func = trace_selftest_test_probe1_func, 150 .func = trace_selftest_test_probe1_func,
151 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
151}; 152};
152 153
153static struct ftrace_ops test_probe2 = { 154static struct ftrace_ops test_probe2 = {
154 .func = trace_selftest_test_probe2_func, 155 .func = trace_selftest_test_probe2_func,
156 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
155}; 157};
156 158
157static struct ftrace_ops test_probe3 = { 159static struct ftrace_ops test_probe3 = {
158 .func = trace_selftest_test_probe3_func, 160 .func = trace_selftest_test_probe3_func,
161 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
159}; 162};
160 163
161static struct ftrace_ops test_global = { 164static struct ftrace_ops test_global = {
162 .func = trace_selftest_test_global_func, 165 .func = trace_selftest_test_global_func,
163 .flags = FTRACE_OPS_FL_GLOBAL, 166 .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
164}; 167};
165 168
166static void print_counts(void) 169static void print_counts(void)
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index 2fa5328e8893..0c1b165778e5 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -137,6 +137,7 @@ stack_trace_call(unsigned long ip, unsigned long parent_ip,
137static struct ftrace_ops trace_ops __read_mostly = 137static struct ftrace_ops trace_ops __read_mostly =
138{ 138{
139 .func = stack_trace_call, 139 .func = stack_trace_call,
140 .flags = FTRACE_OPS_FL_RECURSION_SAFE,
140}; 141};
141 142
142static ssize_t 143static ssize_t