FAILED: patch "[PATCH] tracing: Fix syscall events activation by ensuring refcount" failed to apply to 5.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 0a663b764dbdf135a126284f454c9f01f95a87d4
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026031721-construct-envelope-2cf6@gregkh' --subject-prefix 'PATCH 5.10.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 0a663b764dbdf135a126284f454c9f01f95a87d4 Mon Sep 17 00:00:00 2001
From: Huiwen He <[email protected]>
Date: Tue, 24 Feb 2026 10:35:44 +0800
Subject: [PATCH] tracing: Fix syscall events activation by ensuring refcount
hits zero
When multiple syscall events are specified in the kernel command line (e.g., trace_event=syscalls:sys_enter_openat,syscalls:sys_enter_close), they are often not captured after boot, even though they appear enabled in the tracing/set_event file.
The issue stems from how syscall events are initialized. Syscall tracepoints require the global reference count (sys_tracepoint_refcount) to transition from 0 to 1 to trigger the registration of the syscall work (TIF_SYSCALL_TRACEPOINT) for tasks, including the init process (pid 1).
The current implementation of early_enable_events() with disable_first=true used an interleaved sequence of "Disable A -> Enable A -> Disable B -> Enable B". If multiple syscalls are enabled, the refcount never drops to zero, preventing the 0->1 transition that triggers actual registration.
Fix this by splitting early_enable_events() into two distinct phases:
1. Disable all events specified in the buffer.
2. Enable all events specified in the buffer.
This ensures the refcount hits zero before re-enabling, allowing syscall events to be properly activated during early boot.
The code is also refactored to use a helper function to avoid logic duplication between the disable and enable phases.
kernel/trace/trace_events.c +37 -15
@@ -4668,26 +4668,22 @@ static __init int event_trace_memsetup(void)return 0 ; } -__init void -early_enable_events (struct trace_array *tr,char *buf,bool disable_first) +/* +* Helper function to enable or disable a comma-separated list of events +* from the bootup buffer. +*/ +static __init void __early_set_events (struct trace_array *tr,char *buf,bool enable) {char *token; -int ret; - -while (true) { - token =strsep (&buf,"," ); - -if (!token) -break ; +while ((token =strsep (&buf,"," ))) {if (*token) { -/* Restarting syscalls requires that we stop them first */ -if (disable_first) +if (enable) { +if (ftrace_set_clr_event (tr, token,1 )) +pr_warn ("Failed to enable trace event: %s\n" , token); + }else {ftrace_set_clr_event (tr, token,0 ); - - ret =ftrace_set_clr_event (tr, token,1 ); -if (ret) -pr_warn ("Failed to enable trace event: %s\n" , token); + } }/* Put back the comma to allow this to be called again */
@@ -4696,6 +4692,32 @@ early_enable_events(struct trace_array *tr, char *buf, bool disable_first) } } +/** +* early_enable_events - enable events from the bootup buffer +* @tr: The trace array to enable the events in +* @buf: The buffer containing the comma separated list of events +* @disable_first: If true, disable all events in @buf before enabling them +* +* This function enables events from the bootup buffer. If @disable_first +* is true, it will first disable all events in the buffer before enabling +* them. +* +* For syscall events, which rely on a global refcount to register the +* SYSCALL_WORK_SYSCALL_TRACEPOINT flag (especially for pid 1), we must +* ensure the refcount hits zero before re-enabling them. A simple +* "disable then enable" per-event is not enough if multiple syscalls are +* used, as the refcount will stay above zero. Thus, we need a two-phase +* approach: disable all, then enable all. +*/ +__init void +early_enable_events (struct trace_array *tr,char *buf,bool disable_first) +{ +if (disable_first) +__early_set_events (tr, buf, false); + +__early_set_events (tr, buf, true); +} +static __init int event_trace_enable (void ) {struct trace_array *tr =top_trace_array ();
Sasha Levin
maintainerPATCH 1/1 tracing: Fix syscall events activation by ensuring refcount hits zero
From: Huiwen He <[email protected]>
[ Upstream commit 0a663b764dbdf135a126284f454c9f01f95a87d4 ]
When multiple syscall events are specified in the kernel command line (e.g., trace_event=syscalls:sys_enter_openat,syscalls:sys_enter_close), they are often not captured after boot, even though they appear enabled in the tracing/set_event file.
The issue stems from how syscall events are initialized. Syscall tracepoints require the global reference count (sys_tracepoint_refcount) to transition from 0 to 1 to trigger the registration of the syscall work (TIF_SYSCALL_TRACEPOINT) for tasks, including the init process (pid 1).
The current implementation of early_enable_events() with disable_first=true used an interleaved sequence of "Disable A -> Enable A -> Disable B -> Enable B". If multiple syscalls are enabled, the refcount never drops to zero, preventing the 0->1 transition that triggers actual registration.
Fix this by splitting early_enable_events() into two distinct phases:
1. Disable all events specified in the buffer.
2. Enable all events specified in the buffer.
This ensures the refcount hits zero before re-enabling, allowing syscall events to be properly activated during early boot.
The code is also refactored to use a helper function to avoid logic duplication between the disable and enable phases.
--- kernel/trace/trace_events.c | 51 ++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 15 deletions(-)
kernel/trace/trace_events.c +36 -15
@@ -3393,27 +3393,23 @@ static __init int event_trace_memsetup(void)return 0 ; } -static __init void -early_enable_events (struct trace_array *tr,bool disable_first) +/* +* Helper function to enable or disable a comma-separated list of events +* from the bootup buffer. +*/ +static __init void __early_set_events (struct trace_array *tr,bool enable) {char *buf = bootup_event_buf;char *token; -int ret; - -while (true) { - token =strsep (&buf,"," ); - -if (!token) -break ; +while ((token =strsep (&buf,"," ))) {if (*token) { -/* Restarting syscalls requires that we stop them first */ -if (disable_first) +if (enable) { +if (ftrace_set_clr_event (tr, token,1 )) +pr_warn ("Failed to enable trace event: %s\n" , token); + }else {ftrace_set_clr_event (tr, token,0 ); - - ret =ftrace_set_clr_event (tr, token,1 ); -if (ret) -pr_warn ("Failed to enable trace event: %s\n" , token); + } }/* Put back the comma to allow this to be called again */
@@ -3422,6 +3418,31 @@ early_enable_events(struct trace_array *tr, bool disable_first) } } +/** +* early_enable_events - enable events from the bootup buffer +* @tr: The trace array to enable the events in +* @disable_first: If true, disable all events before enabling them +* +* This function enables events from the bootup buffer. If @disable_first +* is true, it will first disable all events in the buffer before enabling +* them. +* +* For syscall events, which rely on a global refcount to register the +* SYSCALL_WORK_SYSCALL_TRACEPOINT flag (especially for pid 1), we must +* ensure the refcount hits zero before re-enabling them. A simple +* "disable then enable" per-event is not enough if multiple syscalls are +* used, as the refcount will stay above zero. Thus, we need a two-phase +* approach: disable all, then enable all. +*/ +static __init void +early_enable_events (struct trace_array *tr,bool disable_first) +{ +if (disable_first) +__early_set_events (tr, false); + +__early_set_events (tr, true); +} +static __init int event_trace_enable (void ) {struct trace_array *tr =top_trace_array ();
Signature · 1 line
2.51.0