diff options
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r-- | kernel/trace/ftrace.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 1330969d8447..639b6ab1f04c 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -156,14 +156,27 @@ static void | |||
156 | ftrace_global_list_func(unsigned long ip, unsigned long parent_ip, | 156 | ftrace_global_list_func(unsigned long ip, unsigned long parent_ip, |
157 | struct ftrace_ops *op, struct pt_regs *regs) | 157 | struct ftrace_ops *op, struct pt_regs *regs) |
158 | { | 158 | { |
159 | if (unlikely(trace_recursion_test(TRACE_GLOBAL_BIT))) | 159 | int bit; |
160 | |||
161 | if (in_interrupt()) { | ||
162 | if (in_nmi()) | ||
163 | bit = TRACE_GLOBAL_NMI_BIT; | ||
164 | |||
165 | else if (in_irq()) | ||
166 | bit = TRACE_GLOBAL_IRQ_BIT; | ||
167 | else | ||
168 | bit = TRACE_GLOBAL_SIRQ_BIT; | ||
169 | } else | ||
170 | bit = TRACE_GLOBAL_BIT; | ||
171 | |||
172 | if (unlikely(trace_recursion_test(bit))) | ||
160 | return; | 173 | return; |
161 | 174 | ||
162 | trace_recursion_set(TRACE_GLOBAL_BIT); | 175 | trace_recursion_set(bit); |
163 | do_for_each_ftrace_op(op, ftrace_global_list) { | 176 | do_for_each_ftrace_op(op, ftrace_global_list) { |
164 | op->func(ip, parent_ip, op, regs); | 177 | op->func(ip, parent_ip, op, regs); |
165 | } while_for_each_ftrace_op(op); | 178 | } while_for_each_ftrace_op(op); |
166 | trace_recursion_clear(TRACE_GLOBAL_BIT); | 179 | trace_recursion_clear(bit); |
167 | } | 180 | } |
168 | 181 | ||
169 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip, | 182 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip, |
@@ -4132,14 +4145,27 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, | |||
4132 | struct ftrace_ops *ignored, struct pt_regs *regs) | 4145 | struct ftrace_ops *ignored, struct pt_regs *regs) |
4133 | { | 4146 | { |
4134 | struct ftrace_ops *op; | 4147 | struct ftrace_ops *op; |
4148 | unsigned int bit; | ||
4135 | 4149 | ||
4136 | if (function_trace_stop) | 4150 | if (function_trace_stop) |
4137 | return; | 4151 | return; |
4138 | 4152 | ||
4139 | if (unlikely(trace_recursion_test(TRACE_INTERNAL_BIT))) | 4153 | if (in_interrupt()) { |
4140 | return; | 4154 | if (in_nmi()) |
4155 | bit = TRACE_INTERNAL_NMI_BIT; | ||
4156 | |||
4157 | else if (in_irq()) | ||
4158 | bit = TRACE_INTERNAL_IRQ_BIT; | ||
4159 | else | ||
4160 | bit = TRACE_INTERNAL_SIRQ_BIT; | ||
4161 | } else | ||
4162 | bit = TRACE_INTERNAL_BIT; | ||
4163 | |||
4164 | if (unlikely(trace_recursion_test(bit))) | ||
4165 | return; | ||
4166 | |||
4167 | trace_recursion_set(bit); | ||
4141 | 4168 | ||
4142 | trace_recursion_set(TRACE_INTERNAL_BIT); | ||
4143 | /* | 4169 | /* |
4144 | * Some of the ops may be dynamically allocated, | 4170 | * Some of the ops may be dynamically allocated, |
4145 | * they must be freed after a synchronize_sched(). | 4171 | * they must be freed after a synchronize_sched(). |
@@ -4150,7 +4176,7 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip, | |||
4150 | op->func(ip, parent_ip, op, regs); | 4176 | op->func(ip, parent_ip, op, regs); |
4151 | } while_for_each_ftrace_op(op); | 4177 | } while_for_each_ftrace_op(op); |
4152 | preempt_enable_notrace(); | 4178 | preempt_enable_notrace(); |
4153 | trace_recursion_clear(TRACE_INTERNAL_BIT); | 4179 | trace_recursion_clear(bit); |
4154 | } | 4180 | } |
4155 | 4181 | ||
4156 | /* | 4182 | /* |