• Steven Rostedt's avatar
    tracing: Return from tracing_buffers_read() if the file has been closed · d0949cd4
    Steven Rostedt authored
    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: stable@vger.kernel.org
    Cc: Masami Hiramatsu <mhiramat@kernel.org>
    Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
    Link: https://lore.kernel.org/20240808235730.78bf63e5@rorschach.local.home
    Fixes: 2aa043a5 ("tracing/ring-buffer: Fix wait_on_pipe() race")
    Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
    d0949cd4
trace.c 258 KB