ftrace, perf: Avoid infinite event generation loop
authorPeter Zijlstra <peterz@infradead.org>
Thu, 14 Nov 2013 15:23:04 +0000 (16:23 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 19 Nov 2013 15:57:40 +0000 (16:57 +0100)
commitd5b5f391d434c5cc8bcb1ab2d759738797b85f52
tree9be9680fd08dd943cac38b278dde12d83b4a9856
parent801a76050bcf8d4e500eb8d048ff6265f37a61c8
ftrace, perf: Avoid infinite event generation loop

Vince's perf-trinity fuzzer found yet another 'interesting' problem.

When we sample the irq_work_exit tracepoint with period==1 (or
PERF_SAMPLE_PERIOD) and we add an fasync SIGNAL handler we create an
infinite event generation loop:

  ,-> <IPI>
  |     irq_work_exit() ->
  |       trace_irq_work_exit() ->
  |         ...
  |           __perf_event_overflow() -> (due to fasync)
  |             irq_work_queue() -> (irq_work_list must be empty)
  '---------      arch_irq_work_raise()

Similar things can happen due to regular poll() wakeups if we exceed
the ring-buffer wakeup watermark, or have an event_limit.

To avoid this, dis-allow sampling this particular tracepoint.

In order to achieve this, create a special perf_perm function pointer
for each event and call this (when set) on trying to create a
tracepoint perf event.

[ roasted: use expr... to allow for ',' in your expression ]

Reported-by: Vince Weaver <vincent.weaver@maine.edu>
Tested-by: Vince Weaver <vincent.weaver@maine.edu>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Dave Jones <davej@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Link: http://lkml.kernel.org/r/20131114152304.GC5364@laptop.programming.kicks-ass.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/include/asm/trace/irq_vectors.h
include/linux/ftrace_event.h
include/linux/tracepoint.h
include/trace/ftrace.h
kernel/trace/trace_event_perf.c