From 509a2b9a6e142697dd5f34cdd802e5b86eababa1 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 22 Jun 2026 18:27:52 -0700 Subject: [PATCH] perf tests: Fix flakiness in trace record and replay test 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 Signed-off-by: Namhyung Kim --- tools/perf/tests/shell/lib/perf_record.sh | 7 +++- tools/perf/tests/shell/trace_record_replay.sh | 38 +++++++++++++++++-- 2 files changed, 40 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..38fcafcdfb91 100755 --- a/tools/perf/tests/shell/trace_record_replay.sh +++ b/tools/perf/tests/shell/trace_record_replay.sh @@ -6,16 +6,46 @@ # 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) +err=0 -perf trace record -o ${file} sleep 1 || exit 1 -if ! perf trace -i ${file} 2>&1 | grep nanosleep; then - echo "Failed: cannot find *nanosleep syscall" +cleanup() { + rm -f ${file} + perf_record_cleanup + trap - EXIT INT TERM +} + +trap_cleanup() { + echo "Unexpected signal in ${FUNCNAME[1]}" + cleanup + exit 1 +} +trap trap_cleanup EXIT INT TERM + +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=$? + +if [ $err -ne 0 ]; then + if [ $err -eq 2 ]; then + logfile="${PERF_RECORD_LOGS[${#PERF_RECORD_LOGS[@]}-1]}" + echo "perf trace record failed. Log output:" + cat "$logfile" + else + echo "Failed: cannot find *nanosleep syscall" + fi + cleanup exit 1 fi -rm -f ${file} +cleanup +exit 0