| Age | Commit message (Collapse) | Author |
|
Add ttimechart.py, a textual based interactive timechart, and a --tui
option to perf timechart that launches it through perf script. Rather
than writing an SVG file, per-CPU (busy, frequency and idle state),
per-task (running, runnable and blocked) and I/O timelines are shown in
the terminal along with a summary table. The timelines can be zoomed,
panned and the state of the selected row at the cursor is described,
including the task that woke it. The -i, -P, -T and -p options are
passed to the script.
The data is loaded in a background thread and the timelines are shown
and updated as it loads. A --dump option prints a text summary without
the UI.
Committer testing:
Fist record a short session with:
root@x2:/home/acme/git/perf-tools-next# perf timechart record
^C[ perf record: Woken up 9 times to write data ]
[ perf record: Captured and wrote 4.489 MB perf.data (29719 samples) ]
root@x2:/home/acme/git/perf-tools-next#
Then try the TUI with:
root@x2:/home/acme/git/perf-tools-next# tools/perf/python/ttimechart.py
or:
root@x2:/home/acme/git/perf-tools-next# perf timechart --tui
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Alice Rogers <alice.mei.rogers@gmail.com>
Co-developed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Reading a large perf.data file caused a long stall before the treport
app started. Start the app immediately and build the profile in a
background thread, showing the report tree and flame graph as they are
built with the progress in the header. The time between updates grows
with the load time as updating the views costs more as the profile
grows. A lock guards the profile shared between the threads. Quitting
while loading cancels the load.
Tree nodes are now created lazily as they are expanded, expanded nodes
and the cursor are kept across updates, and events are kept in the order
they are first seen as their values aren't comparable. Node names are
escaped so they aren't interpreted as markup.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Alice Rogers <alice.mei.rogers@gmail.com>
Co-developed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
During the perf build, pylint reports:
************* Module export-to-postgresql
python/export-to-postgresql.py:319:8: W0621: Redefining name 'e' from outer scope (line 100) (redefined-outer-name)
Rename 'e' to 'db_error' to clear the warning.
Fixes: b1f968c9656a8a87 ("perf python: Port export-to-postgresql to perf module")
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: Codex:gpt-6
Signed-off-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
When -d/--db is not specified, event_analyzing_sample.py created a
temporary file in /tmp via tempfile.mkstemp() and deleted it in
trace_end(). As noted during review, creating the database in a shared
/tmp directory does not reserve SQLite's auxiliary sidecar filenames
(-journal or -wal), and a temporary on-disk file is unnecessary when the
caller did not ask to persist the database.
Default to sqlite3.connect(":memory:") when db_path is not provided,
removing the temporary file creation and cleanup logic, and test both
the default in-memory mode and explicit -d file mode in
test_event_analyzing_sample_python.sh.
Fixes: eeb70645a8097437 ("perf python: Port event_analyzing_sample to perf module")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
In test_stat_cpi_python.sh, 'perf test -w noploop &' defaults to a
1-second duration and can exit under heavy parallel load before
'perf stat -p' and 'perf script stat-cpi' finish starting up. In
addition, the fixed 'sleep 0.5' before sending SIGINT can fire before
Python finishes importing the perf module, opening the live evlist, and
flushing the first interval.
In stat-cpi.py, register SIGINT and SIGTERM handlers before calling
_open_live_evlist() and pass flush=True when printing live output so
redirected stdout is flushed immediately after each interval.
In test_stat_cpi_python.sh, run 'perf test -w noploop 60 &' so the
target workload stays alive until killed, and poll the output file for
'cpi' (up to 5 seconds) before sending SIGINT.
Fixes: 4425182d426b ("perf python: Port stat-cpi to perf module")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
In sctop.py:
- If an earlier interval elapsed and printed an empty table before the
target comm ('sleep') executed any syscalls, analyzer.printed became
True and the final partial interval containing the target comm's
syscalls was never flushed at EOF. Flush print_current_totals() in
finally when analyzer.syscalls is non-empty as well as when nothing
has been printed yet.
- Initialize analyzer.e_machine after creating perf.session rather than
when session is still None.
In test_sctop_python.sh:
- Use a private temporary directory via 'mktemp -d'.
- Drop '-a' and pass '-B -N --no-bpf-event' to 'perf record', and sleep
briefly in the subshell ('sh -c "sleep 0.1; sleep 0.05"') with a
bounded retry loop so 'sleep's PERF_RECORD_COMM and sys_enter events
are reliably captured under heavy load.
Fixes: b83f0bacf5e4f936 ("perf python: Port sctop to perf module")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
The perf sample dso_bid getter returns a string or None, matching its
Optional[str] annotation. Attempting to decode it as bytes causes mypy
to report union-attr errors, even though this was behind a conditional
that checked for bytes type.
Use the string directly, retaining the fallback for an unknown build ID.
This fixes the following build error:
python/arm-cs-trace-disasm.py:266: error: Item "None" of "str | None" has no attribute "decode" [union-attr]
Fixes: 279b402e5143214c ("perf python: Port arm-cs-trace-disasm to perf module")
Reviewed-by: Leo Yan <leo.yan@arm.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: Codex:GPT-6-Astra
Signed-off-by: James Clark <james.clark@linaro.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Move parallel-perf.py from tools/perf/scripts/python/ to
tools/perf/python/ as it is a standalone Python utility that invokes
'perf script' in parallel across time slices and CPUs. Update
tools/perf/tests/shell/script.sh accordingly.
Also fix bugs and clean up the script to pass mypy and pylint without
suppression comments:
- Fix Work.command() to return the shlex.quote()-escaped command string
(previously sh_cmd was computed with shlex.quote() and discarded in
favor of unquoted self.cmd).
- Close self.popen.stdout in the parent process after spawning the
consumer subprocess in Work.start() when --pipe-to is used, ensuring
the producer receives SIGPIPE if the consumer exits early and avoiding
leaking the pipe file descriptor.
- Convert method and function names to snake_case, specify utf-8 file
encodings, and add type annotations and docstrings.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Move exported-sql-viewer.py from tools/perf/scripts/python/ to
tools/perf/python/ as it is a standalone PySide/PyQt GUI application
for viewing SQLite and PostgreSQL databases exported by perf script.
Improvements and cleanups compared to the legacy script:
- Add support for PySide6 (falling back to PySide2 and PySide) loaded
dynamically via importlib, and provide stub base classes (_QtBase,
_QtWidget) so static analysis (mypy and pylint) and --help-only
execution succeed when Qt bindings are not installed.
- Fix a Python 3 NameError crash in HBoxLayout where expanded_mark and
not_expanded_mark called Python 2's removed unicode() builtin instead
of chr(0x25BC) and chr(0x25B6).
- Replace instance-level method monkey-patching
(self.mousePressEvent = self.MousePressEvent) on SwitchGraphView with
proper class methods gated by self.rb_enabled so Qt virtual method
dispatch works cleanly across PySide2 and PySide6.
- Remove Python 2 constructs (cPickle, xrange), wildcard imports, bare
'except:' clauses, and variable names shadowing Python builtins.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port export-to-postgresql.py to a standalone script in
tools/perf/python/ using the perf module and libpq via ctypes.
Improvements compared to the legacy script:
- Remove the dependency on PySide/QtSql for database creation and DDL
execution by driving libpq directly via ctypes (PQconnectdb, PQexec,
PQputCopyData, PQputCopyEnd) and streaming binary PostgreSQL COPY
files in PostgresExporter, enabling export on headless servers without
Qt installed.
- Harden database connection and SQL identifier handling by rejecting
URI ('://') and connection-parameter ('=') injection strings in
setup_db() and connect(), escaping single quotes and backslashes in
connection strings, and quoting SQL identifiers (quote_ident).
- Support Intel PT and instruction trace export via
perf.session(itrace=...) and perf.call_return callbacks, reconstructing
relational call_paths and calls tables (including id=0 placeholder
rows and callfk/returnfk foreign keys) and unpacking synthesized PT
payloads (ptwrite, cbr, mwait, pwre, exstop, pwrx).
- Use a dedicated context_switch ID counter so context-switch exports
do not advance sample database IDs out of sync with call_return
references.
Update Documentation/db-export.txt and add a shell test
(test_export_to_postgresql_python.sh) to verify the standalone exporter.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port export-to-sqlite.py to a standalone script in tools/perf/python/
using the perf module and Python's standard library sqlite3 module.
Improvements compared to the legacy script:
- Remove the dependency on PySide/QtSql by using Python's built-in
sqlite3 module in DatabaseExporter, allowing SQLite export on headless
and minimal systems without Qt installed.
- Support Intel PT and hardware instruction trace export via
perf.session(itrace=...) and perf.call_return callbacks, reconstructing
relational call_paths and calls tables and decoding synthesized PT
payloads (ptwrite, cbr, mwait, pwre, exstop, pwrx).
- Export context_switches via perf.session's context_switch callback
and map thread and comm IDs to their relational database keys.
- Manage temporary staging files inside an isolated tempfile.mkdtemp()
directory with guaranteed cleanup in a finally block.
Update Documentation/db-export.txt and add a shell test
(test_export_to_sqlite_python.sh) to verify the standalone exporter.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port intel-pt-events.py and libxed.py from tools/perf/scripts/python/
to standalone modules in tools/perf/python/:
- Refactor intel-pt-events.py into an IntelPTAnalyzer class with full
type annotations to encapsulate trace state and stashed output.
- Configure instruction trace decoding directly via perf.session's
itrace option and context_switch callback.
- Dynamically select 32-bit vs 64-bit disassembly mode in libxed.py
using session.is_64_bit and annotate instructions with source lines
via sample.srccode().
- Rename methods in libxed.py to snake_case (instruction, set_mode,
disassemble_one) and remove Python 2 compatibility code.
Add a shell test (test_intel_pt_events_python.sh) to verify the
standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port powerpc-hcalls.py from tools/perf/scripts/python/ to a standalone
script in tools/perf/python/:
- Refactor the script into an HCallAnalyzer class with full type
annotations to encapsulate per-CPU hypervisor call entry/exit state.
- Use perf.session for event processing to track hypervisor call entry
and exit timestamps and aggregate min/max/average duration statistics
against HCALL_TABLE.
- Add argparse CLI support (-i/--input) and remove Python 2
compatibility code.
Add a shell test (test_powerpc_hcalls_python.sh) to verify the
standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port arm-cs-trace-disasm.py to a standalone script in tools/perf/python/
using the perf module directly.
Improvements compared to the legacy script:
- Encapsulate trace disassembly state in a TraceDisasm class.
- Default to itrace="b" when creating perf.session() (overridable via
--itrace or PERF_ITRACE) so all CoreSight branch samples are
synthesized without requiring --itrace=b on the command line.
- Automatically search standard kernel debug paths (find_vmlinux())
when -k/--vmlinux is not specified, and query
perf.config_get("annotate.objdump") for the default objdump binary.
- Bound DISASM_CACHE memory consumption by evicting the cache at 1024
entries and skipping caching of oversized (> 512 lines) objdump
outputs.
- Use sample.srccode() from the perf extension module to annotate
disassembly output with source filenames, line numbers, and source
lines.
Update the ARM CoreSight disassembly shell test
(test_arm_coresight_disasm.sh) to invoke the standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port check-perf-trace.py to a standalone script in tools/perf/python/
using the perf module directly.
Improvements compared to the legacy script:
- Access tracepoint fields directly as attributes on perf.sample_event
instead of per-event dictionaries and legacy Perf-Trace-Util helpers.
- Decode symbolic flag and enum masks for irq:softirq_entry and
kmem:kmalloc directly in Python and add -i/--input CLI support via
argparse.
- Add full type annotations and clean up Python 2 idioms.
Add a shell test (test_check_perf_trace_python.sh) to verify the
standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port netdev-times.py from tools/perf/scripts/python/ to a standalone
script in tools/perf/python/:
- Refactor the script into a NetDevTimesAnalyzer class with full type
annotations to encapsulate state.
- Collect events via perf.session and sort them in timestamp order
before analysis so multi-CPU TX and RX packet timelines are
reconstructed deterministically.
- Replace custom argument parsing with argparse (-i/--input, --tx,
--rx, --dev, --debug), extract tracepoint fields directly from sample
attributes, and remove Python 2 compatibility artifacts.
Add a shell test (test_netdev_times_python.sh) to verify the standalone
script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port net_dropmonitor.py from tools/perf/scripts/python/ to a standalone
script in tools/perf/python/:
- Refactor the script into a DropMonitor class with full type
annotations to encapsulate state.
- Use perf.session for skb:kfree_skb event processing and add argparse
CLI support (-i/--input and -k/--kallsyms).
- Resolve kernel drop addresses via perf.session symbols/callchains and
binary search over /proc/kallsyms, ignoring zeroed kptr_restrict
addresses with graceful fallback when kallsyms is unavailable.
- Remove Python 2 compatibility code.
Add a shell test (test_net_dropmonitor_python.sh) to verify the
standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port compaction-times.py to a standalone script in tools/perf/python/
using the perf module directly to analyze mm_compaction tracepoints.
Improvements compared to the legacy script:
- Replace Python 2 constructs (such as sys.maxint and raw integer
bitmasks) with Python 3 enum.IntEnum (Popt) and enum.IntFlag (Topt)
types.
- Access tracepoint fields directly on perf.sample_event and add
-i/--input CLI option support via argparse.
- Add full type annotations passing mypy and pylint without suppression
comments.
Add a shell test (test_compaction_times_python.sh) to verify the
standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Replace the legacy Perl script wakeup-latency.pl with a standalone
Python script in tools/perf/python/wakeup-latency.py using the perf
Python module.
Improvements compared to the legacy Perl script:
- Remove the dependency on libperl and Perf::Trace::Util.
- Track wakeup timestamps per-task (keyed by the wakee PID on
sched:sched_wakeup and matched against next_pid on sched:sched_switch)
rather than per-CPU, avoiding mixed latencies when multiple wakeups
occur on a CPU before a context switch.
- Guard print_totals() when total_wakeups == 0 (printing 'N/A' instead
of dividing by zero when a trace contains no matched wakeup/switch
pairs).
- Add argparse CLI options (-i/--input) and full type annotations.
Add a shell test
(test_wakeup_latency_python.sh) to verify the standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port sched-migration.py and SchedGui.py from tools/perf/scripts/python/
to standalone modules in tools/perf/python/:
- Refactor sched-migration.py into a SchedMigrationAnalyzer class using
perf.session for event processing and add argparse CLI support
(-i/--input, -v/--verbose, --gui, --no-gui).
- Port SchedGui.py to tools/perf/python/ as a local module dependency.
- Load wxPython dynamically via importlib only when GUI mode (--gui) is
requested so text-mode analysis, testing on headless systems, and
static analysis (mypy/pylint) succeed without wx installed.
- Remove Python 2 compatibility code.
Add a shell test (test_sched_migration_python.sh) to verify the
standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port task-analyzer.py from tools/perf/scripts/python/ to a standalone
script in tools/perf/python/ refactored into a class-based architecture.
Improvements compared to the legacy script:
- Support both offline perf.data file analysis (using perf.session) and
live trace capture (using evlist.read_on_cpu), accessing
sched:sched_switch tracepoint fields directly from sample objects.
- Automatically disable ANSI terminal color escape sequences when --csv
or --csv-summary is enabled so CSV column headers ('Comm,',
'Time Out-Out,', etc.) are never polluted by color codes when running
interactively on a TTY (e.g. as root).
- Sanitize non-printable characters and leading CSV formula characters
(=, +, -, @) in task comm strings.
- Emit a one-time warning to stderr if sched:sched_switch samples are
missing tracepoint fields (such as when recorded without libtraceevent
support).
Update test_task_analyzer.sh to invoke the standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port tools/perf/scripts/python/futex-contention.py to a standalone
script in tools/perf/python/ using the perf module. Avoiding the
embedded interpreter overhead improves execution speed by ~3.2x:
```
$ perf record -e syscalls:sys_*_futex -a sleep 1
...
$ time perf script tools/perf/scripts/python/futex-contention.py
...
real 0m1.007s
user 0m0.935s
sys 0m0.072s
$ time python3 tools/perf/python/futex-contention.py
...
real 0m0.314s
user 0m0.259s
sys 0m0.056s
```
Additional improvements compared to the legacy script:
- Consolidate per-(tid, uaddr) contention count, total_time, min_time,
and max_time into a single LockStats class instead of maintaining
three separate dictionaries.
- Validate that uaddr and op tracepoint attributes are present on
syscalls:sys_enter_futex samples rather than silently attributing
missing fields to uaddr=0, op=0 (FUTEX_WAIT).
- Add -i/--input CLI option support via argparse and full type
annotations.
Add a shell test (test_futex_contention_python.sh) to verify the
standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Replace the legacy Perl script rwtop.pl with a standalone Python script
in tools/perf/python/rwtop.py using the perf Python module.
Improvements compared to the legacy Perl script:
- Remove the dependency on libperl and Perf::Trace::Util.
- Support both offline perf.data files (via perf.session) and live
recording (via LiveSession with --live), driving periodic interval
summaries from event timestamps rather than wall-clock SIGALRM timers
so both live and offline runs produce deterministic output.
- Convert unsigned 32-bit and 64-bit error return values
(0xfffff000..0xffffffff and >= 0x8000000000000000) to negative errnos
so failed read/write syscalls are recorded in the error table rather
than inflating bytes_read / bytes_written.
- Sanitize non-printable characters in /proc/<pid>/comm to prevent
terminal control sequence injection.
Add a shell test
(test_rwtop_python.sh) to verify the standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Replace the legacy Perl script rw-by-pid.pl with a standalone Python
script in tools/perf/python/rw-by-pid.py using the perf Python module.
Improvements compared to the legacy Perl script:
- Remove the dependency on libperl and Perf::Trace::Util.
- Convert unsigned 32-bit and 64-bit error return values
(0xfffff000..0xffffffff and >= 0x8000000000000000) to negative errnos
so failed read/write syscalls are recorded in the error table rather
than inflating bytes_read / bytes_written.
- Add argparse CLI support (-i/--input) and full type annotations.
Add a shell test
(test_rw_by_pid_python.sh) to verify the standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Replace the legacy Perl script rw-by-file.pl with a standalone Python
script in tools/perf/python/rw-by-file.py using the perf Python module.
Improvements compared to the legacy Perl script:
- Remove the dependency on libperl and Perf::Trace::Util.
- Encapsulate per-file-descriptor read/write byte and call count
aggregation in an RwByFile class using perf.session and resolve thread
command names via session.find_thread(pid, sample_tid).
- Add argparse CLI support (-i/--input and target program filter) and
full type annotations.
Add a shell test
(test_rw_by_file_python.sh) to verify the standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port sctop.py from tools/perf/scripts/python/ to a standalone script in
tools/perf/python/ using an SCTopAnalyzer class structure.
Improvements compared to the legacy script:
- Support both offline perf.data analysis (via perf.session, advancing
display intervals deterministically using event timestamps) and live
monitoring (via LiveSession with automatic tracepoint fallback from
raw_syscalls:sys_enter to syscalls:sys_enter_*).
- Resolve architecture-aware syscall names via
perf.syscall_name(id, session.e_machine) without requiring
python-audit.
- Replace unsafe signal.SIGALRM dictionary mutation and os.popen("clear")
subshell spawning with a synchronized threading.Lock / threading.Event
timer and direct ANSI terminal escape sequences ('\x1b[2J\x1b[H').
Add a shell test (test_sctop_python.sh) to verify the standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Replace the legacy Perl script failed-syscalls.pl with a standalone
Python script in tools/perf/python/failed-syscalls.py using the perf
Python module.
Improvements compared to the legacy Perl script:
- Remove the dependency on libperl and Perf::Trace::Util.
- Support both syscalls:sys_exit_* and raw_syscalls:sys_exit events (the
legacy script only handled raw_syscalls::sys_exit).
- Use session.is_64_bit to distinguish 32-bit vs 64-bit unsigned error
return ranges (0xfffff000..0xffffffff vs >= 0xfffffffffffff000) so
valid 64-bit syscalls returning ~4GB values are not misclassified as
32-bit negative errors.
- Add argparse CLI support (-i/--input and optional comm filter) and
full type annotations.
Add a shell test
(test_failed_syscalls_python.sh) to verify the standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port failed-syscalls-by-pid.py to a standalone script in
tools/perf/python/ using the perf module:
- Resolve architecture-aware syscall names using
perf.syscall_name(id, session.e_machine) instead of host python-audit
tables, supporting cross-architecture perf.data files without external
dependencies.
- Translate negative syscall return values into symbolic E* error names
using perf.arch_strerrno(ret, session.e_machine), leveraging the
auto-generated trace beauty architecture errno tables.
- Encapsulate aggregation in a SyscallAnalyzer class using
collections.defaultdict and add argparse filtering by comm, PID, and
-i/--input.
Add a shell test (test_failed_syscalls_by_pid_python.sh) to verify the
standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port tools/perf/scripts/python/syscall-counts-by-pid.py to a standalone
script in tools/perf/python/ using the perf module. Avoiding the
embedded interpreter and per-event dictionary overhead improves
execution speed by ~3.8x:
```
$ perf record -e raw_syscalls:sys_enter -a sleep 1
...
$ time perf script tools/perf/scripts/python/syscall-counts-by-pid.py perf
...
real 0m3.852s
user 0m3.512s
sys 0m0.336s
$ time python3 tools/perf/python/syscall-counts-by-pid.py perf
...
real 0m1.011s
user 0m0.963s
sys 0m0.048s
```
Additional improvements compared to the legacy script:
- Resolve architecture-specific syscall names via
perf.syscall_name(id, session.e_machine) instead of host python-audit
tables.
- Support both raw_syscalls:sys_enter and individual syscalls:sys_enter_*
tracepoints, and filter out invalid (> 0xffff or negative) syscall IDs.
- Support filtering by numeric PID as well as command name (comm), and
resolve process command names via session.find_thread(pid).
Add a shell test (test_syscall_counts_by_pid_python.sh) to verify the
standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port tools/perf/scripts/python/syscall-counts.py to a standalone script
in tools/perf/python/ using the perf module. Avoiding the embedded
interpreter and per-event dictionary allocation overhead improves
execution speed by ~4x:
```
$ perf record -e raw_syscalls:sys_enter -a sleep 1
...
$ time perf script tools/perf/scripts/python/syscall-counts.py perf
...
real 0m3.887s
user 0m3.578s
sys 0m0.308s
$ time python3 tools/perf/python/syscall-counts.py perf
...
real 0m0.953s
user 0m0.905s
sys 0m0.048s
```
Additional improvements compared to the legacy script:
- Resolve syscall names using perf.syscall_name(id, session.e_machine)
instead of host python-audit / Util.py tables, enabling accurate
cross-architecture perf.data analysis without external dependencies.
- Support both raw_syscalls:sys_enter (sample.id) and individual
syscalls:sys_enter_* tracepoints (sample.__syscall_nr / sample.nr),
filtering out invalid/corrupt (> 0xffff or negative) syscall numbers.
- Add argparse CLI options (-i/--input and optional comm filter).
Add a shell test (test_syscall_counts_python.sh) to verify the
standalone script. The legacy script and its bin wrapper are retained
temporarily during the transition to maintain bisectability and are
removed once all scripts are migrated.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port event_analyzing_sample.py to a standalone script in
tools/perf/python/ using the perf module and standard library sqlite3
module.
Improvements compared to the legacy script:
- Encapsulate database state in a _DB container instead of mutating
module-level globals, and ensure temporary SQLite database files are
cleaned up on exit.
- Add argparse CLI options (-i/--input and -d/--db) while preserving
PerfEvent, PebsEvent, and PebsNHM binary raw_buf unpacking and
symbol/DSO histogram reporting.
- Remove Python 2 compatibility code and add type annotations.
Add a shell test (test_event_analyzing_sample_python.sh) to verify the
standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port gecko.py to a standalone script in tools/perf/python/ that uses
the perf module directly to convert perf.data profiles into Firefox
Gecko profile format.
Improvements compared to the legacy script:
- Encapsulate profiler state in GeckoCLI and CategoryData classes with
full type annotations, removing global variables.
- Harden the local HTTP server in _write_and_launch(): write the
temporary profile to an isolated tempfile.TemporaryDirectory() with a
randomized UUID filename instead of the current working directory,
bind HTTPServer exclusively to 127.0.0.1 on an OS-assigned ephemeral
port (0), restrict CORS Access-Control-Allow-Origin to
'https://profiler.firefox.com' instead of '*', and restrict HTTP GET
requests exclusively to the randomized profile filename (returning
HTTP 403 for directory listings and any other path).
- Add -i/--input and -e/--event CLI options via argparse.
Add a shell test (test_gecko_python.sh) to verify the standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port flamegraph.py to a standalone script in tools/perf/python/ that
uses the perf module directly, avoiding intermediate dictionary
allocations for event fields.
Improvements compared to the legacy script:
- Add Subresource Integrity (integrity="sha256-...") and
crossorigin="anonymous" attributes to external CDN stylesheet and
script tags in MINIMAL_HTML.
- Upgrade CDN HTML template hash verification from weak MD5
(hashlib.md5) to cryptographic SHA-256 (hashlib.sha256).
- Escape '<', '>', and '&' ('\u003c', '\u003e', '\u0026') in embedded
JSON payloads (stacks_json and options_json) to prevent HTML script
injection / XSS when rendering untrusted symbol or command names.
- Skip invoking 'perf report --header-only' when the input is stdin
('-'), a FIFO pipe, or a character device (S_ISFIFO / S_ISCHR) so
non-seekable streams do not hang or fail.
Add a shell test (test_flamegraph_python.sh) to verify the standalone
script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port stackcollapse.py from tools/perf/scripts/python/ to a standalone
script in tools/perf/python/ refactored into a StackCollapseAnalyzer
class.
Improvements compared to the legacy script:
- Traverse sample.callchain directly from perf.session without
allocating per-event dictionaries, and fall back to sample.symbol when
a sample has no callchain.
- Replace deprecated optparse with argparse, adding -i/--input alongside
--include-tid, --include-pid, --no-comm, --tidy-java, and --kernel.
- Handle BrokenPipeError cleanly when output is piped into downstream
tools (such as head or flamegraph.pl).
Add a shell test (test_stackcollapse_python.sh) using a CPU workload
(perf test -w noploop) to verify the standalone script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port mem-phys-addr.py to a standalone script in tools/perf/python/
using the perf.session API to read perf.data files and profile physical
memory access types against /proc/iomem.
Improvements compared to the legacy script:
- Parse the full indentation hierarchy of /proc/iomem into a parent-child
tree of frozen IomemEntry dataclasses (instead of only top-level
indent-0 ranges), resolving physical addresses to the most specific
sub-range (such as Kernel code/data/bss inside System RAM) and rolling
child counts up into parent totals.
- Support profiling multiple memory events in a single perf.data session
(keyed by evsel name) instead of assuming a single global event.
- Add argparse CLI options (-i/--input and --iomem to allow supplying an
offline /proc/iomem snapshot from a target system).
Add a shell test (test_mem_phys_addr_python.sh) to verify the standalone
script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Port stat-cpi.py from the legacy embedded scripting framework to a
standalone Python script in tools/perf/python/ to calculate Cycles Per
Instruction (CPI) per interval per CPU or thread.
Improvements compared to the legacy script:
- Support both perf.data file mode (via perf.session stat callbacks)
and live counter collection mode (using perf.parse_events,
evlist.open, and evsel.read across intervals), with automatic fallback
to user-space (:u) and self-process monitoring when perf_event_paranoid
restricts system-wide events (EACCES).
- Compute per-interval counter deltas (val, ena, run) keyed by raw event
name so cumulative PERF_RECORD_STAT snapshots and hybrid PMU events
(e.g. cpu_core/cycles/, cpu_atom/cycles/) are accumulated accurately,
and scale counts by time_enabled / time_running when multiplexed.
- Replace hard-coded CPU ([0, 1]) and thread ([0]) arrays with dynamic
CPU and thread discovery so arbitrary system topologies work
automatically.
- Add CLI option handling (-i, -I, -p) via argparse and type annotations
passing mypy and pylint.
Add a shell test (test_stat_cpi_python.sh) to verify the standalone
script.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
LiveSession.run() synchronously blocks while polling evlist for events.
When running interactive tools or scripts from the terminal,
KeyboardInterrupt exceptions raised via Ctrl-C must propagate so the
caller can break out of the polling loop.
Previously, LiveSession caught KeyboardInterrupt with an empty pass
statement, swallowing the exception and preventing calling scripts from
detecting the interrupt cleanly. Remove the empty handler so calling
scripts receive KeyboardInterrupt and can perform clean teardown.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Add support for Intel PT call_return events and itrace options to the
perf Python extension so standalone Python scripts can decode and
inspect low-level instruction traces.
Specifically:
- Add a call_return callback parameter and itrace option string to
perf.session, treating explicit None (Py_None) callbacks as omitted.
- Expose the perf.call_return object with db_id, parent_id, insn_count,
cyc_count, comm, pid, tid, call_time, return_time, branch_count,
call_ref, return_ref, flags, and call_path (resolved as a
perf.callchain ordered from outermost caller to callee, populating
frame->map and frame->sym so call_path entries expose resolved symbol
and DSO names).
- Export perf.CALL_RETURN_NO_CALL, perf.CALL_RETURN_NO_RETURN, and
perf.CALL_RETURN_NON_CALL flag constants.
- Expose session.e_machine and session.is_64_bit properties, preferring
recorded thread ELF machines (perf_session__e_machine) over perf_env
so pipe-mode traces do not prematurely cache host bitness.
- Support optional vmlinux, kallsyms, and symfs symbol configuration
parameters (and PERF_SYMBOL_VMLINUX, PERF_SYMBOL_KALLSYMS,
PERF_SYMBOL_SYMFS environment fallbacks) in perf.session, resetting
symbol_conf pointers and freeing vm_tm_corr_args, cpu_bitmap, and
ptime_range in pyrf_session__delete().
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Expose destination address location components (addr_dso, addr_symbol,
addr_sym_offset), branch/transaction metrics (branch_type, in_tx,
flags, transaction), machine_pid, vcpu, sym_offset, and context_switch
callbacks directly to the Python extension.
Also include supporting fixes and infrastructure updates in
util/python.c and perf.pyi:
- Support fetching sym_offset on resolved sample symbols.
- Populate sample machine_pid and vcpu from evlist__id2sid() when
perf_guest is enabled, and resolve samples against the matching guest
or host machine.
- Expose next_prev_pid and next_prev_tid on switch_event only for
PERF_RECORD_SWITCH_CPU_WIDE records (returning None otherwise).
- Wire up tracing_data in pyrf_session__new() and update perf.pyi type
stubs (including srccode() and insn() return types).
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Add module docstrings to counting.py, tracepoint.py, and twatch.py. This
satisfies pylint's missing-module-docstring check and prepares these
existing standalone scripts in tools/perf/python/ for the later commit
in this series ("perf script: Support standalone scripts and remove
embedded scripting"), which updates 'perf script -l' to scan
tools/perf/python/ and display each script's module docstring:
```
$ perf script -l
List of available scripts:
...
counting
Example for counting perf events.
...
tracepoint
Example showing how to enable a tracepoint and access its fields.
twatch
Example to show how to enable a software event and track
context switches.
...
```
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Clean up pylint warnings in twatch.py so that it passes pylint without
warning suppression comments:
- Convert tab indentation to 4 spaces (W0311: bad-indentation).
- Remove unnecessary trailing semicolon (W0301: unnecessary-semicolon)
after evsel.open().
- Convert floating multi-line string comments to '#' comments (W0105:
pointless-string-statement).
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Clean up pylint warnings in tracepoint.py so that it passes pylint
without warning suppression comments:
- Catch ImportError instead of bare 'except:' (W0702: bare-except) when
importing setproctitle.
- Remove unnecessary trailing semicolon (W0301: unnecessary-semicolon)
after evlist.enable().
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Clean up pylint warnings in treport.py so that it passes pylint without
warning suppression comments:
- Replace broad 'except Exception:' clauses (W0718:
broad-exception-caught) with specific exception tuples.
- Pass both pid and sample_tid to session.find_thread() so guest and
process threads are resolved accurately.
- Rename parameter 'args' to 'pos_args' in FlameGraph.__init__() to
avoid shadowing the outer scope variable 'args' (W0621:
redefined-outer-name).
- Clear session = None in a finally block after session.process_events()
to break the C perf_session reference cycle before launching the TUI.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Replace bare 'except:' clauses (pylint W0702: bare-except) in ilist.py
with specific exception tuples (OSError, ValueError, RuntimeError,
TypeError, KeyError) and use a safe '.get("name", "")' sort key in
IListApp.compose() so that ilist.py passes pylint without warning
suppression comments and handles unnamed PMU events gracefully.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Update pyrf_session__find_thread() in util/python.c to accept an
optional tid parameter (defaulting to pid) and return None instead of
raising TypeError when a thread is not found in the session machines.
Update perf.pyi to match:
- Set session.find_thread() signature to (pid: int, tid: int = -1) ->
Optional[thread].
- Update callchain_node.symbol and callchain_node.dso to str (the C
getters return "[unknown]" fallback strings rather than None) and add
__iter__() to callchain.
Also update treport.py to handle Optional[thread] returned by
session.find_thread().
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Update the PyArg_ParseTupleAndKeywords format string for
pyrf__syscall_name() and pyrf__syscall_id() from "i|$i" to "i|i" (and
"s|$i" to "s|i"), allowing elf_machine to be passed as an optional
positional argument as well as a keyword argument. Update syscall_id()
and syscall_name() in perf.pyi to match, and set the return type of
syscall_name() to Optional[str] as unknown syscall numbers return None.
Also expose perf_env__arch_strerrno() as perf.arch_strerrno(err,
elf_machine=None) so standalone Python scripts can resolve
architecture-specific errno names directly from the auto-generated
trace beauty tables instead of maintaining duplicate errno dictionaries
in Python. Tighten the macro pattern in arch_errno_names.sh to
E[A-Z0-9]+ so compiler -D flags containing underscores (such as LLVM's
-DEXPERIMENTAL_KEY_INSTRUCTIONS=1) do not shadow EPERM (1), and add
EM_SPARC32PLUS alongside EM_SPARC and EM_SPARCV9.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Updates Tree type hints to correctly use TreeNode[TreeValue]
across all assignments preventing mypy strictness mismatches.
Address some other minor stylistic issues reported by mypy, pylint and
Sashiko.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Implement a flamegraph widget that recursively walks down a tree
splitting line segments based on their value (summed up periods across
call chains). A visitor pattern is used so that the same logic can
both draw the line segments and locate which segment had a mouse
click.
Add a tab for the flame graph widget.
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Co-developed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Alice Rogers <alice.mei.rogers@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
A textual app that displays the results of processing samples similar
to perf report. The app displays a tree of first processes and then
functions which drop down to show more detail on the functions they
call. The functions with the largest number of samples are sorted
first, after each function the percentage of time spent within it is
highlighted. If more than one event is recorded then each event
appears first, with the processes and functions sorted for that event
beneath it.
The app is written in python and requires the textual framework. Using
the textual framework means that in most modern terminals the mouse is
supported, the color scheme can be configured, and screenshots made.
With perf report:
```
$ perf record -e cycles:u -g perf test -w brstack
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.008 MB perf.data (57 samples) ]
$ perf report
...
Samples: 57 of event 'cycles:u', Event count (approx.): 15907831
Children Self Command Shared Object Symbol
- 88.86% 0.00% perf libc.so.6 [.] 0x000079b17df69ca8
0x79b17df69ca8
main
handle_internal_command
cmd_test
- brstack
- 84.27% brstack_bench
- 40.69% brstack_foo
brstack_bar
3.32% brstack_bar
3.31% brstack_bar
1.27% brstack_foo
+ 88.86% 0.00% perf perf [.] main
+ 88.86% 0.00% perf perf [.] handle_internal_command
+ 88.86% 0.00% perf perf [.] cmd_test
+ 88.86% 0.00% perf perf [.] brstack
+ 84.27% 40.26% perf perf [.] brstack_bench
+ 41.96% 30.71% perf perf [.] brstack_foo
+ 17.89% 17.89% perf perf [.] brstack_bar
```
With the treport script:
```
$ perf record -e cycles:u -g perf test -w brstack
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.008 MB perf.data (57 samples) ]
$ tools/perf/python/treport.py
O ReportApp
Report
╸━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
▼ Profile
└── ▼ cycles:u 100%
└── ▼ perf (32963) 100%
├── ▼ /usr/lib/x86_64-linux-gnu/libc.so.6 0x79b17df6
│ └── ▼ main 56.1%
│ └── ▼ handle_internal_command 56.1%
│ └── ▼ cmd_test 56.1%
│ └── ▼ brstack 56.1% ▁▁
│ ├── ▼ brstack_bench 52.6%
│ │ ├── ▶ brstack_foo 24.6%
│ │ └── brstack_bar 1.75%
│ ├── brstack_foo 1.75%
│ └── brstack_bar 1.75%
├── ▶ /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
▌
^q Quit ▏^p palette
```
Committer testing:
One needs to install 'python-textual' to have this working.
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Co-developed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Alice Rogers <alice.mei.rogers@gmail.com>
Link: https://lore.kernel.org/r/20260809051820.2436530-2-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
The metrics() function can return a dictionary where the value is either
a string or a list of strings, so the type signature in the stub file
should be Union[str, List[str]].
Fixes: 430da3cd03b4 ("perf python: Add perf.pyi stubs file")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
|