aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-03-12 19:48:41 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-04-01 19:01:17 -0400
commit70e27dedd11fdbb3a9dec79af59d8ba61a19365b (patch)
treeceeebb9871a93301e09b1c829b87bcea58e69338 /kernel
parentfe030f50c598ffd9476da37d35a7dd7301487795 (diff)
tracing: Use same local variable when resetting the ring buffer
commit 283740c619d211e34572cc93c8cdba92ccbdb9cc upstream. In the ftrace code that resets the ring buffer it references the buffer with a local variable, but then uses the tr->buffer as the parameter to reset. If the wakeup tracer is running, which can switch the tr->buffer with the max saved buffer, this can break the requirement of disabling the buffer before the reset. buffer = tr->buffer; ring_buffer_record_disable(buffer); synchronize_sched(); __tracing_reset(tr->buffer, cpu); If the tr->buffer is swapped, then the reset is not happening to the buffer that was disabled. This will cause the ring buffer to fail. Found with Li Zefan's ftrace_stress_test. Reported-by: Lai Jiangshan <laijs@cn.fujitsu.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 1069dcb935e3..95c944a0b1e1 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -747,10 +747,10 @@ out:
747 mutex_unlock(&trace_types_lock); 747 mutex_unlock(&trace_types_lock);
748} 748}
749 749
750static void __tracing_reset(struct trace_array *tr, int cpu) 750static void __tracing_reset(struct ring_buffer *buffer, int cpu)
751{ 751{
752 ftrace_disable_cpu(); 752 ftrace_disable_cpu();
753 ring_buffer_reset_cpu(tr->buffer, cpu); 753 ring_buffer_reset_cpu(buffer, cpu);
754 ftrace_enable_cpu(); 754 ftrace_enable_cpu();
755} 755}
756 756
@@ -762,7 +762,7 @@ void tracing_reset(struct trace_array *tr, int cpu)
762 762
763 /* Make sure all commits have finished */ 763 /* Make sure all commits have finished */
764 synchronize_sched(); 764 synchronize_sched();
765 __tracing_reset(tr, cpu); 765 __tracing_reset(buffer, cpu);
766 766
767 ring_buffer_record_enable(buffer); 767 ring_buffer_record_enable(buffer);
768} 768}
@@ -780,7 +780,7 @@ void tracing_reset_online_cpus(struct trace_array *tr)
780 tr->time_start = ftrace_now(tr->cpu); 780 tr->time_start = ftrace_now(tr->cpu);
781 781
782 for_each_online_cpu(cpu) 782 for_each_online_cpu(cpu)
783 __tracing_reset(tr, cpu); 783 __tracing_reset(buffer, cpu);
784 784
785 ring_buffer_record_enable(buffer); 785 ring_buffer_record_enable(buffer);
786} 786}