aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_stack.c')
-rw-r--r--kernel/trace/trace_stack.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index b746399ab59c..8abf1ba18085 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -85,9 +85,19 @@ check_stack(unsigned long ip, unsigned long *stack)
85 if (!object_is_on_stack(stack)) 85 if (!object_is_on_stack(stack))
86 return; 86 return;
87 87
88 /* Can't do this from NMI context (can cause deadlocks) */
89 if (in_nmi())
90 return;
91
88 local_irq_save(flags); 92 local_irq_save(flags);
89 arch_spin_lock(&max_stack_lock); 93 arch_spin_lock(&max_stack_lock);
90 94
95 /*
96 * RCU may not be watching, make it see us.
97 * The stack trace code uses rcu_sched.
98 */
99 rcu_irq_enter();
100
91 /* In case another CPU set the tracer_frame on us */ 101 /* In case another CPU set the tracer_frame on us */
92 if (unlikely(!frame_size)) 102 if (unlikely(!frame_size))
93 this_size -= tracer_frame; 103 this_size -= tracer_frame;
@@ -169,6 +179,7 @@ check_stack(unsigned long ip, unsigned long *stack)
169 } 179 }
170 180
171 out: 181 out:
182 rcu_irq_exit();
172 arch_spin_unlock(&max_stack_lock); 183 arch_spin_unlock(&max_stack_lock);
173 local_irq_restore(flags); 184 local_irq_restore(flags);
174} 185}