[PATCH v3 07/13] perf tests: Fix flakiness in trace record and replay test
From: Ian Rogers
Date: Tue Jun 16 2026 - 13:00:51 EST
The `perf trace record and replay` test fails intermittently on slow or
virtualized hosts because the default recording workload (`sleep 1`)
occasionally completes without scheduling the target `nanosleep` or
`clock_nanosleep` system calls inside the recorded sample window,
resulting in the error: `Failed: cannot find *nanosleep syscall`.
Generalize the `perf_record_with_retry` helper in
`tests/shell/lib/perf_record.sh` to support a custom record command prefix
via the `PERF_RECORD_CMD` environment variable (defaulting to "perf
record").
Update `trace_record_replay.sh` to use this robust retry loop running with
`PERF_RECORD_CMD="perf trace record"` and a base workload of `sleep`. The
test will automatically retry with scaled sleep durations (from 0.01s up
to 2.0s) until the required `nanosleep` event is successfully captured.
Fixes: 15bcfb96d0dd ("perf test: Add trace record and replay test")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
---
tools/perf/tests/shell/lib/perf_record.sh | 7 ++++++-
tools/perf/tests/shell/trace_record_replay.sh | 18 ++++++++++++++----
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/tools/perf/tests/shell/lib/perf_record.sh b/tools/perf/tests/shell/lib/perf_record.sh
index e137fa75370d..2b9e11b66dc7 100644
--- a/tools/perf/tests/shell/lib/perf_record.sh
+++ b/tools/perf/tests/shell/lib/perf_record.sh
@@ -24,9 +24,14 @@ perf_record_with_retry() {
local duration
local first_run=true
local ret=1
+ local cmd_prefix="perf record"
+ if [ -n "${PERF_RECORD_CMD}" ]; then
+ cmd_prefix="${PERF_RECORD_CMD}"
+ fi
+
for duration in 0.01 0.1 0.3 1.0 2.0; do
rm -f "${perfdata}".old
- perf record "$@" -o "${perfdata}" ${testprog_base} ${duration} > "$logfile" 2>&1
+ ${cmd_prefix} "$@" -o "${perfdata}" ${testprog_base} ${duration} > "$logfile" 2>&1
local record_exit=$?
if [ "$first_run" = true ] && [ $record_exit -ne 0 ]; then
diff --git a/tools/perf/tests/shell/trace_record_replay.sh b/tools/perf/tests/shell/trace_record_replay.sh
index 88d30a03dcec..f27e32b18697 100755
--- a/tools/perf/tests/shell/trace_record_replay.sh
+++ b/tools/perf/tests/shell/trace_record_replay.sh
@@ -6,16 +6,26 @@
# shellcheck source=lib/probe.sh
. "$(dirname $0)"/lib/probe.sh
+# shellcheck source=lib/perf_record.sh
+. "$(dirname $0)"/lib/perf_record.sh
skip_if_no_perf_trace || exit 2
[ "$(id -u)" = 0 ] || exit 2
file=$(mktemp /tmp/temporary_file.XXXXX)
-perf trace record -o ${file} sleep 1 || exit 1
-if ! perf trace -i ${file} 2>&1 | grep nanosleep; then
+check_nanosleep() {
+ perf trace -i "${file}" 2>&1 | grep -q nanosleep
+}
+
+PERF_RECORD_CMD="perf trace record" perf_record_with_retry "${file}" "check_nanosleep" "sleep"
+err=$?
+
+perf_record_cleanup
+rm -f ${file}
+
+if [ $err -ne 0 ]; then
echo "Failed: cannot find *nanosleep syscall"
exit 1
fi
-
-rm -f ${file}
+exit 0
--
2.54.0.1189.g8c84645362-goog