linux/kernel/trace
Steven Rostedt 78d904b46a ring-buffer: add NMI protection for spinlocks
Impact: prevent deadlock in NMI

The ring buffers are not yet totally lockless with writing to
the buffer. When a writer crosses a page, it grabs a per cpu spinlock
to protect against a reader. The spinlocks taken by a writer are not
to protect against other writers, since a writer can only write to
its own per cpu buffer. The spinlocks protect against readers that
can touch any cpu buffer. The writers are made to be reentrant
with the spinlocks disabling interrupts.

The problem arises when an NMI writes to the buffer, and that write
crosses a page boundary. If it grabs a spinlock, it can be racing
with another writer (since disabling interrupts does not protect
against NMIs) or with a reader on the same CPU. Luckily, most of the
users are not reentrant and protects against this issue. But if a
user of the ring buffer becomes reentrant (which is what the ring
buffers do allow), if the NMI also writes to the ring buffer then
we risk the chance of a deadlock.

This patch moves the ftrace_nmi_enter called by nmi_enter() to the
ring buffer code. It replaces the current ftrace_nmi_enter that is
used by arch specific code to arch_ftrace_nmi_enter and updates
the Kconfig to handle it.

When an NMI is called, it will set a per cpu variable in the ring buffer
code and will clear it when the NMI exits. If a write to the ring buffer
crosses page boundaries inside an NMI, a trylock is used on the spin
lock instead. If the spinlock fails to be acquired, then the entry
is discarded.

This bug appeared in the ftrace work in the RT tree, where event tracing
is reentrant. This workaround solved the deadlocks that appeared there.

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
2009-02-07 20:00:17 -05:00
..
ftrace.c Merge branches 'tracing/blktrace', 'tracing/ftrace', 'tracing/urgent' and 'linus' into tracing/core 2009-02-04 20:45:41 +01:00
Kconfig ring-buffer: add NMI protection for spinlocks 2009-02-07 20:00:17 -05:00
kmemtrace.c kmemtrace: fix printk formats, fix 2009-01-30 16:12:33 +01:00
Makefile tracing: add a new workqueue tracer 2009-01-14 12:11:43 +01:00
ring_buffer.c ring-buffer: add NMI protection for spinlocks 2009-02-07 20:00:17 -05:00
trace_boot.c trace: let boot trace be chosen by command line 2009-02-03 06:26:12 +01:00
trace_branch.c trace: make the trace_event callbacks return enum print_line_t 2009-02-04 20:48:39 +01:00
trace_functions_graph.c trace: Use tracing_reset_online_cpus in more places 2009-01-29 14:28:31 +01:00
trace_functions.c ftrace: remove static from function tracer functions 2009-01-16 12:17:58 +01:00
trace_hw_branches.c trace: remove deprecated entry->cpu 2009-02-07 19:38:43 -05:00
trace_irqsoff.c trace: remove internal irqsoff disabling for trace output 2009-01-23 11:10:36 +01:00
trace_mmiotrace.c trace: clean up format errors in calls to trace_seq_printf 2009-01-16 12:17:38 +01:00
trace_nop.c trace: Use tracing_reset_online_cpus in more places 2009-01-29 14:28:31 +01:00
trace_output.c trace: remove deprecated entry->cpu 2009-02-07 19:38:43 -05:00
trace_output.h trace: make the trace_event callbacks return enum print_line_t 2009-02-04 20:48:39 +01:00
trace_power.c Merge branches 'tracing/kmemtrace2' and 'tracing/ftrace' into tracing/urgent 2009-01-06 10:18:43 +01:00
trace_sched_switch.c sched, trace: update trace_sched_wakeup() 2008-12-25 13:10:21 +01:00
trace_sched_wakeup.c trace_sched_wakeup: Remove unused variable 2009-01-29 14:31:03 +01:00
trace_selftest_dynamic.c ftrace: fix dynamic ftrace selftest 2008-05-23 21:13:23 +02:00
trace_selftest.c tracing/selftest: remove TRACE_CONT reference 2008-12-29 15:07:47 +01:00
trace_stack.c trace: better use of stack_trace_enabled for boot up code 2008-12-18 12:56:56 +01:00
trace_stat.c tracing: trace_stat.c cleanup 2009-01-15 11:31:21 +01:00
trace_stat.h tracing/ftrace: separate events tracing and stats tracing engine 2009-01-14 12:11:37 +01:00
trace_sysprof.c cpumask: convert kernel trace functions 2009-01-01 10:12:22 +10:30
trace_workqueue.c trace_workqueue: use percpu data for workqueue stat 2009-01-20 13:06:59 +01:00
trace.c trace: remove deprecated entry->cpu 2009-02-07 19:38:43 -05:00
trace.h trace: remove deprecated entry->cpu 2009-02-07 19:38:43 -05:00