|
@@ -156,14 +156,27 @@ static void
|
|
|
ftrace_global_list_func(unsigned long ip, unsigned long parent_ip,
|
|
|
struct ftrace_ops *op, struct pt_regs *regs)
|
|
|
{
|
|
|
- if (unlikely(trace_recursion_test(TRACE_GLOBAL_BIT)))
|
|
|
+ int bit;
|
|
|
+
|
|
|
+ if (in_interrupt()) {
|
|
|
+ if (in_nmi())
|
|
|
+ bit = TRACE_GLOBAL_NMI_BIT;
|
|
|
+
|
|
|
+ else if (in_irq())
|
|
|
+ bit = TRACE_GLOBAL_IRQ_BIT;
|
|
|
+ else
|
|
|
+ bit = TRACE_GLOBAL_SIRQ_BIT;
|
|
|
+ } else
|
|
|
+ bit = TRACE_GLOBAL_BIT;
|
|
|
+
|
|
|
+ if (unlikely(trace_recursion_test(bit)))
|
|
|
return;
|
|
|
|
|
|
- trace_recursion_set(TRACE_GLOBAL_BIT);
|
|
|
+ trace_recursion_set(bit);
|
|
|
do_for_each_ftrace_op(op, ftrace_global_list) {
|
|
|
op->func(ip, parent_ip, op, regs);
|
|
|
} while_for_each_ftrace_op(op);
|
|
|
- trace_recursion_clear(TRACE_GLOBAL_BIT);
|
|
|
+ trace_recursion_clear(bit);
|
|
|
}
|
|
|
|
|
|
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,
|
|
|
struct ftrace_ops *ignored, struct pt_regs *regs)
|
|
|
{
|
|
|
struct ftrace_ops *op;
|
|
|
+ unsigned int bit;
|
|
|
|
|
|
if (function_trace_stop)
|
|
|
return;
|
|
|
|
|
|
- if (unlikely(trace_recursion_test(TRACE_INTERNAL_BIT)))
|
|
|
- return;
|
|
|
+ if (in_interrupt()) {
|
|
|
+ if (in_nmi())
|
|
|
+ bit = TRACE_INTERNAL_NMI_BIT;
|
|
|
+
|
|
|
+ else if (in_irq())
|
|
|
+ bit = TRACE_INTERNAL_IRQ_BIT;
|
|
|
+ else
|
|
|
+ bit = TRACE_INTERNAL_SIRQ_BIT;
|
|
|
+ } else
|
|
|
+ bit = TRACE_INTERNAL_BIT;
|
|
|
+
|
|
|
+ if (unlikely(trace_recursion_test(bit)))
|
|
|
+ return;
|
|
|
+
|
|
|
+ trace_recursion_set(bit);
|
|
|
|
|
|
- trace_recursion_set(TRACE_INTERNAL_BIT);
|
|
|
/*
|
|
|
* Some of the ops may be dynamically allocated,
|
|
|
* they must be freed after a synchronize_sched().
|
|
@@ -4150,7 +4176,7 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,
|
|
|
op->func(ip, parent_ip, op, regs);
|
|
|
} while_for_each_ftrace_op(op);
|
|
|
preempt_enable_notrace();
|
|
|
- trace_recursion_clear(TRACE_INTERNAL_BIT);
|
|
|
+ trace_recursion_clear(bit);
|
|
|
}
|
|
|
|
|
|
/*
|