tracing: make tracing_reset safe for external use
authorSteven Rostedt <srostedt@redhat.com>
Fri, 4 Sep 2009 16:35:16 +0000 (12:35 -0400)
committerSteven Rostedt <rostedt@goodmis.org>
Fri, 4 Sep 2009 22:46:51 +0000 (18:46 -0400)
Reseting the trace buffer without first disabling the buffer and
waiting for any writers to complete, can corrupt the ring buffer.

This patch makes the external version of tracing_reset safe from
corruption by disabling the ring buffer and calling synchronize_sched.

This version can no longer be called from interrupt context. But all those
callers have been removed.

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

index 7daf372e319a3ee556ba646dbeb3a1ac056baf10..0418e2650d418e5338e2d21179e9c043385b97b0 100644 (file)
@@ -641,13 +641,26 @@ void unregister_tracer(struct tracer *type)
        mutex_unlock(&trace_types_lock);
 }
 
-void tracing_reset(struct trace_array *tr, int cpu)
+static void __tracing_reset(struct trace_array *tr, int cpu)
 {
        ftrace_disable_cpu();
        ring_buffer_reset_cpu(tr->buffer, cpu);
        ftrace_enable_cpu();
 }
 
+void tracing_reset(struct trace_array *tr, int cpu)
+{
+       struct ring_buffer *buffer = tr->buffer;
+
+       ring_buffer_record_disable(buffer);
+
+       /* Make sure all commits have finished */
+       synchronize_sched();
+       __tracing_reset(tr, cpu);
+
+       ring_buffer_record_enable(buffer);
+}
+
 void tracing_reset_online_cpus(struct trace_array *tr)
 {
        struct ring_buffer *buffer = tr->buffer;
@@ -661,7 +674,7 @@ void tracing_reset_online_cpus(struct trace_array *tr)
        tr->time_start = ftrace_now(tr->cpu);
 
        for_each_online_cpu(cpu)
-               tracing_reset(tr, cpu);
+               __tracing_reset(tr, cpu);
 
        ring_buffer_record_enable(buffer);
 }