Skip to content

Commit d0949cd

Browse files
committed
tracing: Return from tracing_buffers_read() if the file has been closed
When running the following: # cd /sys/kernel/tracing/ # echo 1 > events/sched/sched_waking/enable # echo 1 > events/sched/sched_switch/enable # echo 0 > tracing_on # dd if=per_cpu/cpu0/trace_pipe_raw of=/tmp/raw0.dat The dd task would get stuck in an infinite loop in the kernel. What would happen is the following: When ring_buffer_read_page() returns -1 (no data) then a check is made to see if the buffer is empty (as happens when the page is not full), it will call wait_on_pipe() to wait until the ring buffer has data. When it is it will try again to read data (unless O_NONBLOCK is set). The issue happens when there's a reader and the file descriptor is closed. The wait_on_pipe() will return when that is the case. But this loop will continue to try again and wait_on_pipe() will again return immediately and the loop will continue and never stop. Simply check if the file was closed before looping and exit out if it is. Cc: [email protected] Cc: Masami Hiramatsu <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Link: https://lore.kernel.org/[email protected] Fixes: 2aa043a ("tracing/ring-buffer: Fix wait_on_pipe() race") Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 0b6743b commit d0949cd

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

kernel/trace/trace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7956,7 +7956,7 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
79567956
trace_access_unlock(iter->cpu_file);
79577957

79587958
if (ret < 0) {
7959-
if (trace_empty(iter)) {
7959+
if (trace_empty(iter) && !iter->closed) {
79607960
if ((filp->f_flags & O_NONBLOCK))
79617961
return -EAGAIN;
79627962

0 commit comments

Comments
 (0)