* [RFC PATCH bpf-next 0/2] ftrace: deprecate the ftrace_enabled disable switch
@ 2026-07-30 16:35 Andrey Grodzovsky
2026-07-30 16:35 ` [RFC PATCH bpf-next 1/2] ftrace: deprecate disabling via ftrace_enabled sysctl Andrey Grodzovsky
2026-07-30 16:35 ` [RFC PATCH bpf-next 2/2] selftests/livepatch: update test-ftrace.sh for deprecated ftrace_enabled Andrey Grodzovsky
0 siblings, 2 replies; 5+ messages in thread
From: Andrey Grodzovsky @ 2026-07-30 16:35 UTC (permalink / raw)
To: bpf, linux-trace-kernel, live-patching, linux-kselftest,
linux-doc
Cc: rostedt, corbet, jpoimboe, shuah, jolsa, mbenes, mhiramat, stable,
linux-open-source
This fixes a long-standing issue: kernel.ftrace_enabled=0 silently
disables BPF trampolines (fentry/fexit) and ftrace-based
kprobes/kretprobes. The write succeeds, the hook stops firing with no
error, and re-enabling silently restores it.
The solution chosen is to deny setting this knob to 0 from userspace,
thus preventing this case in the first place. Steven mentioned that the
switch became effectively useless and doesn't serve any meaningful
purpose anymore, and only creates problems for systems that rely on
ftrace, such as Livepatching and eBPF. Any attempt to set it to 0 will
fail with -EOPNOTSUPP. Reading and writing 1 remain unchanged.
Patch 1: the sysctl change plus a doc note.
Patch 2: updates the one selftest that relied on the old disable
behavior.
This replaces an earlier attempt[1] to restore FTRACE_OPS_FL_PERMANENT
on BPF trampolines and classic kprobes to work around the same issue.
Steven suggested this simpler approach instead: rather than
tracking down every caller that needs protecting, refuse to disable
ftrace via the sysctl unconditionally.
The original patch-set was a fix to commit 00963a2e75a8 ("bpf: Support
bpf_trampoline on functions with IPMODIFY (e.g. livepatch)"), and so we
would want to see this backported at least to LTS branches starting
with 6.1. But since this is effectively a new behavior and technically not a bug
fix, I am not sure what the policy is in this case.
[1] https://lore.kernel.org/bpf/20260729005959.3853865-1-andrey.grodzovsky@crowdstrike.com/
Andrey Grodzovsky (2):
ftrace: deprecate disabling via ftrace_enabled sysctl
selftests/livepatch: update test-ftrace.sh for deprecated
ftrace_enabled
Documentation/trace/ftrace.rst | 5 ++
kernel/trace/ftrace.c | 19 +++----
.../selftests/livepatch/test-ftrace.sh | 49 ++-----------------
3 files changed, 16 insertions(+), 57 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC PATCH bpf-next 1/2] ftrace: deprecate disabling via ftrace_enabled sysctl
2026-07-30 16:35 [RFC PATCH bpf-next 0/2] ftrace: deprecate the ftrace_enabled disable switch Andrey Grodzovsky
@ 2026-07-30 16:35 ` Andrey Grodzovsky
2026-07-30 17:10 ` sashiko-bot
2026-07-30 16:35 ` [RFC PATCH bpf-next 2/2] selftests/livepatch: update test-ftrace.sh for deprecated ftrace_enabled Andrey Grodzovsky
1 sibling, 1 reply; 5+ messages in thread
From: Andrey Grodzovsky @ 2026-07-30 16:35 UTC (permalink / raw)
To: bpf, linux-trace-kernel, live-patching, linux-kselftest,
linux-doc
Cc: rostedt, corbet, jpoimboe, shuah, jolsa, mbenes, mhiramat, stable,
linux-open-source
Writing 0 to kernel.ftrace_enabled has not reliably disabled ftrace
for years (FTRACE_OPS_FL_PERMANENT users already block it, and more
callers rely on ftrace always being on). Refuse the write instead of
leaving it in an inconsistent "disables some, not all" state: return
-EOPNOTSUPP and log a message. Reads and enabling (writing 1) are
unaffected.
Update the docs to note the deprecation up front.
Suggested-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
---
Documentation/trace/ftrace.rst | 5 +++++
kernel/trace/ftrace.c | 19 ++++++++-----------
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst
index 84f06bf0da9b..7261f25f8b4b 100644
--- a/Documentation/trace/ftrace.rst
+++ b/Documentation/trace/ftrace.rst
@@ -3313,6 +3313,11 @@ this special filter via::
ftrace_enabled
--------------
+.. note::
+ Disabling ftrace via this switch is deprecated. Writing 0 is refused
+ with -EOPNOTSUPP and logs a warning; writing 1 and reading the value
+ are unaffected.
+
Note, the proc sysctl ftrace_enable is a big on/off switch for the
function tracer. By default it is enabled (when function tracing is
enabled in the kernel). If it is disabled, all function tracing is
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index f93e34dd2328..82bb7356ccce 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -9357,7 +9357,7 @@ static void ftrace_startup_sysctl(void)
}
}
-static void ftrace_shutdown_sysctl(void)
+static void __maybe_unused ftrace_shutdown_sysctl(void)
{
int command;
@@ -9377,7 +9377,7 @@ static void ftrace_shutdown_sysctl(void)
# define ftrace_shutdown_sysctl() do { } while (0)
#endif /* CONFIG_DYNAMIC_FTRACE */
-static bool is_permanent_ops_registered(void)
+static bool __maybe_unused is_permanent_ops_registered(void)
{
struct ftrace_ops *op;
@@ -9415,15 +9415,12 @@ ftrace_enable_sysctl(const struct ctl_table *table, int write,
ftrace_startup_sysctl();
} else {
- if (is_permanent_ops_registered()) {
- ftrace_enabled = true;
- return -EBUSY;
- }
-
- /* stopping ftrace calls (just send to ftrace_stub) */
- ftrace_trace_function = ftrace_stub;
-
- ftrace_shutdown_sysctl();
+ /*
+ * Disabling ftrace at runtime via this knob is deprecated.
+ */
+ ftrace_enabled = true;
+ pr_warn_once("The ftrace_enabled file is deprecated and no longer disables ftrace\n");
+ return -EOPNOTSUPP;
}
last_ftrace_enabled = !!ftrace_enabled;
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC PATCH bpf-next 2/2] selftests/livepatch: update test-ftrace.sh for deprecated ftrace_enabled
2026-07-30 16:35 [RFC PATCH bpf-next 0/2] ftrace: deprecate the ftrace_enabled disable switch Andrey Grodzovsky
2026-07-30 16:35 ` [RFC PATCH bpf-next 1/2] ftrace: deprecate disabling via ftrace_enabled sysctl Andrey Grodzovsky
@ 2026-07-30 16:35 ` Andrey Grodzovsky
2026-07-31 0:09 ` Steven Rostedt
1 sibling, 1 reply; 5+ messages in thread
From: Andrey Grodzovsky @ 2026-07-30 16:35 UTC (permalink / raw)
To: bpf, linux-trace-kernel, live-patching, linux-kselftest,
linux-doc
Cc: rostedt, corbet, jpoimboe, shuah, jolsa, mbenes, mhiramat, stable,
linux-open-source
kernel.ftrace_enabled=0 is now always refused, so the old scenario
(disable, fail to load a livepatch, re-enable, load) no longer applies.
Replace it with a single check that the write is refused with the new
error, and drop the now-stale disable/reload flow.
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
---
.../selftests/livepatch/test-ftrace.sh | 49 ++-----------------
1 file changed, 3 insertions(+), 46 deletions(-)
diff --git a/tools/testing/selftests/livepatch/test-ftrace.sh b/tools/testing/selftests/livepatch/test-ftrace.sh
index d2c3dea63104..c88f4d13a134 100755
--- a/tools/testing/selftests/livepatch/test-ftrace.sh
+++ b/tools/testing/selftests/livepatch/test-ftrace.sh
@@ -9,56 +9,13 @@ MOD_LIVEPATCH=test_klp_livepatch
setup_config
-# - turn ftrace_enabled OFF and verify livepatches can't load
-# - turn ftrace_enabled ON and verify livepatch can load
-# - verify that ftrace_enabled can't be turned OFF while a livepatch is loaded
+# - verify that kernel.ftrace_enabled=0 is refused (deprecated knob)
-start_test "livepatch interaction with ftrace_enabled sysctl"
+start_test "ftrace_enabled sysctl write is refused (deprecated)"
-set_ftrace_enabled 0
-load_failing_mod $MOD_LIVEPATCH
-
-set_ftrace_enabled 1
-load_lp $MOD_LIVEPATCH
-if [[ "$(cat /proc/cmdline)" != "$MOD_LIVEPATCH: this has been live patched" ]] ; then
- echo -e "FAIL\n\n"
- die "livepatch kselftest(s) failed"
-fi
-
-# Check that ftrace could not get disabled when a livepatch is enabled
set_ftrace_enabled --fail 0
-if [[ "$(cat /proc/cmdline)" != "$MOD_LIVEPATCH: this has been live patched" ]] ; then
- echo -e "FAIL\n\n"
- die "livepatch kselftest(s) failed"
-fi
-disable_lp $MOD_LIVEPATCH
-unload_lp $MOD_LIVEPATCH
-check_result "livepatch: kernel.ftrace_enabled = 0
-% insmod test_modules/$MOD_LIVEPATCH.ko
-livepatch: enabling patch '$MOD_LIVEPATCH'
-livepatch: '$MOD_LIVEPATCH': initializing patching transition
-livepatch: failed to register ftrace handler for function 'cmdline_proc_show' (-16)
-livepatch: failed to patch object 'vmlinux'
-livepatch: failed to enable patch '$MOD_LIVEPATCH'
-livepatch: '$MOD_LIVEPATCH': canceling patching transition, going to unpatch
-livepatch: '$MOD_LIVEPATCH': completing unpatching transition
-livepatch: '$MOD_LIVEPATCH': unpatching complete
-insmod: ERROR: could not insert module test_modules/$MOD_LIVEPATCH.ko: Device or resource busy
-livepatch: kernel.ftrace_enabled = 1
-% insmod test_modules/$MOD_LIVEPATCH.ko
-livepatch: enabling patch '$MOD_LIVEPATCH'
-livepatch: '$MOD_LIVEPATCH': initializing patching transition
-livepatch: '$MOD_LIVEPATCH': starting patching transition
-livepatch: '$MOD_LIVEPATCH': completing patching transition
-livepatch: '$MOD_LIVEPATCH': patching complete
-livepatch: sysctl: setting key \"kernel.ftrace_enabled\": Device or resource busy
-% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled
-livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
-livepatch: '$MOD_LIVEPATCH': starting unpatching transition
-livepatch: '$MOD_LIVEPATCH': completing unpatching transition
-livepatch: '$MOD_LIVEPATCH': unpatching complete
-% rmmod $MOD_LIVEPATCH"
+check_result "livepatch: sysctl: setting key \"kernel.ftrace_enabled\": Operation not supported"
# - verify livepatch can load
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [RFC PATCH bpf-next 1/2] ftrace: deprecate disabling via ftrace_enabled sysctl
2026-07-30 16:35 ` [RFC PATCH bpf-next 1/2] ftrace: deprecate disabling via ftrace_enabled sysctl Andrey Grodzovsky
@ 2026-07-30 17:10 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-07-30 17:10 UTC (permalink / raw)
To: Andrey Grodzovsky; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] The livepatch ftrace selftest is broken because it explicitly tests the deprecated `kernel.ftrace_enabled` sysctl behavior.
- [Low] The functions `ftrace_shutdown_sysctl` and `is_permanent_ops_registered` are now completely unused but are left in the codebase.
--
--- Patch [1]: [RFC PATCH bpf-next 1/2] ftrace: deprecate disabling via ftrace_enabled sysctl ---
commit b118500ef9b6245b16b7bddf0a01d982bf5b52ce
Author: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
ftrace: deprecate disabling via ftrace_enabled sysctl
This commit deprecates disabling ftrace via the kernel.ftrace_enabled
sysctl. Writing 0 to the sysctl now returns -EOPNOTSUPP and logs a warning
instead of attempting to disable ftrace.
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index f93e34dd23288..82bb7356ccce5 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -9357,7 +9357,7 @@ static void ftrace_startup_sysctl(void)
> }
> }
>
> -static void ftrace_shutdown_sysctl(void)
> +static void __maybe_unused ftrace_shutdown_sysctl(void)
[Severity: Low]
Since the only caller in ftrace_enable_sysctl() has been removed, should this
function be deleted entirely instead of keeping it around as dead code with
the __maybe_unused attribute?
[ ... ]
> -static bool is_permanent_ops_registered(void)
> +static bool __maybe_unused is_permanent_ops_registered(void)
[Severity: Low]
Similarly, should this function be removed entirely since it is no longer
called anywhere?
> @@ -9415,15 +9415,12 @@ ftrace_enable_sysctl(const struct ctl_table *table, int write,
> ftrace_startup_sysctl();
>
> } else {
> - if (is_permanent_ops_registered()) {
> - ftrace_enabled = true;
> - return -EBUSY;
> - }
> -
> - /* stopping ftrace calls (just send to ftrace_stub) */
> - ftrace_trace_function = ftrace_stub;
> -
> - ftrace_shutdown_sysctl();
> + /*
> + * Disabling ftrace at runtime via this knob is deprecated.
> + */
> + ftrace_enabled = true;
> + pr_warn_once("The ftrace_enabled file is deprecated and no longer disables ftrace\n");
> + return -EOPNOTSUPP;
[Severity: Medium]
Will this break the livepatch selftests?
The script tools/testing/selftests/livepatch/test-ftrace.sh explicitly attempts
to write 0 to the sysctl on line 18:
tools/testing/selftests/livepatch/test-ftrace.sh:
set_ftrace_enabled 0
Because this is now refused, the helper function in functions.sh detects the
failure and skips:
tools/testing/selftests/livepatch/functions.sh:set_ftrace_enabled() {
...
if [[ $(cat /proc/sys/kernel/ftrace_enabled) != "$1" ]]; then
skip "failed to set kernel.ftrace_enabled = $1"
...
}
This skip call unconditionally exits the script, preventing the remaining tests
in the file from running. Should the selftests be updated to reflect this
change in behavior?
> }
>
> last_ftrace_enabled = !!ftrace_enabled;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730163544.2042327-1-andrey.grodzovsky@crowdstrike.com?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC PATCH bpf-next 2/2] selftests/livepatch: update test-ftrace.sh for deprecated ftrace_enabled
2026-07-30 16:35 ` [RFC PATCH bpf-next 2/2] selftests/livepatch: update test-ftrace.sh for deprecated ftrace_enabled Andrey Grodzovsky
@ 2026-07-31 0:09 ` Steven Rostedt
0 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2026-07-31 0:09 UTC (permalink / raw)
To: Andrey Grodzovsky
Cc: bpf, linux-trace-kernel, live-patching, linux-kselftest,
linux-doc, corbet, jpoimboe, shuah, jolsa, mbenes, mhiramat,
stable, linux-open-source
On Thu, 30 Jul 2026 12:35:44 -0400
Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com> wrote:
> kernel.ftrace_enabled=0 is now always refused, so the old scenario
> (disable, fail to load a livepatch, re-enable, load) no longer applies.
> Replace it with a single check that the write is refused with the new
> error, and drop the now-stale disable/reload flow.
>
> Assisted-by: Claude:claude-sonnet-5
> Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
> ---
> .../selftests/livepatch/test-ftrace.sh | 49 ++-----------------
> 1 file changed, 3 insertions(+), 46 deletions(-)
>
> diff --git a/tools/testing/selftests/livepatch/test-ftrace.sh b/tools/testing/selftests/livepatch/test-ftrace.sh
> index d2c3dea63104..c88f4d13a134 100755
> --- a/tools/testing/selftests/livepatch/test-ftrace.sh
> +++ b/tools/testing/selftests/livepatch/test-ftrace.sh
> @@ -9,56 +9,13 @@ MOD_LIVEPATCH=test_klp_livepatch
> setup_config
>
>
> -# - turn ftrace_enabled OFF and verify livepatches can't load
> -# - turn ftrace_enabled ON and verify livepatch can load
> -# - verify that ftrace_enabled can't be turned OFF while a livepatch is loaded
> +# - verify that kernel.ftrace_enabled=0 is refused (deprecated knob)
>
> -start_test "livepatch interaction with ftrace_enabled sysctl"
> +start_test "ftrace_enabled sysctl write is refused (deprecated)"
>
> -set_ftrace_enabled 0
> -load_failing_mod $MOD_LIVEPATCH
> -
> -set_ftrace_enabled 1
> -load_lp $MOD_LIVEPATCH
> -if [[ "$(cat /proc/cmdline)" != "$MOD_LIVEPATCH: this has been live patched" ]] ; then
> - echo -e "FAIL\n\n"
> - die "livepatch kselftest(s) failed"
> -fi
> -
This test should work for both old and new kernels. I would have it still
do everything here but if setting ftrace_enabled returns -EOPNOTSUPP then
do the simple path.
-- Steve
> -# Check that ftrace could not get disabled when a livepatch is enabled
> set_ftrace_enabled --fail 0
> -if [[ "$(cat /proc/cmdline)" != "$MOD_LIVEPATCH: this has been live patched" ]] ; then
> - echo -e "FAIL\n\n"
> - die "livepatch kselftest(s) failed"
> -fi
> -disable_lp $MOD_LIVEPATCH
> -unload_lp $MOD_LIVEPATCH
>
> -check_result "livepatch: kernel.ftrace_enabled = 0
> -% insmod test_modules/$MOD_LIVEPATCH.ko
> -livepatch: enabling patch '$MOD_LIVEPATCH'
> -livepatch: '$MOD_LIVEPATCH': initializing patching transition
> -livepatch: failed to register ftrace handler for function 'cmdline_proc_show' (-16)
> -livepatch: failed to patch object 'vmlinux'
> -livepatch: failed to enable patch '$MOD_LIVEPATCH'
> -livepatch: '$MOD_LIVEPATCH': canceling patching transition, going to unpatch
> -livepatch: '$MOD_LIVEPATCH': completing unpatching transition
> -livepatch: '$MOD_LIVEPATCH': unpatching complete
> -insmod: ERROR: could not insert module test_modules/$MOD_LIVEPATCH.ko: Device or resource busy
> -livepatch: kernel.ftrace_enabled = 1
> -% insmod test_modules/$MOD_LIVEPATCH.ko
> -livepatch: enabling patch '$MOD_LIVEPATCH'
> -livepatch: '$MOD_LIVEPATCH': initializing patching transition
> -livepatch: '$MOD_LIVEPATCH': starting patching transition
> -livepatch: '$MOD_LIVEPATCH': completing patching transition
> -livepatch: '$MOD_LIVEPATCH': patching complete
> -livepatch: sysctl: setting key \"kernel.ftrace_enabled\": Device or resource busy
> -% echo 0 > $SYSFS_KLP_DIR/$MOD_LIVEPATCH/enabled
> -livepatch: '$MOD_LIVEPATCH': initializing unpatching transition
> -livepatch: '$MOD_LIVEPATCH': starting unpatching transition
> -livepatch: '$MOD_LIVEPATCH': completing unpatching transition
> -livepatch: '$MOD_LIVEPATCH': unpatching complete
> -% rmmod $MOD_LIVEPATCH"
> +check_result "livepatch: sysctl: setting key \"kernel.ftrace_enabled\": Operation not supported"
>
>
> # - verify livepatch can load
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-31 0:08 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 16:35 [RFC PATCH bpf-next 0/2] ftrace: deprecate the ftrace_enabled disable switch Andrey Grodzovsky
2026-07-30 16:35 ` [RFC PATCH bpf-next 1/2] ftrace: deprecate disabling via ftrace_enabled sysctl Andrey Grodzovsky
2026-07-30 17:10 ` sashiko-bot
2026-07-30 16:35 ` [RFC PATCH bpf-next 2/2] selftests/livepatch: update test-ftrace.sh for deprecated ftrace_enabled Andrey Grodzovsky
2026-07-31 0:09 ` Steven Rostedt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.