aboutsummaryrefslogtreecommitdiff
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-12-13 09:28:43 +0100
committerTakashi Iwai <tiwai@suse.de>2010-12-13 09:28:43 +0100
commit20aeeb356ba2e8daa99b5942c528ae2b3ea28433 (patch)
treed2cebc7039954851998d592123899f5627def7a9 /kernel/trace/trace.c
parent07a9e2b2fbdda631eeff54e4b8ebcaaea71be538 (diff)
parent5b84ba26a9672e615897234fa5efd3eea2d6b295 (diff)
Merge branch 'topic/workq-update' into topic/asoc
Conflicts: sound/soc/codecs/wm8350.c sound/soc/codecs/wm8753.c sound/soc/sh/fsi.c sound/soc/soc-core.c
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 82d9b8106cd..c380612273b 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -17,7 +17,6 @@
#include <linux/writeback.h>
#include <linux/kallsyms.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/irqflags.h>
#include <linux/debugfs.h>
@@ -1284,6 +1283,8 @@ void trace_dump_stack(void)
__ftrace_trace_stack(global_trace.buffer, flags, 3, preempt_count());
}
+static DEFINE_PER_CPU(int, user_stack_count);
+
void
ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
{
@@ -1302,6 +1303,18 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
if (unlikely(in_nmi()))
return;
+ /*
+ * prevent recursion, since the user stack tracing may
+ * trigger other kernel events.
+ */
+ preempt_disable();
+ if (__this_cpu_read(user_stack_count))
+ goto out;
+
+ __this_cpu_inc(user_stack_count);
+
+
+
event = trace_buffer_lock_reserve(buffer, TRACE_USER_STACK,
sizeof(*entry), flags, pc);
if (!event)
@@ -1319,6 +1332,11 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
save_stack_trace_user(&trace);
if (!filter_check_discard(call, entry, buffer, event))
ring_buffer_unlock_commit(buffer, event);
+
+ __this_cpu_dec(user_stack_count);
+
+ out:
+ preempt_enable();
}
#ifdef UNUSED