aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-03-11 19:52:30 -0400
committerSteven Rostedt <srostedt@redhat.com>2009-03-11 22:15:25 -0400
commit9aba60fe6eb20453de53a572143bef22fa929fba (patch)
tree97df44bc298fe40719d6f08000d96532d3ecf27e /kernel/trace/trace.c
parent1852fcce181faa237c010a3dbedb473cf9d4555f (diff)
tracing: fix trace_wait to know to wait on all cpus or just one
Impact: fix to task live locking on reading trace_pipe on one CPU The same code is used for both trace_pipe (all CPUS) and the per_cpu trace_pipe file. When there is no data to read, it will check for signals and wait on the trace wait queue. The problem happens with the per_cpu wait. The trace_wait code checks all CPUs. Thus, if there's data in another CPU buffer, then it will exit the wait, without checking for signals or waiting on the wait queue. It would then try to read the empty buffer, and since that will just return nothing, then it will try to wait again. Unfortunately, that will again fail due to there still being data in the other buffers. This ends up with a live lock for the task. This patch fixes the trace_wait to be aware that the iterator may only be waiting on a single buffer. Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 35ee63ae4122..e60f4be10d64 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1666,6 +1666,19 @@ static int trace_empty(struct trace_iterator *iter)
1666{ 1666{
1667 int cpu; 1667 int cpu;
1668 1668
1669 /* If we are looking at one CPU buffer, only check that one */
1670 if (iter->cpu_file != TRACE_PIPE_ALL_CPU) {
1671 cpu = iter->cpu_file;
1672 if (iter->buffer_iter[cpu]) {
1673 if (!ring_buffer_iter_empty(iter->buffer_iter[cpu]))
1674 return 0;
1675 } else {
1676 if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu))
1677 return 0;
1678 }
1679 return 1;
1680 }
1681
1669 for_each_tracing_cpu(cpu) { 1682 for_each_tracing_cpu(cpu) {
1670 if (iter->buffer_iter[cpu]) { 1683 if (iter->buffer_iter[cpu]) {
1671 if (!ring_buffer_iter_empty(iter->buffer_iter[cpu])) 1684 if (!ring_buffer_iter_empty(iter->buffer_iter[cpu]))