]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
tracing: Fix enabling of tracing on file release
authorSteven Rostedt <rostedt@goodmis.org>
Tue, 2 Dec 2025 21:17:51 +0000 (16:17 -0500)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Fri, 5 Dec 2025 20:17:56 +0000 (15:17 -0500)
The trace file will pause tracing if the tracing instance has the
"pause-on-trace" option is set. This happens when the file is opened, and
it is unpaused when the file is closed. When this was first added, there
was only one user that paused tracing. On open, the check to pause was:

   if (!iter->snapshot && (tr->trace_flags & TRACE_ITER(PAUSE_ON_TRACE)))

Where if it is not the snapshot tracer and the "pause-on-trace" option is
set, then it increments a "stop_count" of the trace instance.

On close, the check is:

   if (!iter->snapshot && tr->stop_count)

That is, if it is not the snapshot buffer and it was stopped, it will
re-enable tracing.

Now there's more places that stop tracing. This means, if something else
stops tracing the tr->stop_count will be non-zero, and that means if the
trace file is closed, it will decrement the stop_count even though it
never incremented it. This causes a warning because when the user that
stopped tracing enables it again, the stop_count goes below zero.

Instead of relying on the stop_count being set to know if the close of
the trace file should enable tracing again, add a new flag to the trace
iterator. The trace iterator is unique per open of the trace file, and if
the open stops tracing set the trace iterator PAUSE flag. On close, if the
PAUSE flag is set, then re-enable it again.

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20251202161751.24abaaf1@gandalf.local.home
Fixes: 06e0a548bad0f ("tracing: Do not disable tracing when reading the trace file")
Reported-by: syzbot+ccdec3bfe0beec58a38d@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/692f44a5.a70a0220.2ea503.00c8.GAE@google.com/
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
include/linux/trace_events.h
kernel/trace/trace.c

index 04307a19cde30587d9cbfcc87bc2f4b3713b084f..3690221ba3d80d78d5d85c262b7ff591bff6a9ae 100644 (file)
@@ -138,6 +138,7 @@ enum trace_iter_flags {
        TRACE_FILE_LAT_FMT      = 1,
        TRACE_FILE_ANNOTATE     = 2,
        TRACE_FILE_TIME_IN_NS   = 4,
+       TRACE_FILE_PAUSE        = 8,
 };
 
 
index c9fbb316dcbdfdf54dd19f63c394d11a0dec27d8..cf725a33d99c5c81dc9d62e45a9f97b6576c28e6 100644 (file)
@@ -4709,8 +4709,10 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)
         * If pause-on-trace is enabled, then stop the trace while
         * dumping, unless this is the "snapshot" file
         */
-       if (!iter->snapshot && (tr->trace_flags & TRACE_ITER(PAUSE_ON_TRACE)))
+       if (!iter->snapshot && (tr->trace_flags & TRACE_ITER(PAUSE_ON_TRACE))) {
+               iter->iter_flags |= TRACE_FILE_PAUSE;
                tracing_stop_tr(tr);
+       }
 
        if (iter->cpu_file == RING_BUFFER_ALL_CPUS) {
                for_each_tracing_cpu(cpu) {
@@ -4842,7 +4844,7 @@ static int tracing_release(struct inode *inode, struct file *file)
        if (iter->trace && iter->trace->close)
                iter->trace->close(iter);
 
-       if (!iter->snapshot && tr->stop_count)
+       if (iter->iter_flags & TRACE_FILE_PAUSE)
                /* reenable tracing if it was previously enabled */
                tracing_start_tr(tr);