[PATCH v4 41/49] perf test: Migrate Intel PT virtual LBR test to Python API
From: Ian Rogers
Date: Sat Sep 26 2026 - 02:28:11 EST
Migrate the Intel PT virtual LBR test from generating an inline legacy
perf script callback to using a standalone Python script
(perf_brstack_max.py) with the brstack iterator API in the perf Python
module.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
---
.../perf/tests/shell/lib/perf_brstack_max.py | 40 +++++++++++++++++
tools/perf/tests/shell/test_intel_pt.sh | 43 ++++++++-----------
2 files changed, 58 insertions(+), 25 deletions(-)
create mode 100644 tools/perf/tests/shell/lib/perf_brstack_max.py
diff --git a/tools/perf/tests/shell/lib/perf_brstack_max.py b/tools/perf/tests/shell/lib/perf_brstack_max.py
new file mode 100644
index 000000000000..cc065f07cfed
--- /dev/null
+++ b/tools/perf/tests/shell/lib/perf_brstack_max.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+# SPDX-License-Identifier: GPL-2.0
+# Determine the maximum size of branch stacks in a perf.data file.
+
+import argparse
+import sys
+
+import perf
+
+def main():
+ ap = argparse.ArgumentParser()
+ ap.add_argument("-i", "--input", default="perf.data", help="Input file name")
+ args = ap.parse_args()
+
+ bmax = 0
+
+ def process_event(sample):
+ nonlocal bmax
+ try:
+ brstack = sample.brstack
+ if brstack:
+ n = len(list(brstack))
+ if n > bmax:
+ bmax = n
+ except AttributeError:
+ pass
+
+ session = None
+ try:
+ session = perf.session(perf.data(args.input), sample=process_event)
+ session.process_events()
+ print("max brstack", bmax)
+ except Exception as e:
+ print(f"Error processing events: {e}", file=sys.stderr)
+ sys.exit(1)
+ finally:
+ session = None
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh
index a2e87ef09593..c0ecece0a825 100755
--- a/tools/perf/tests/shell/test_intel_pt.sh
+++ b/tools/perf/tests/shell/test_intel_pt.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Miscellaneous Intel PT testing (exclusive)
# SPDX-License-Identifier: GPL-2.0
+# Miscellaneous Intel PT testing (exclusive)
set -e
@@ -21,7 +21,6 @@ perfdatafile="${temp_dir}/test-perf.data"
outfile="${temp_dir}/test-out.txt"
errfile="${temp_dir}/test-err.txt"
awkscript="${temp_dir}/awkscript"
-maxbrstack="${temp_dir}/maxbrstack.py"
cleanup()
{
@@ -375,34 +374,28 @@ test_kernel_trace()
test_virtual_lbr()
{
echo "--- Test virtual LBR ---"
- # Check if python script is supported
- libpython=$(perf version --build-options | grep python | grep -cv OFF)
- if [ "${libpython}" != "1" ] ; then
- echo "SKIP: python scripting is not supported"
+ # Run setup_python.sh in a subshell first so its 'exit 2' when Python is
+ # not detected skips only this subtest rather than exiting test_intel_pt.sh
+ # (which would trigger trap_cleanup and fail the suite).
+ # shellcheck source=lib/setup_python.sh
+ if ! ( . "${shelldir}"/lib/setup_python.sh ) ; then
return 2
fi
+ # shellcheck source=lib/setup_python.sh
+ . "${shelldir}"/lib/setup_python.sh
- # Python script to determine the maximum size of branch stacks
- cat << "_end_of_file_" > "${maxbrstack}"
-from __future__ import print_function
-
-bmax = 0
-
-def process_event(param_dict):
- if "brstack" in param_dict:
- brstack = param_dict["brstack"]
- n = len(brstack)
- global bmax
- if n > bmax:
- bmax = n
-
-def trace_end():
- print("max brstack", bmax)
-_end_of_file_
+ if ! "$PYTHON" -c 'import perf' > /dev/null 2>&1; then
+ echo "SKIP: Python perf module not found"
+ return 2
+ fi
# Check if virtual lbr is working
- perf_record_no_bpf -o "${perfdatafile}" --aux-sample -e '{intel_pt//,cycles}:u' uname
- times_val=$(perf script -i "${perfdatafile}" --itrace=L -s "${maxbrstack}" 2>/dev/null | grep "max brstack " | cut -d " " -f 3)
+ perf_record_no_bpf -o "${tmpfile}" --aux-sample \
+ -e '{intel_pt//,cycles}:u' perf test -w brstack || return 1
+ perf inject --itrace=L -i "${tmpfile}" -o "${perfdatafile}" || return 1
+ output=$("$PYTHON" "${shelldir}/lib/perf_brstack_max.py" -i "${perfdatafile}") || return 1
+ echo "Debug: perf_brstack_max.py output: $output"
+ times_val=$(echo "$output" | grep "max brstack " | cut -d " " -f 3)
case "${times_val}" in
[0-9]*) ;;
*) times_val=0;;
--
2.56.0.rc1.315.gc6ed9934b7-goog