1
linux/kernel/trace
Frederic Weisbecker 444a2a3bcd tracing, perf_events: Protect the buffer from recursion in perf
While tracing using events with perf, if one enables the
lockdep:lock_acquire event, it will infect every other perf
trace events.

Basically, you can enable whatever set of trace events through
perf but if this event is part of the set, the only result we
can get is a long list of lock_acquire events of rcu read lock,
and only that.

This is because of a recursion inside perf.

1) When a trace event is triggered, it will fill a per cpu
   buffer and submit it to perf.

2) Perf will commit this event but will also protect some data
   using rcu_read_lock

3) A recursion appears: rcu_read_lock triggers a lock_acquire
   event that will fill the per cpu event and then submit the
   buffer to perf.

4) Perf detects a recursion and ignores it

5) Perf continues its work on the previous event, but its buffer
   has been overwritten by the lock_acquire event, it has then
   been turned into a lock_acquire event of rcu read lock

Such scenario also happens with lock_release with
rcu_read_unlock().

We could turn the rcu_read_lock() into __rcu_read_lock() to drop
the lock debugging from perf fast path, but that would make us
lose the rcu debugging and that doesn't prevent from other
possible kind of recursion from perf in the future.

This patch adds a recursion protection based on a counter on the
perf trace per cpu buffers to solve the problem.

-v2: Fixed lost whitespace, added reviewed-by tag

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Reviewed-by: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Jason Baron <jbaron@redhat.com>
LKML-Reference: <1257477185-7838-1-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-11-08 10:31:42 +01:00
..
blktrace.c Add a tracepoint for block request remapping 2009-10-01 21:19:34 +02:00
ftrace.c ftrace: Copy ftrace_graph_filter boot param using strlcpy 2009-10-14 20:43:39 +02:00
Kconfig tracing/kprobes: Rename Kprobe-tracer to kprobe-event 2009-11-04 13:02:48 +01:00
kmemtrace.c kmemtrace: Fix up tracer registration 2009-10-01 11:53:44 +02:00
Makefile tracing/kprobes: Rename Kprobe-tracer to kprobe-event 2009-11-04 13:02:48 +01:00
power-traces.c tracing, perf: Convert the power tracer into an event tracer 2009-09-19 11:42:12 +02:00
ring_buffer_benchmark.c ring-buffer: have benchmark test print to trace buffer 2009-06-17 17:01:09 -04:00
ring_buffer.c tracing/events: Add 'signed' field to format files 2009-10-06 15:04:45 +02:00
trace_boot.c tracing: add filter event logic to special, mmiotrace and boot tracers 2009-09-12 23:34:04 -04:00
trace_branch.c tracing: user local buffer variable for trace branch tracer 2009-10-07 21:53:41 -04:00
trace_clock.c tracing: optimize global_trace_clock cachelines 2009-09-15 12:24:22 -04:00
trace_entries.h tracing, perf: Convert the power tracer into an event tracer 2009-09-19 11:42:12 +02:00
trace_event_profile.c tracing, perf_events: Protect the buffer from recursion in perf 2009-11-08 10:31:42 +01:00
trace_events_filter.c tracing/events: Fix locking imbalance in the filter code 2009-10-15 12:41:56 +02:00
trace_events.c Merge branch 'perf/core' into perf/probes 2009-10-23 08:23:20 +02:00
trace_export.c Merge branch 'perf/core' into perf/probes 2009-10-23 08:23:20 +02:00
trace_functions_graph.c tracing: switch function prints from %pf to %ps 2009-09-17 15:53:40 -04:00
trace_functions.c tracing: switch function prints from %pf to %ps 2009-09-17 15:53:40 -04:00
trace_hw_branches.c tracing: fix warning on kernel/trace/trace_branch.c andtrace_hw_branches.c 2009-10-07 21:52:03 -04:00
trace_irqsoff.c tracing: do not update tracing_max_latency when tracer is stopped 2009-09-12 21:45:17 -04:00
trace_kprobe.c tracing, perf_events: Protect the buffer from recursion in perf 2009-11-08 10:31:42 +01:00
trace_mmiotrace.c tracing: add filter event logic to special, mmiotrace and boot tracers 2009-09-12 23:34:04 -04:00
trace_nop.c tracing/ftrace: make nop-tracer use polling wait for events on pipe 2009-03-23 09:22:15 +01:00
trace_output.c tracing: fix transposed numbers of lock_depth and preempt_count 2009-10-07 14:05:04 -04:00
trace_output.h tracing: consolidate code between trace_output.c and trace_function_graph.c 2009-09-11 14:24:13 -04:00
trace_printk.c tracing: Remove markers 2009-09-18 21:22:08 +02:00
trace_sched_switch.c tracing: pass around ring buffer instead of tracer 2009-09-04 18:59:39 -04:00
trace_sched_wakeup.c tracing: do not update tracing_max_latency when tracer is stopped 2009-09-12 21:45:17 -04:00
trace_selftest_dynamic.c
trace_selftest.c tracing/function-graph-tracer: Move graph event insertion helpers in the graph tracer file 2009-08-06 07:28:06 +02:00
trace_stack.c sysctl: remove "struct file *" argument of ->proc_handler 2009-09-24 07:21:04 -07:00
trace_stat.c trace_stat: Fix missing entry in stat file 2009-08-17 11:25:09 +02:00
trace_stat.h tracing/stat: Add stat_release() callback 2009-07-10 12:14:05 +02:00
trace_syscalls.c tracing, perf_events: Protect the buffer from recursion in perf 2009-11-08 10:31:42 +01:00
trace_sysprof.c Merge branch 'timers-for-linus-migration' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2009-06-15 10:06:19 -07:00
trace_workqueue.c tracing/workqueues: Add refcnt to struct cpu_workqueue_stats 2009-07-10 12:14:07 +02:00
trace.c ftrace: Rename set_bootup_ftrace into set_cmdline_ftrace 2009-10-14 20:55:55 +02:00
trace.h Merge branch 'perf/core' into perf/probes 2009-10-23 08:23:20 +02:00