Thread (25 messages) 25 messages, 2 authors, 11d ago

Re: [PATCH v3 9/9] selftests/verification: add tlob selftests

From: Gabriele Monaco <gmonaco@redhat.com>
Date: 2026-06-22 09:26:49
Also in: lkml

On Mon, 2026-06-08 at 00:13 +0800, wen.yang@linux.dev wrote:
From: Wen Yang <redacted>

+grep -qE "^p ${UPROBE_TARGET}:0x[0-9a-f]+ 0x[0-9a-f]+ threshold=[0-
9]+$" "$TLOB_MONITOR"
+grep -q "threshold=5000000000" "$TLOB_MONITOR"
+
+! echo "p ${UPROBE_TARGET}:${busy_offset} ${stop_offset}
threshold=9999000" > "$TLOB_MONITOR" 2>/dev/null
+
+echo "-${UPROBE_TARGET}:${busy_offset}" > "$TLOB_MONITOR"
+! grep -q "^p .*:0x${busy_offset#0x} " "$TLOB_MONITOR"
...
+! grep -q "error_env_tlob" /sys/kernel/tracing/trace
There is a widespread misconception under selftests that ! cmd with set -e
fails if the command succeeds, so you can use it to expect a program failure.

That isn't the case though [1], errexit (what set -e does), skips commands starting
with ! where the result isn't checked.
Essentially if you want to say exit if the command succeeds, you can do:

  cmd && exit 1 # explicit
  ! cmd || exit 1 # explicit

or still exploiting errexit

  cmd && false
  ! cmd || false

I'm going to fix it in existing selftests using the last variant, but keep
this in mind in your selftests as well. (Variants with ! are preferred because
they also return 0 if cmd fails, as you'd expect, I personally prefer to use
false instead of explicit exit, but that's up to you).

Thanks,
Gabriele

[1] - https://www.shellcheck.net/wiki/SC2251
quoted hunk ↗ jump to hunk
+echo 0 > monitors/tlob/enable
+echo 0 > /sys/kernel/tracing/events/rv/error_env_tlob/enable
+echo > /sys/kernel/tracing/trace
diff --git
a/tools/testing/selftests/verification/test.d/tlob/uprobe_violation.t
c
b/tools/testing/selftests/verification/test.d/tlob/uprobe_violation.t
c
new file mode 100644
index 000000000000..d210d9c3a92d
--- /dev/null
+++
b/tools/testing/selftests/verification/test.d/tlob/uprobe_violation.t
c
@@ -0,0 +1,67 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Test tlob monitor budget violation (error_env_tlob
and detail_env_tlob fire with correct fields)
+# requires: tlob:monitor
+
+RV_BINDIR="${RV_BINDIR:-$(realpath "$(dirname "${1:-$0}")")}"
+UPROBE_TARGET="${RV_BINDIR}/tlob_target"
+TLOB_SYM="${RV_BINDIR}/tlob_sym"
+[ -x "$UPROBE_TARGET" ] || exit_unsupported
+[ -x "$TLOB_SYM" ]      || exit_unsupported
+TLOB_MONITOR=monitors/tlob/monitor
+
+busy_offset=$("$TLOB_SYM" sym_offset "$UPROBE_TARGET" tlob_busy_work
2>/dev/null)
+stop_offset=$("$TLOB_SYM" sym_offset "$UPROBE_TARGET"
tlob_busy_work_done 2>/dev/null)
+[ -n "$busy_offset" ] || exit_unsupported
+[ -n "$stop_offset" ] || exit_unsupported
+
+"$UPROBE_TARGET" 30000 &
+busy_pid=$!
+sleep 0.05
+
+echo 1 > /sys/kernel/tracing/events/rv/error_env_tlob/enable
+echo 1 > /sys/kernel/tracing/events/rv/detail_env_tlob/enable
+echo 1 > /sys/kernel/tracing/tracing_on
+echo 1 > monitors/tlob/enable
+echo > /sys/kernel/tracing/trace
+
+# 10 µs budget - fires almost immediately; task is busy-spinning on-
CPU.
+echo "p ${UPROBE_TARGET}:${busy_offset} ${stop_offset}
threshold=10000" > "$TLOB_MONITOR"
+
+# wait up to 2 s for detail_env_tlob
+found=0; i=0
+while [ "$i" -lt 20 ]; do
+	sleep 0.1
+	grep -q "detail_env_tlob" /sys/kernel/tracing/trace && {
found=1; break; }
+	i=$((i+1))
+done
+
+echo "-${UPROBE_TARGET}:${busy_offset}" > "$TLOB_MONITOR"
2>/dev/null
+kill "$busy_pid" 2>/dev/null || true; wait "$busy_pid" 2>/dev/null
|| true
+echo 0 > /sys/kernel/tracing/events/rv/error_env_tlob/enable
+echo 0 > /sys/kernel/tracing/events/rv/detail_env_tlob/enable
+echo 0 > monitors/tlob/enable
+
+[ "$found" = "1" ]
+
+# error_env_tlob must carry the clk_elapsed environment field.
+# The event label is "budget_exceeded" when detected by the hrtimer
callback,
+# or the triggering sched event name when detected by the constraint
path on a
+# preemption that races with the timer (common on PREEMPT_RT / VM). 
Both are
+# valid detections; check the env field instead of the label.
+grep "error_env_tlob" /sys/kernel/tracing/trace | head -n 1 | grep -
q "clk_elapsed="
+
+# detail_env_tlob must have all five fields with the correct
threshold
+line=$(grep "detail_env_tlob" /sys/kernel/tracing/trace | head -n 1)
+echo "$line" | grep -q "pid="
+echo "$line" | grep -q "threshold_ns=10000"
+echo "$line" | grep -q "running_ns="
+echo "$line" | grep -q "waiting_ns="
+echo "$line" | grep -q "sleeping_ns="
+
+# Busy-spin keeps the task on-CPU: running_ns must exceed
sleeping_ns.
+running=$(echo "$line" | sed 's/.*running_ns=\([0-9]*\).*/\1/')
+sleeping=$(echo "$line" | sed 's/.*sleeping_ns=\([0-9]*\).*/\1/')
+[ "$running" -gt "$sleeping" ]
+
+echo > /sys/kernel/tracing/trace
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help