tracing: Add ioctl() to force ring buffer waiters to wake up
authorSteven Rostedt (Google) <rostedt@goodmis.org>
Thu, 29 Sep 2022 13:50:29 +0000 (09:50 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Oct 2022 10:34:31 +0000 (12:34 +0200)
commit 01b2a52171735c6eea80ee2f355f32bea6c41418 upstream.

If a process is waiting on the ring buffer for data, there currently isn't
a clean way to force it to wake up. Add an ioctl call that will force any
tasks that are waiting on the trace_pipe_raw file to wake up.

Link: https://lkml.kernel.org/r/20220929095029.117f913f@gandalf.local.home
Cc: stable@vger.kernel.org
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Fixes: e30f53aad2202 ("tracing: Do not busy wait in buffer splice")
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
kernel/trace/trace.c

index 2f98c0a..0dc17fd 100644 (file)
@@ -8310,12 +8310,34 @@ out:
        return ret;
 }
 
+/* An ioctl call with cmd 0 to the ring buffer file will wake up all waiters */
+static long tracing_buffers_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct ftrace_buffer_info *info = file->private_data;
+       struct trace_iterator *iter = &info->iter;
+
+       if (cmd)
+               return -ENOIOCTLCMD;
+
+       mutex_lock(&trace_types_lock);
+
+       iter->wait_index++;
+       /* Make sure the waiters see the new wait_index */
+       smp_wmb();
+
+       ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file);
+
+       mutex_unlock(&trace_types_lock);
+       return 0;
+}
+
 static const struct file_operations tracing_buffers_fops = {
        .open           = tracing_buffers_open,
        .read           = tracing_buffers_read,
        .poll           = tracing_buffers_poll,
        .release        = tracing_buffers_release,
        .splice_read    = tracing_buffers_splice_read,
+       .unlocked_ioctl = tracing_buffers_ioctl,
        .llseek         = no_llseek,
 };