X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=kernel%2Ftrace%2Ftrace_stack.c;fp=kernel%2Ftrace%2Ftrace_stack.c;h=dda9e6742950305f36fbe920f9fe0c6f68d83fbf;hb=22402cd0af685c1a5d067c87db3051db7fff7709;hp=0bd212af406c49fc64ad308112e9ad7fab1eb4ff;hpb=d227c3ae4e94e5eb11dd780a811f59e1a7b74ccd;p=linux-2.6-block.git diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 0bd212af406c..dda9e6742950 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c @@ -91,9 +91,19 @@ check_stack(unsigned long ip, unsigned long *stack) if (!object_is_on_stack(stack)) return; + /* Can't do this from NMI context (can cause deadlocks) */ + if (in_nmi()) + return; + local_irq_save(flags); arch_spin_lock(&stack_trace_max_lock); + /* + * RCU may not be watching, make it see us. + * The stack trace code uses rcu_sched. + */ + rcu_irq_enter(); + /* In case another CPU set the tracer_frame on us */ if (unlikely(!frame_size)) this_size -= tracer_frame; @@ -175,6 +185,7 @@ check_stack(unsigned long ip, unsigned long *stack) } out: + rcu_irq_exit(); arch_spin_unlock(&stack_trace_max_lock); local_irq_restore(flags); }