diff options
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r-- | kernel/trace/ftrace.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 25949b33057c..1ee417fcbfa5 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -109,12 +109,18 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip); | |||
109 | static void ftrace_global_list_func(unsigned long ip, | 109 | static void ftrace_global_list_func(unsigned long ip, |
110 | unsigned long parent_ip) | 110 | unsigned long parent_ip) |
111 | { | 111 | { |
112 | struct ftrace_ops *op = rcu_dereference_raw(ftrace_global_list); /*see above*/ | 112 | struct ftrace_ops *op; |
113 | |||
114 | if (unlikely(trace_recursion_test(TRACE_GLOBAL_BIT))) | ||
115 | return; | ||
113 | 116 | ||
117 | trace_recursion_set(TRACE_GLOBAL_BIT); | ||
118 | op = rcu_dereference_raw(ftrace_global_list); /*see above*/ | ||
114 | while (op != &ftrace_list_end) { | 119 | while (op != &ftrace_list_end) { |
115 | op->func(ip, parent_ip); | 120 | op->func(ip, parent_ip); |
116 | op = rcu_dereference_raw(op->next); /*see above*/ | 121 | op = rcu_dereference_raw(op->next); /*see above*/ |
117 | }; | 122 | }; |
123 | trace_recursion_clear(TRACE_GLOBAL_BIT); | ||
118 | } | 124 | } |
119 | 125 | ||
120 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) | 126 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) |
@@ -3490,6 +3496,10 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) | |||
3490 | { | 3496 | { |
3491 | struct ftrace_ops *op; | 3497 | struct ftrace_ops *op; |
3492 | 3498 | ||
3499 | if (unlikely(trace_recursion_test(TRACE_INTERNAL_BIT))) | ||
3500 | return; | ||
3501 | |||
3502 | trace_recursion_set(TRACE_INTERNAL_BIT); | ||
3493 | /* | 3503 | /* |
3494 | * Some of the ops may be dynamically allocated, | 3504 | * Some of the ops may be dynamically allocated, |
3495 | * they must be freed after a synchronize_sched(). | 3505 | * they must be freed after a synchronize_sched(). |
@@ -3502,6 +3512,7 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) | |||
3502 | op = rcu_dereference_raw(op->next); | 3512 | op = rcu_dereference_raw(op->next); |
3503 | }; | 3513 | }; |
3504 | preempt_enable_notrace(); | 3514 | preempt_enable_notrace(); |
3515 | trace_recursion_clear(TRACE_INTERNAL_BIT); | ||
3505 | } | 3516 | } |
3506 | 3517 | ||
3507 | static void clear_ftrace_swapper(void) | 3518 | static void clear_ftrace_swapper(void) |