From: Steven Rostedt <rostedt@goodmis.org>
A few bugs were found in the fprobe accounting logic along with it using
the function graph infrastructure. Update the fprobe selftest to catch
those bugs in case they or something similar shows up in the future.
The test now checks the enabled_functions file which shows all the
functions attached to ftrace or fgraph. When enabling a fprobe, make sure
that its corresponding function is also added to that file. Also add two
more fprobes to enable to make sure that the fprobe logic works properly
with multiple probes.
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Tested-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
.../test.d/dynevent/add_remove_fprobe.tc | 54 +++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc
index dc25bcf4f9e2..449f9d8be746 100644
--- a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc
+++ b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc
@@ -7,12 +7,38 @@ echo 0 > events/enable
echo > dynamic_events
PLACE=$FUNCTION_FORK
+PLACE2="kmem_cache_free"
+PLACE3="schedule_timeout"
echo "f:myevent1 $PLACE" >> dynamic_events
+
+# Make sure the event is attached and is the only one
+grep -q $PLACE enabled_functions
+cnt=`cat enabled_functions | wc -l`
+if [ $cnt -ne 1 ]; then
+ exit_fail
+fi
+
echo "f:myevent2 $PLACE%return" >> dynamic_events
+# It should till be the only attached function
+cnt=`cat enabled_functions | wc -l`
+if [ $cnt -ne 1 ]; then
+ exit_fail
+fi
+
+# add another event
+echo "f:myevent3 $PLACE2" >> dynamic_events
+
+grep -q $PLACE2 enabled_functions
+cnt=`cat enabled_functions | wc -l`
+if [ $cnt -ne 2 ]; then
+ exit_fail
+fi
+
grep -q myevent1 dynamic_events
grep -q myevent2 dynamic_events
+grep -q myevent3 dynamic_events
test -d events/fprobes/myevent1
test -d events/fprobes/myevent2
@@ -21,6 +47,34 @@ echo "-:myevent2" >> dynamic_events
grep -q myevent1 dynamic_events
! grep -q myevent2 dynamic_events
+# should still have 2 left
+cnt=`cat enabled_functions | wc -l`
+if [ $cnt -ne 2 ]; then
+ exit_fail
+fi
+
echo > dynamic_events
+# Should have none left
+cnt=`cat enabled_functions | wc -l`
+if [ $cnt -ne 0 ]; then
+ exit_fail
+fi
+
+echo "f:myevent4 $PLACE" >> dynamic_events
+
+# Should only have one enabled
+cnt=`cat enabled_functions | wc -l`
+if [ $cnt -ne 1 ]; then
+ exit_fail
+fi
+
+echo > dynamic_events
+
+# Should have none left
+cnt=`cat enabled_functions | wc -l`
+if [ $cnt -ne 0 ]; then
+ exit_fail
+fi
+
clear_trace
--
2.47.2
On Thu, Feb 20, 2025 at 03:20:14PM -0500, Steven Rostedt wrote:
> From: Steven Rostedt <rostedt@goodmis.org>
>
> A few bugs were found in the fprobe accounting logic along with it using
> the function graph infrastructure. Update the fprobe selftest to catch
> those bugs in case they or something similar shows up in the future.
>
> The test now checks the enabled_functions file which shows all the
> functions attached to ftrace or fgraph. When enabling a fprobe, make sure
> that its corresponding function is also added to that file. Also add two
> more fprobes to enable to make sure that the fprobe logic works properly
> with multiple probes.
>
> Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> Tested-by: Heiko Carstens <hca@linux.ibm.com>
> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
> ---
> .../test.d/dynevent/add_remove_fprobe.tc | 54 +++++++++++++++++++
> 1 file changed, 54 insertions(+)
>
> diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc
> index dc25bcf4f9e2..449f9d8be746 100644
> --- a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc
> +++ b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc
> @@ -7,12 +7,38 @@ echo 0 > events/enable
> echo > dynamic_events
>
> PLACE=$FUNCTION_FORK
> +PLACE2="kmem_cache_free"
> +PLACE3="schedule_timeout"
>
> echo "f:myevent1 $PLACE" >> dynamic_events
> +
> +# Make sure the event is attached and is the only one
> +grep -q $PLACE enabled_functions
> +cnt=`cat enabled_functions | wc -l`
> +if [ $cnt -ne 1 ]; then
> + exit_fail
> +fi
Bah.. :) this doesn't work always, since at least with Fedora 41 the
assumption that there are zero enabled functions before this test is
executed is not necessarily true:
# cat tracing/enabled_functions
free_user_ns (1) R
bpf_lsm_path_mkdir (1) R D M tramp: ftrace_regs_caller+0x0/0x68 (call_direct_funcs+0x0/0x20)
direct-->bpf_trampoline_6442505669+0x0/0x148
bpf_lsm_path_mknod (1) R D M tramp: ftrace_regs_caller+0x0/0x68 (call_direct_funcs+0x0/0x20)
direct-->bpf_trampoline_6442505671+0x0/0x14e
...
I didn't stumble across this before, since I tried a monolithic kernel
without modules when verifying your series; and then there aren't any
enabled functions. But with modules there are.
This could be worked around for example with something like the patch
below (against linux-next). But no idea what your preferred way to
handle this would be.
diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc
index 449f9d8be746..b0f24c57b8e1 100644
--- a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc
+++ b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_fprobe.tc
@@ -10,12 +10,14 @@ PLACE=$FUNCTION_FORK
PLACE2="kmem_cache_free"
PLACE3="schedule_timeout"
+ocnt=`cat enabled_functions | wc -l`
+
echo "f:myevent1 $PLACE" >> dynamic_events
# Make sure the event is attached and is the only one
grep -q $PLACE enabled_functions
cnt=`cat enabled_functions | wc -l`
-if [ $cnt -ne 1 ]; then
+if [ $cnt -ne $((ocnt + 1)) ]; then
exit_fail
fi
@@ -23,7 +25,7 @@ echo "f:myevent2 $PLACE%return" >> dynamic_events
# It should till be the only attached function
cnt=`cat enabled_functions | wc -l`
-if [ $cnt -ne 1 ]; then
+if [ $cnt -ne $((ocnt + 1)) ]; then
exit_fail
fi
@@ -32,7 +34,7 @@ echo "f:myevent3 $PLACE2" >> dynamic_events
grep -q $PLACE2 enabled_functions
cnt=`cat enabled_functions | wc -l`
-if [ $cnt -ne 2 ]; then
+if [ $cnt -ne $((ocnt + 2)) ]; then
exit_fail
fi
@@ -49,7 +51,7 @@ grep -q myevent1 dynamic_events
# should still have 2 left
cnt=`cat enabled_functions | wc -l`
-if [ $cnt -ne 2 ]; then
+if [ $cnt -ne $((ocnt + 2)) ]; then
exit_fail
fi
@@ -57,7 +59,7 @@ echo > dynamic_events
# Should have none left
cnt=`cat enabled_functions | wc -l`
-if [ $cnt -ne 0 ]; then
+if [ $cnt -ne $ocnt ]; then
exit_fail
fi
@@ -65,7 +67,7 @@ echo "f:myevent4 $PLACE" >> dynamic_events
# Should only have one enabled
cnt=`cat enabled_functions | wc -l`
-if [ $cnt -ne 1 ]; then
+if [ $cnt -ne $((ocnt + 1)) ]; then
exit_fail
fi
@@ -73,7 +75,7 @@ echo > dynamic_events
# Should have none left
cnt=`cat enabled_functions | wc -l`
-if [ $cnt -ne 0 ]; then
+if [ $cnt -ne $ocnt ]; then
exit_fail
fi
On Wed, 26 Feb 2025 11:50:28 +0100 Heiko Carstens <hca@linux.ibm.com> wrote: > Bah.. :) this doesn't work always, since at least with Fedora 41 the > assumption that there are zero enabled functions before this test is > executed is not necessarily true: > > # cat tracing/enabled_functions > free_user_ns (1) R > bpf_lsm_path_mkdir (1) R D M tramp: ftrace_regs_caller+0x0/0x68 (call_direct_funcs+0x0/0x20) > direct-->bpf_trampoline_6442505669+0x0/0x148 > bpf_lsm_path_mknod (1) R D M tramp: ftrace_regs_caller+0x0/0x68 (call_direct_funcs+0x0/0x20) > direct-->bpf_trampoline_6442505671+0x0/0x14e After I submitted the patches, I then remembered that some user space tools add BPF programs that attach to functions, and those will show up in the enabled_functions table (that's a feature as it is always good to know what is modifying your kernel!). And I figured it will break this test. I decided to wait until someone complains about it before fixing it ;-) > ... > > I didn't stumble across this before, since I tried a monolithic kernel > without modules when verifying your series; and then there aren't any > enabled functions. But with modules there are. > > This could be worked around for example with something like the patch > below (against linux-next). But no idea what your preferred way to > handle this would be. Actually, when I thought about fixing this, your patch is pretty much what I was thinking of doing. -- Steve
On Wed, Feb 26, 2025 at 08:47:59AM -0500, Steven Rostedt wrote: > On Wed, 26 Feb 2025 11:50:28 +0100 > Heiko Carstens <hca@linux.ibm.com> wrote: > > # cat tracing/enabled_functions > > free_user_ns (1) R > > bpf_lsm_path_mkdir (1) R D M tramp: ftrace_regs_caller+0x0/0x68 (call_direct_funcs+0x0/0x20) > > direct-->bpf_trampoline_6442505669+0x0/0x148 > > bpf_lsm_path_mknod (1) R D M tramp: ftrace_regs_caller+0x0/0x68 (call_direct_funcs+0x0/0x20) > > direct-->bpf_trampoline_6442505671+0x0/0x14e > > After I submitted the patches, I then remembered that some user space tools > add BPF programs that attach to functions, and those will show up in the > enabled_functions table (that's a feature as it is always good to know what > is modifying your kernel!). And I figured it will break this test. > > I decided to wait until someone complains about it before fixing it ;-) ... > > > > This could be worked around for example with something like the patch > > below (against linux-next). But no idea what your preferred way to > > handle this would be. > > Actually, when I thought about fixing this, your patch is pretty much what > I was thinking of doing. Ok, I'll send a proper patch then.
© 2016 - 2025 Red Hat, Inc.