From: Ian Rogers <irogers@google.com>
To: irogers@google.com, acme@kernel.org, namhyung@kernel.org
Cc: adrian.hunter@intel.com, james.clark@linaro.org,
jolsa@kernel.org, linux-kernel@vger.kernel.org,
linux-perf-users@vger.kernel.org, mingo@redhat.com,
peterz@infradead.org
Subject: [PATCH v3 4/9] perf test: Deflake Intel PT Python shell tests under load
Date: Mon, 28 Sep 2026 23:58:34 -0700 [thread overview]
Message-ID: <20260929065839.407062-5-irogers@google.com> (raw)
In-Reply-To: <20260929065839.407062-1-irogers@google.com>
In test_intel_pt_events_python.sh, test_export_to_sqlite_python.sh, and
test_export_to_postgresql_python.sh, 'sh -c "uname; true"' uses the
shell builtin 'true' and exits within microseconds of 'uname', sending
SIGCHLD to 'perf record' before the Intel PT AUX buffer is always
flushed under heavy parallel load (~5-10% drop rate).
Sleep 0.05s in the subshell after 'uname' ('sh -c "uname; sleep 0.05"')
so 'uname' completely exits and flushes its AUX trace before 'sh' exits,
and wrap the record and verification step in a bounded retry loop (up to
5 attempts). Also pass '-B -N --no-bpf-event' to 'perf record -g' in
test_export_to_sqlite_python.sh and test_export_to_postgresql_python.sh
to avoid build-id cache and BPF synthesis overhead.
Fixes: d4ce72e9e238 ("perf python: Port intel-pt-events and libxed to perf module")
Fixes: 62d350135e67 ("perf python: Port export-to-sqlite to perf module")
Fixes: b1f968c9656a ("perf python: Port export-to-postgresql to perf module")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
.../shell/test_export_to_postgresql_python.sh | 49 ++++++++++--------
.../shell/test_export_to_sqlite_python.sh | 50 +++++++++++--------
.../shell/test_intel_pt_events_python.sh | 43 +++++++++-------
3 files changed, 79 insertions(+), 63 deletions(-)
diff --git a/tools/perf/tests/shell/test_export_to_postgresql_python.sh b/tools/perf/tests/shell/test_export_to_postgresql_python.sh
index 350813466700..835f48f002e9 100755
--- a/tools/perf/tests/shell/test_export_to_postgresql_python.sh
+++ b/tools/perf/tests/shell/test_export_to_postgresql_python.sh
@@ -61,9 +61,10 @@ test_file_mode() {
fi
# Generate events with callchains and context switches
- if ! perf record -g --switch-events -o "${temp_data}" \
+ if ! perf record -B -N --no-bpf-event -g --switch-events -o "${temp_data}" \
-- perf test -w noploop >/dev/null 2>&1 && \
- ! perf record -g -o "${temp_data}" -- perf test -w noploop >/dev/null 2>&1; then
+ ! perf record -B -N --no-bpf-event -g -o "${temp_data}" \
+ -- perf test -w noploop >/dev/null 2>&1; then
echo "Skipping test, perf record failed"
exit 2
fi
@@ -92,29 +93,33 @@ test_file_mode() {
test_intel_pt() {
echo "Testing export-to-postgresql.py with intel_pt..."
- psql -c "DROP DATABASE IF EXISTS ${temp_db}" postgres >/dev/null 2>&1 || true
- rm -f "${temp_data}"
- # Generate some intel_pt events; use a subshell that waits for uname
- if ! perf record -B -N --no-bpf-event -e intel_pt//u -o "${temp_data}" \
- -- sh -c "uname; true" >/dev/null 2>&1; then
- echo "Skipping intel_pt test, intel_pt not available."
- return 0
- fi
+ # Generate some intel_pt events; sleep briefly after uname in the subshell
+ # so uname's AUX buffer is flushed before SIGCHLD stops perf record.
+ passed=0
+ for _ in 1 2 3 4 5; do
+ psql -c "DROP DATABASE IF EXISTS ${temp_db}" postgres >/dev/null 2>&1 || true
+ rm -f "${temp_data}"
+ if ! perf record -B -N --no-bpf-event -e intel_pt//u -o "${temp_data}" \
+ -- sh -c "uname; sleep 0.05" >/dev/null 2>&1; then
+ echo "Skipping intel_pt test, intel_pt not available."
+ return 0
+ fi
- # Run the script with --itrace cr to synthesize call_returns
- if ! perf script export-to-postgresql -i "${temp_data}" \
- -o "${temp_db}" --itrace cr >/dev/null; then
- echo "intel_pt file mode test failed."
- err=1
- else
- # Check DB for calls
- if ! psql -d "${temp_db}" -t -c 'SELECT COUNT(*) FROM calls WHERE id > 0;' | \
+ # Run the script with --itrace cr to synthesize call_returns
+ if perf script export-to-postgresql -i "${temp_data}" \
+ -o "${temp_db}" --itrace cr >/dev/null && \
+ psql -d "${temp_db}" -t -c 'SELECT COUNT(*) FROM calls WHERE id > 0;' | \
grep -q '[1-9]'; then
- echo "PostgreSQL intel_pt validation failed (no calls found)."
- err=1
- else
- echo "intel_pt test passed (cr validated)."
+ passed=1
+ break
fi
+ done
+
+ if [ "$passed" -eq 0 ]; then
+ echo "PostgreSQL intel_pt validation failed (no calls found)."
+ err=1
+ else
+ echo "intel_pt test passed (cr validated)."
fi
}
diff --git a/tools/perf/tests/shell/test_export_to_sqlite_python.sh b/tools/perf/tests/shell/test_export_to_sqlite_python.sh
index d3c5e22a0754..19ca7c539cf7 100755
--- a/tools/perf/tests/shell/test_export_to_sqlite_python.sh
+++ b/tools/perf/tests/shell/test_export_to_sqlite_python.sh
@@ -47,9 +47,10 @@ test_file_mode() {
echo "Testing export-to-sqlite.py..."
# Generate events with callchains and context switches if supported
- if ! perf record -g --switch-events -o "${temp_data}" \
+ if ! perf record -B -N --no-bpf-event -g --switch-events -o "${temp_data}" \
-- perf test -w noploop >/dev/null 2>&1 && \
- ! perf record -g -o "${temp_data}" -- perf test -w noploop >/dev/null 2>&1; then
+ ! perf record -B -N --no-bpf-event -g -o "${temp_data}" \
+ -- perf test -w noploop >/dev/null 2>&1; then
echo "Skipping test, perf record failed"
exit 2
fi
@@ -77,29 +78,34 @@ test_file_mode() {
test_intel_pt() {
echo "Testing export-to-sqlite.py with intel_pt..."
- rm -f "${temp_db}" "${temp_data}"
- # Generate some intel_pt events; use a subshell that waits for uname
- if ! perf record -B -N --no-bpf-event -e intel_pt//u -o "${temp_data}" \
- -- sh -c "uname; true" >/dev/null 2>&1; then
- echo "Skipping intel_pt test, intel_pt not available."
- return 0
- fi
+ query="import sqlite3; c = sqlite3.connect('${temp_db}'); "
+ query="${query}r = c.execute('SELECT COUNT(*) FROM calls').fetchone()[0]; "
+ query="${query}exit(1 if r == 0 else 0)"
+
+ # Generate some intel_pt events; sleep briefly after uname in the subshell
+ # so uname's AUX buffer is flushed before SIGCHLD stops perf record.
+ passed=0
+ for _ in 1 2 3 4 5; do
+ rm -f "${temp_db}" "${temp_data}"
+ if ! perf record -B -N --no-bpf-event -e intel_pt//u -o "${temp_data}" \
+ -- sh -c "uname; sleep 0.05" >/dev/null 2>&1; then
+ echo "Skipping intel_pt test, intel_pt not available."
+ return 0
+ fi
- # Run the script with --itrace cr to synthesize call_returns
- if ! perf script export-to-sqlite -i "${temp_data}" -o "${temp_db}" --itrace cr; then
- echo "intel_pt file mode test failed."
+ # Run the script with --itrace cr to synthesize call_returns
+ if perf script export-to-sqlite -i "${temp_data}" -o "${temp_db}" --itrace cr && \
+ "$PYTHON" -c "$query" >/dev/null 2>&1; then
+ passed=1
+ break
+ fi
+ done
+
+ if [ "$passed" -eq 0 ]; then
+ echo "SQLite intel_pt validation failed (no calls found)."
err=1
else
- # Check DB for calls
- query="import sqlite3; c = sqlite3.connect('${temp_db}'); "
- query="${query}r = c.execute('SELECT COUNT(*) FROM calls').fetchone()[0]; "
- query="${query}exit(1 if r == 0 else 0)"
- if ! "$PYTHON" -c "$query" >/dev/null 2>&1; then
- echo "SQLite intel_pt validation failed (no calls found)."
- err=1
- else
- echo "intel_pt test passed (cr validated)."
- fi
+ echo "intel_pt test passed (cr validated)."
fi
}
diff --git a/tools/perf/tests/shell/test_intel_pt_events_python.sh b/tools/perf/tests/shell/test_intel_pt_events_python.sh
index b5c3173fa2db..9754b9125da1 100755
--- a/tools/perf/tests/shell/test_intel_pt_events_python.sh
+++ b/tools/perf/tests/shell/test_intel_pt_events_python.sh
@@ -30,7 +30,8 @@ cleanup() {
[ -n "${temp_dir}" ] && rm -rf "${temp_dir}"
}
-trap 'cleanup' EXIT TERM INT
+trap 'cleanup' EXIT
+trap 'cleanup; exit 1' TERM INT
temp_dir=$(mktemp -d /tmp/perf.ipt.XXXXXX)
temp_data="${temp_dir}/perf.data"
@@ -39,27 +40,31 @@ temp_out="${temp_dir}/perf.out"
test_intel_pt() {
echo "Testing intel-pt-events.py with intel_pt..."
- rm -f "${temp_data}" "${temp_out}"
- # Generate some intel_pt events; use a subshell that waits for uname so
- # uname's AUX buffer is flushed before the parent workload exits.
- if ! perf record -B -N --no-bpf-event -e intel_pt//u -o "${temp_data}" \
- -- sh -c "uname; true" >/dev/null 2>&1; then
- echo "Skipping intel_pt test, intel_pt not available."
- exit 2
- fi
+ # Generate some intel_pt events; sleep briefly after uname in the subshell
+ # so uname's AUX buffer is flushed before SIGCHLD stops perf record.
+ passed=0
+ for _ in 1 2 3 4 5; do
+ rm -f "${temp_data}" "${temp_out}"
+ if ! perf record -B -N --no-bpf-event -e intel_pt//u -o "${temp_data}" \
+ -- sh -c "uname; sleep 0.05" >/dev/null 2>&1; then
+ echo "Skipping intel_pt test, intel_pt not available."
+ exit 2
+ fi
- # Run the script and check output
- if ! perf script intel-pt-events -i "${temp_data}" > "${temp_out}"; then
- echo "intel-pt-events.py test failed."
+ # Run the script and check output
+ if perf script intel-pt-events -i "${temp_data}" > "${temp_out}" && \
+ grep -q "Intel PT Branch Trace" "${temp_out}" && \
+ grep -q "uname" "${temp_out}"; then
+ passed=1
+ break
+ fi
+ done
+
+ if [ "$passed" -eq 0 ]; then
+ echo "Failed to find expected output: $(cat "${temp_out}" 2>/dev/null)"
err=1
else
- if ! grep -q "Intel PT Branch Trace" "${temp_out}" || \
- ! grep -q "uname" "${temp_out}"; then
- echo "Failed to find expected output: $(cat "${temp_out}")"
- err=1
- else
- echo "intel-pt-events test passed."
- fi
+ echo "intel-pt-events test passed."
fi
rm -f "${temp_out}"
}
--
2.56.0.rc1.315.gc6ed9934b7-goog
next prev parent reply other threads:[~2026-09-29 6:58 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-29 2:19 [PATCH v1 0/9] perf python: Follow-up fixes and shell test deflaking Ian Rogers
2026-09-29 2:19 ` [PATCH v1 1/9] perf evsel: Clamp sample_id size for ksymbol, bpf, and text_poke events Ian Rogers
2026-09-29 2:19 ` [PATCH v1 2/9] perf python sctop: Fix offline interval printing and test flakiness Ian Rogers
2026-09-29 2:19 ` [PATCH v1 3/9] perf python stat-cpi: Fix live mode signal races " Ian Rogers
2026-09-29 2:19 ` [PATCH v1 4/9] perf test: Deflake Intel PT Python shell tests under load Ian Rogers
2026-09-29 2:19 ` [PATCH v1 5/9] perf test: Deflake failed-syscalls " Ian Rogers
2026-09-29 2:19 ` [PATCH v1 6/9] perf test: Reduce overhead and contention in Python shell tests Ian Rogers
2026-09-29 2:19 ` [PATCH v1 7/9] perf python event_analyzing_sample: Default to in-memory SQLite database Ian Rogers
2026-09-29 2:19 ` [PATCH v1 8/9] perf python: Initialize debug output on module load Ian Rogers
2026-09-29 2:19 ` [PATCH v1 9/9] perf pmu: Fix race with concurrent tracepoint creation and removal in perf list Ian Rogers
2026-09-29 6:29 ` [PATCH v2 0/9] perf python: Follow-up fixes and shell test deflaking Ian Rogers
2026-09-29 6:29 ` [PATCH v2 1/9] perf evsel: Clamp sample_id size for ksymbol, bpf, and text_poke events Ian Rogers
2026-09-29 6:29 ` [PATCH v2 2/9] perf python sctop: Fix offline interval printing and test flakiness Ian Rogers
2026-09-29 6:29 ` [PATCH v2 3/9] perf python stat-cpi: Fix live mode signal races " Ian Rogers
2026-09-29 6:29 ` [PATCH v2 4/9] perf test: Deflake Intel PT Python shell tests under load Ian Rogers
2026-09-29 6:29 ` [PATCH v2 5/9] perf test: Deflake failed-syscalls " Ian Rogers
2026-09-29 6:29 ` [PATCH v2 6/9] perf test: Reduce overhead and contention in Python shell tests Ian Rogers
2026-09-29 6:29 ` [PATCH v2 7/9] perf python event_analyzing_sample: Default to in-memory SQLite database Ian Rogers
2026-09-29 6:29 ` [PATCH v2 8/9] perf python: Initialize debug output on module load Ian Rogers
2026-09-29 6:29 ` [PATCH v2 9/9] perf pmu: Fix race with concurrent tracepoint creation and removal in perf list Ian Rogers
2026-09-29 6:58 ` [PATCH v3 0/9] perf python: Follow-up fixes and shell test deflaking Ian Rogers
2026-09-29 6:58 ` [PATCH v3 1/9] perf evsel: Clamp sample_id size for ksymbol, bpf, and text_poke events Ian Rogers
2026-09-29 6:58 ` [PATCH v3 2/9] perf python sctop: Fix offline interval printing and test flakiness Ian Rogers
2026-09-29 6:58 ` [PATCH v3 3/9] perf python stat-cpi: Fix live mode signal races " Ian Rogers
2026-09-29 6:58 ` Ian Rogers [this message]
2026-09-29 6:58 ` [PATCH v3 5/9] perf test: Deflake failed-syscalls Python shell tests under load Ian Rogers
2026-09-29 6:58 ` [PATCH v3 6/9] perf test: Reduce overhead and contention in Python shell tests Ian Rogers
2026-09-29 6:58 ` [PATCH v3 7/9] perf python event_analyzing_sample: Default to in-memory SQLite database Ian Rogers
2026-09-29 6:58 ` [PATCH v3 8/9] perf python: Initialize debug output on module load Ian Rogers
2026-09-29 6:58 ` [PATCH v3 9/9] perf pmu: Fix race with concurrent tracepoint creation and removal in perf list Ian Rogers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260929065839.407062-5-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®