diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-18 14:27:55 +0000 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-18 14:27:55 +0000 |
| commit | 2f841ed13b9f10037e25ddf417d01700ecd886d0 (patch) | |
| tree | 123448d98b3be03ac90fbb6e32f224235063c8bf /kernel/trace | |
| parent | 961ec6daa7b14f376c30d447a830fa4783a2112c (diff) | |
| parent | 8fbf397c3389c1dedfa9ee412715046ab28fd82d (diff) | |
Merge branch 'hw-breakpoint' of git://repo.or.cz/linux-2.6/linux-wd into devel-stable
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/trace.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 042084157980..c380612273bf 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1283,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) { @@ -1301,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) @@ -1318,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 |
