tracing: Fix race with max_tr and changing tracers
authorSteven Rostedt <srostedt@redhat.com>
Tue, 22 Jan 2013 18:35:11 +0000 (13:35 -0500)
committerSteven Rostedt <rostedt@goodmis.org>
Wed, 23 Jan 2013 04:33:07 +0000 (23:33 -0500)
commit34600f0e9c33c9cd48ae87448205f51332b7d5a0
treefb6159552edf55526219b4c4c55f6120595be53e
parent0a71e4c6d749d06f52e75a406fc9046924fcfcc1
tracing: Fix race with max_tr and changing tracers

There's a race condition between the setting of a new tracer and
the update of the max trace buffers (the swap). When a new tracer
is added, it sets current_trace to nop_trace before disabling
the old tracer. At this moment, if the old tracer uses update_max_tr(),
the update may trigger the warning against !current_trace->use_max-tr,
as nop_trace doesn't have that set.

As update_max_tr() requires that interrupts be disabled, we can
add a check to see if current_trace == nop_trace and bail if it
does. Then when disabling the current_trace, set it to nop_trace
and run synchronize_sched(). This will make sure all calls to
update_max_tr() have completed (it was called with interrupts disabled).

As a clean up, this commit also removes shrinking and recreating
the max_tr buffer if the old and new tracers both have use_max_tr set.
The old way use to always shrink the buffer, and then expand it
for the next tracer. This is a waste of time.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
kernel/trace/trace.c