[PATCH v2 14/15] tools/rv: Add selftest for rv bpf monitors
From: Gabriele Monaco
Date: Thu Oct 01 2026 - 11:57:59 EST
Add selftest cases for the rv userspace tool BPF monitors, test BPF
monitors listing and functionality, including traces and reactors.
Signed-off-by: Gabriele Monaco <gmonaco@xxxxxxxxxx>
---
tools/verification/rv/tests/rv_list.t | 6 ++-
tools/verification/rv/tests/rv_mon.t | 61 ++++++++++++++++++++++++++-
2 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/tools/verification/rv/tests/rv_list.t b/tools/verification/rv/tests/rv_list.t
index 201af33a52cc..3c94f2af2109 100644
--- a/tools/verification/rv/tests/rv_list.t
+++ b/tools/verification/rv/tests/rv_list.t
@@ -6,6 +6,8 @@ test_begin
set_timeout 30s
RVDIR=/sys/kernel/tracing/rv/
+# only works when running in the kernel tree
+RVTOOL=$(dirname "$RV")
# Help and basic tests
check "verify help page" \
@@ -17,13 +19,15 @@ check "verify list subcommand help" \
all_nested=$(grep : $RVDIR/available_monitors | cut -d: -f2 | paste -s | sed 's/\t/\\|/g')
all_non_nested=$(grep -v : $RVDIR/available_monitors | cut -d: -f2 | paste -s | sed 's/\t/\\|/g')
sched_monitors=$(grep sched: $RVDIR/available_monitors | cut -d: -f2 | paste -s | sed 's/\t/\\|/g')
+all_bpf=$(find "$RVTOOL/bpf_monitors" -name "*.o" -exec basename \{} .o \; | paste -s | sed 's/\t/\\|/g')
description_state="[[:space:]]\+[[:print:]]\+\[\(OFF\|ON\)\]"
line_nested=" - \($all_nested\)${description_state}"
line_non_nested="\($all_non_nested\)${description_state}"
+line_bpf="\($all_bpf\)${description_state}"
# List monitors and containers
check "list all monitors" \
- "$RV list" 0 "" "" "^\($line_nested\|$line_non_nested\)$"
+ "$RV list" 0 "" "" "^\($line_nested\|$line_non_nested\|$line_bpf\)$"
check_if_exists "list container" \
"$RV list sched" "$RVDIR/monitors/sched" \
diff --git a/tools/verification/rv/tests/rv_mon.t b/tools/verification/rv/tests/rv_mon.t
index cbc346c74c71..8e14471661c7 100644
--- a/tools/verification/rv/tests/rv_mon.t
+++ b/tools/verification/rv/tests/rv_mon.t
@@ -6,6 +6,7 @@ test_begin
set_timeout 30s
RVDIR=/sys/kernel/tracing/rv/
+RVTOOL=$(dirname "$RV")
# Help and basic tests
check "verify mon subcommand help" \
@@ -23,13 +24,34 @@ if [ -d $RVDIR/monitors/wwnr ]; then
check "invalid reactor name" \
"$RV mon wwnr -r invalid" 1 "failed to set invalid reactor, is it available?"
+check "invalid BPF reactor name" \
+ "$RV mon nohz -r invalid" 1 "failed to set invalid reactor, is it available?"
+
+check "invalid BPF reactor name check available" \
+ "$RV mon nohz -r invalid" 1 "available BPF reactors: nop [a-z]\+" \
+ "available reactors:"
+
check "monitor name is substring of another monitor" \
"$RV mon nr" 1 "monitor nr does not exist"
check "already enabled monitor returns error" \
"echo 1 > $RVDIR/monitors/wwnr/enable; $RV mon wwnr" 1 \
"monitor wwnr (in-kernel) is already enabled"
-echo 0 > $RVDIR/monitors/wwnr/enable
+[ -n "$TEST_COUNT" ] && echo 0 > $RVDIR/monitors/wwnr/enable
+
+fi
+
+if [ -f "$RVTOOL/bpf_monitors/tqueue.o" ]; then
+
+[ -n "$TEST_COUNT" ] && { $RV mon tqueue & disown ; tmp=$! ; sleep 1 ; }
+check "already enabled BPF monitor returns error" \
+ "$RV mon tqueue" 1 "monitor tqueue (BPF) is already enabled"
+
+[ -n "$TEST_COUNT" ] && { kill -9 "$tmp" && sleep 1 ; }
+set_expected_timeout 1s
+
+check "crashed BPF monitor does not leak resources" \
+ "$RV mon tqueue" 0 "" "monitor tqueue (BPF) is already enabled"
fi
@@ -40,6 +62,12 @@ set_expected_timeout 2s
check_if_exists "run the monitor without parameters" \
"$RV mon wwnr" "$RVDIR/monitors/wwnr" "" "."
+check_if_exists "run a BPF monitor without parameters" \
+ "$RV mon nohz" "$RVTOOL/bpf_monitors/nohz.o" "" "."
+
+check_if_exists "run a per-task BPF monitor without parameters" \
+ "$RV mon tqueue" "$RVTOOL/bpf_monitors/tqueue.o" "" "."
+
check_if_exists "run the monitor as verbose" \
"$RV mon wwnr -v" "$RVDIR/monitors/wwnr" \
"my pid is \$pid" "\(event\|error\)"
@@ -60,6 +88,20 @@ check_if_exists "run an explicitly nested monitor with a reactor" \
"$RV mon sched:sssw -r printk & sleep .5 && cat $RVDIR/monitors/sched/sssw/reactors && wait" \
"$RVDIR/monitors/sched/sssw/reactors" "\[printk\]"
+TRACE=/sys/kernel/tracing/trace
+
+[ -n "$TEST_COUNT" ] && echo -n > $TRACE
+check_if_exists "run a BPF monitor with a reactor" \
+ "$RV mon nohz -r printk && cat $TRACE" "$RVTOOL/bpf_monitors/nohz.o" \
+ "rv: monitor nohz does not allow event [a-z_]\+ on state [a-z_]\+"
+
+# Give some time for maps from previous run to be cleaned up
+[ -n "$TEST_COUNT" ] && sleep 1
+[ -n "$TEST_COUNT" ] && echo -n > $TRACE
+check_if_exists "run BPF monitors with nop reactor" \
+ "$RV mon nohz -r nop && cat $TRACE" "$RVTOOL/bpf_monitors/nohz.o" \
+ "" "rv: monitor nohz does not allow event"
+
check_if_exists "run container monitor" \
"$RV mon sched & sleep .5 && cat $RVDIR/monitors/sched/{sssw,sco}/enable && wait" \
"$RVDIR/monitors/sched" "1" "0" "^1$"
@@ -92,4 +134,21 @@ check_if_exists "run per-cpu monitor tracing also self" \
"$RV mon sco -t -s" "$RVDIR/monitors/sched/sco" \
"$trace_cpu_self" "" "\($header\|$trace_cpu\)"
+check_if_exists "run per-task BPF monitor with tracing" \
+ "$RV mon tqueue -t" "$RVTOOL/bpf_monitors/tqueue.o" \
+ "$header" "$trace_task_self" "\($header\|$trace_task\)"
+
+check_if_exists "run per-task BPF monitor tracing also self" \
+ "$RV mon tqueue -t -s" "$RVTOOL/bpf_monitors/tqueue.o" \
+ "$trace_task_self" "" "\($header\|$trace_task\)"
+
+check_if_exists "run per-cpu BPF monitor with tracing" \
+ "$RV mon nohz -t" "$RVTOOL/bpf_monitors/nohz.o" \
+ "$header" "$trace_cpu_self" "\($header\|$trace_cpu\)"
+
+# This is unstable, we may never see events from self
+#check_if_exists "run per-cpu BPF monitor tracing also self" \
+# "$RV mon nohz -t -s" "$RVTOOL/bpf_monitors/nohz.o" \
+# "$trace_cpu_self" "" "\($header\|$trace_cpu\)"
+
test_end
--
2.55.0