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: 15bcfb96d0 ("perf test: Add trace record and replay test")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
Ian Rogers 2026-06-22 18:27:52 -07:00 committed by Namhyung Kim
parent 07eac17339
commit 509a2b9a6e
2 changed files with 40 additions and 5 deletions

View File

@ -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

View File

@ -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