aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c40
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
156ftrace_global_list_func(unsigned long ip, unsigned long parent_ip, 156ftrace_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
169static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip, 182static 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/*