summaryrefslogtreecommitdiff
path: root/tools/perf
AgeCommit message (Collapse)Author
2026-10-17perf test attr: State, spelled out in a line, why a test is skippedArnaldo Carvalho de Melo
Per skip the default output shows a self contained one liner: unsupp 'test-record-branch-filter-any' exit 255, expected 1, no attrs recorded to verify skipped [kernel newer than 6.12] 'test-record-group-sampling' skipped [arch = !aarch64, machine = aarch64] 'test-record-graph-default' The extra notes explaining the reason, with a copy pasteable command to observe the failure, come in the very same stream when the verbosity is bumped, at -vvv, nothing is written to a separate place for later consultation, it is just the logging ladder: detail: '/root/bin/perf record -o /dev/null --no-bpf-event -j any kill' exited with 255, the expectations want the workload's 1 exit, so there are no attrs recorded to verify; this is normally a capability problem, run '/root/bin/perf record -o /dev/null --no-bpf-event -j any kill' to see why Note that 'perf test -v/-vv/-vvv attribute' appends a single -v to the shell test entry (shell_test__run()), so to see the notes one runs the python module directly, f.i.: python3 tests/shell/lib/attr.py -vvv -d tests/shell/attr -p ./perf The skip functions now return the reason fragment when they want to skip and None when the test can go on. The command suggested to observe the failure writes to /dev/null, so it doesn't leave a perf.data in the directory it is run from. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Ignore the group read_format bit the PMU count can removeArnaldo Carvalho de Melo
read_format's PERF_FORMAT_GROUP bit asks for the group members to be read along with the leader, which aside from this bit is verified with the fd/group_fd based group checking in Test.compare(), and with more than one core PMU a group whose members are pinned to one of them, say 'default_core', leaves the clones for the other core PMUs without any members: $ perf stat -e '{cycles,default_core/legacy-hardware-config=3/}:S' ... the A53 leader keeps its cohort, both A73 cycles clones are alone, read_format 20 instead of 28 so that bit isn't there: whether it is there is a consequence of how the evlist got expanded to more than one core PMU, not of the groupness the expectations say about, which is verified structurally, so take it out on both sides. That leaves the A73 leader clones, now with: expected read_format=28|31, got 20 matching the base event expectations again. With a single core PMU there is nothing to expand, so there is nothing to explain away: count the core PMUs when the script starts, from what perf makes of 'cycles', see parse_events_multi_pmu_add(), and take the bit out only when there is more than one, leaving the machines with a single core PMU verifying what the expectations say about it. That count is 2 on the Amlogic A311D, where its A53 and A73 PMUs both answer for 'cycles', and 1 on a machine with a single core PMU. Where there is no binding to ask, as when attr.py runs without setup_python.sh, the count isn't available and the bit is taken out as well. core_pmu_count() takes the count from the same probe core_pmu_available() uses, so the binding is asked once, and only when a comparison needs the answer, not at import time. The sample id bits hide_sample_id() takes out when the expectations ask for none are another consequence of having more than one core PMU, so the same single core PMU gate covers them; equating the two id bits, needed when the evlist has more than one event even with a single core PMU, keeps applying. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Leave out the events of the other core PMUsArnaldo Carvalho de Melo
On a hybrid machine the default stat metrics are opened on each core PMU, and the events of the other one have their own encodings: on an i7-14700K cpu_atom (type 10) opens UOPS_RETIRED.ALL, config 194, which the expectations, written for cpu_core (type 4), don't name: expected type=4, got 10 expected config=209|391, got 194 The test already masks the core PMU type out of 'config' for the legacy events, but raw events keep their type and encoding, so leave out the events of the core PMUs no expectation names, like the dummy tracking event. Core PMUs are found as perf finds them: 'cpu' or 'cpum_cf', or a PMU with a 'cpus' file in sysfs. Nothing is left out unless an expectation names a core PMU, so single core PMU machines and the tests with only legacy expectations are not affected. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Ignore the dummy tracking event and the terms it carriesArnaldo Carvalho de Melo
With more than one core PMU the requested events can't cover all the CPUs, each cluster has its own PMU, so perf opens the software dummy event to carry the tracking terms (mmap, comm, task, mmap_data), leaving the requested events without them: expected mmap=1, got 0 expected comm=1, got 0 expected task=1, got 0 That dummy event is not part of what the expectations are about, so leave it out of the comparison, unless the expectations ask for one, like system-wide-dummy and test-record-dummy-C0 do. And when perf used it to carry the tracking terms, those terms can't be matched on the requested events, leave them out of the match as well. The terms are left out only where the dropped dummy actually carried them, from the sample_type it was opened with, a dummy that didn't is no reason to stop verifying them. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Accept either sample id bit perf asks forArnaldo Carvalho de Melo
evlist__config() asks for a way to tell the samples apart, PERF_SAMPLE_IDENTIFIER where available, PERF_SAMPLE_ID otherwise: bool sample_id = opts->sample_id; ... if (opts->full_auxtrace || opts->sample_identifier) { ... use_sample_identifier = perf_can_sample_identifier(); sample_id = true; } else if (evlist__nr_entries(evlist) > 1) { ... use_sample_identifier = perf_can_sample_identifier(); sample_id = true; } so the id is asked for whenever the evlist has more than one event, and also when asked to outright, with --sample-identifier or by an auxtrace session, or by record__config() for a pipe run, through opts->sample_id, none of which depends on the sample types: 'perf record --sample-identifier -e cycles' and the arm SPE expectations in this very directory ask for it with a single event. Which one it asks for depends on the composition of the evlist: with more than one core PMU a request for 'cycles' becomes one event per core PMU, the extra dummy tracking events then make the sample types differ and perf goes for IDENTIFIER, while the expectations were written on machines with a single core PMU, where perf asks for ID: expected sample_type=263, got 65799 # 263 | (1 << 16) expected sample_type=343, got 65815 # (343 & ~(1 << 6)) | (1 << 16), group-sampling Both bits mean the same thing here, how the samples get associated with the event that produced them, so when the expectation asks for one of them, ask for "an id of some sort" on both sides, and when the expectation doesn't ask for any, take the bits out of what got recorded: whether they are there and which one it is are consequences of what was asked for and of how the request got expanded, none of that is what these expectations are about. Since Test.compare() looks at both directions, expectations matching the recorded events and recorded events matching the expectations, keep track of which side is the one perf recorded to take the bits out of the right side. The masking is only for the comparison: the warnings keep showing the values as they are, nothing to un-mask by hand to see what is being complained about. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Introduce mask_bits(), generalizing hide_core_pmu_type()Arnaldo Carvalho de Melo
What hide_core_pmu_type() does is take a set of bits out of each of the '|'-separated alternatives in a value, wildcards included, keeping the rest of the expression: extract that as mask_bits() and implement hide_core_pmu_type() in terms of it, a prep for using the same thing to ignore, when comparing expectations, the sample id bit perf ends up asking for and the read_format group bit that a PMU count can remove. No change in behaviour. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf evsel: Close the fds opened so far when disabling missing featuresArnaldo Carvalho de Melo
evsel__open_cpu() opens the events one by one and, when an open fails with EINVAL and evsel__detect_missing_features() has a feature to leave out, goes back to fallback_missing_features to open them all again from start_cpu_map_idx, without closing what the abandoned attempt opened: the fd of every CPU or thread that was opened before the failing one is overwritten in the FD() array, leaking it. Close them first, the same way out_close does when returning an error, leaving the entries at -1 for the retry. Fixes: af954f76eea5 ("perf tools: Check fallback error and order") Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://lore.kernel.org/r/sashiko-outbox-173532@kernel.org Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf evsel: Don't dump probe events to PERF_TEST_ATTRArnaldo Carvalho de Melo
Events opened just to ask if they are supported, i.e. the ones in is_event_supported() and is_libpfm_event_supported(), go through the regular evsel__open() path and thus end up in the event files written to $PERF_TEST_ATTR, with everything but type, config and disabled zeroed: [event-0-38654705664-3] fd=3 cpu=-1 pid=0 type=0 size=0 config=38654705664 sample_type=0 ... which 'perf test attr' then takes as one of the events that were asked for, failing with: expected cpu=0, got -1 expected size=176, got 0 expected sample_type=65927, got 0 expected freq=1, got 0 This started showing up when there is more than one core PMU, as perf_pmus__supports_extended_type() probes one such event per core PMU, but these records were always bogus: nothing asked for them. Flag those evsels as support probes, keeping the name clear of the kprobe/uprobe meaning probe already has in evsel, and leave them out of the dump. Reported-by: Namhyung Kim <namhyung@kernel.org> Link: https://lore.kernel.org/linux-perf-users/asWQvXRdqp_RK85c@google.com/ Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Ignore the core PMU type perf puts in 'config'Arnaldo Carvalho de Melo
Since commit 55bcf6ef314a ("perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE") in v5.13, and arm_pmu opted in with commit 5c816728651a ("arm_pmu: Add PERF_PMU_CAP_EXTENDED_HW_TYPE capability") in v6.6, the kernel can be told which core PMU a legacy type event is meant for, with its type in the top 32 bits of 'config', see perf_pmus__supports_extended_type(), which __parse_events_add_numeric() does for HARDWARE and HW_CACHE events, but only when there is more than one core PMU, i.e. on heterogeneous machines, where asking for one event ends up being one event per core PMU: $ perf stat -e cycles -a -- sleep 1 20,520,998 armv8_cortex_a53/cycles/ 13,029,350 armv8_cortex_a73/cycles/ and what lands in PERF_TEST_ATTR is the extended encoding: type=0 config=38654705664 # core PMU type 9, PERF_COUNT_HW_CPU_CYCLES so the expectations written for the single core PMU case fail with: expected config=0|1, got 38654705664 expected config=0, got 38654705664 # 'perf stat -d' L1-dcache events which is what now happens on an Amlogic A311D (2 Cortex-A53 + 4 Cortex-A73), a machine that just got the CPU PMU nodes it was missing. Take those bits out when comparing the 'config' of legacy type events, keeping what these expectations mean on machines with a single core PMU: which of the PMUs is counting is not what we're asking here. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf evsel: Mark the event as supported when retrying an openArnaldo Carvalho de Melo
Opening a group with perf record on a machine with perf_event_paranoid > 1 and no CAP_PERFMON fails the first perf_event_open() with EACCES, after which evsel__open_cpu() clears evsel->supported; evsel__fallback() then adds exclude_kernel and record__open() retries, and the retry succeeds with supported left false. get_group_fd() treats unsupported events as ungroupable, so the retry opens the group members without their leader: sys_perf_event_open: pid 12345 cpu 0 group_fd -1 FAILED '.../test-record-group-sampling1' - group failure which fails the group subtests of "perf test 82", the Perf attribute expectations test, when it is run as a regular user, while it passes as root or with CAP_PERFMON, where the first open doesn't fail. commit 2cc7aa995ce9 ("perf stat: Refactor retry/skip/fatal error handling") dropped the pos->supported = true that record__open() did after a successful open and moved the resets into the stat code only, while saying "When an event is tried the supported is set to true again". Do that in evsel__open_cpu(), which every open entry point funnels through, so that a retry describes its own try instead of the previous failure. Fixes: 2cc7aa995ce9ecd8 ("perf stat: Refactor retry/skip/fatal error handling") Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Cc: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Relax group checking for ungrouped expectationsArnaldo Carvalho de Melo
When matching the recorded events back against the expectations, attr.py requires every event opened in a group to match an expectation that declares the same group. The perf stat default metrics open the events of each metric in groups, but the test expectations only verify the event attributes, so test-stat-default fails with: FAILED '.../test-stat-default' - group failure Only enforce the group of a recorded event when the expectation it matches declares one. Expectations that ask for a group are still verified in both directions. Fixes: c7adeb0974f18da4 ("perf jevents: Add set of common metrics based on default ones") Fixes: 2dfc0cab3da4a205 ("perf stat: Add detail -d,-dd,-ddd metrics") Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Fix default stat metrics expectationsArnaldo Carvalho de Melo
Since commit c7adeb0974f1 ("perf jevents: Add set of common metrics based on default ones") and commit 2dfc0cab3da4 ("perf stat: Add detail -d,-dd,-ddd metrics") the perf stat default metrics open their events in groups, so group leaders and members have read_format=15 and members are enabled without enable_on_exec, while standalone events keep read_format=3 and are disabled until exec. Also, since commit b1c5efbfd92e ("perf parse-events: Remove hard coded legacy hardware and cache parsing") bare hardware events resolve to the core PMU sysfs/JSON events (type 4), so add the raw encodings the Intel and AMD core PMUs use for instructions, branch-misses, cpu-cycles and stalled-cycles-frontend/backend to test-stat-default and test-stat-detailed-1/2/3. Add base-stat-group, that accepts both the standalone and the group variants of read_format, disabled and enable_on_exec, and point the four default/detailed expectations at it. test-stat-basic, test-stat-C0 and test-stat-no-inherit keep base-stat, whose events aren't opened in a group: for those, a change that groups or enables them differently is still something to catch. test-stat-group1 does open its events in a group, but pins read_format, disabled and enable_on_exec itself, the very terms base-stat-group loosens, so it doesn't need it either. Fixes: b1c5efbfd92eb84d ("perf parse-events: Remove hard coded legacy hardware and cache parsing") Fixes: c7adeb0974f18da4 ("perf jevents: Add set of common metrics based on default ones") Fixes: 2dfc0cab3da4a205 ("perf stat: Add detail -d,-dd,-ddd metrics") Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Fix legacy event encodings in group testsArnaldo Carvalho de Melo
Since commit b1c5efbfd92e ("perf parse-events: Remove hard coded legacy hardware and cache parsing"), event names are resolved with sysfs/JSON priority over the legacy encodings, so bare cache-misses and instructions now become the core PMU sysfs/JSON events (on x86 type 4, configs 0x412e and 0xc0) rather than the legacy PERF_TYPE_HARDWARE/config=3 and config=1 events the tests expect, e.g.: expected config=3, got 0 expected disabled=0, got 1 expected mmap=0, got 1 expected comm=0, got 1 expected freq=0, got 1 expected enable_on_exec=0, got 1 expected task=0, got 1 FAILED '.../test-record-group-sampling1' - match failure The shown diff is against the cycles group leader, as no result event matches the expected cache-misses member anymore. Request the legacy encodings explicitly with the legacy-hardware-config term, added in commit 0012e0fa221bf9cc ("perf jevents: Add legacy-hardware and legacy-cache json"), keeping the original attribute expectations unchanged, in: test-record-group1 test-record-group2 test-record-group3 test-record-group-sampling test-record-group-sampling1 test-record-group-sampling2 test-stat-group1 This went unnoticed until tests/attr.sh stopped ignoring attr.py's return value. Fixes: b1c5efbfd92eb84d ("perf parse-events: Remove hard coded legacy hardware and cache parsing") Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Allow tests to require a core PMUArnaldo Carvalho de Melo
On machines without a usable core PMU, like an aarch64 box with no DT node for the ARM PMU, the expectations that pin the legacy hardware encoding can't be checked: without a core PMU at all 'cycles' doesn't even resolve, and with one that can't be opened 'perf record' takes the software fallback and records attributes they can never match: expected type=0, got 1 expected config=0, got 1 FAILED '.../attr/test-record-group-sampling1' - match failure And since attr.py stops at the first failure, every expectation that would come after that one ends up not being run at all. Add a 'requires' limitation, modelled after the existing 'arch', 'auxv' and 'kernel_since/until' ones, with 'core-pmu' as its first value, that is checked by asking perf itself to open 'cycles' via its python binding: a parse failure or an ENOENT means there is no PMU that can count it, hence nothing to check and the test gets skipped, while any other error means we can't tell, so the test keeps running as it does today, where there is no binding to ask either. When there is no core PMU, asking the binding fails and prints a parse error, once for every test that asks, so the answer is kept: it is asked once per run. A value other than 'core-pmu' is warned about, not silently ignored, so a typo can't turn the skip into a no-op. An old distro python package may have a 'perf' module without parse_events(), i.e. there is nothing to ask with, so that AttributeError gets the same treatment as the ImportError: let the expectations speak. The expectations that have a strict 'type=0', plus the group tests, where the fallback drops a member and leaves nothing to compare the group leader attributes with, now state that they require a core PMU. They are marked here, before the commit that has the group tests ask for the legacy encodings, so the requisite comes with that dependency. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf python: Free the parse error entries when parsing failsArnaldo Carvalho de Melo
pyrf__parse_events() prints the entries parse_events_error__print() receives with the details of a failed parse, but returns without freeing them, leaking whatever parse_events_error__handle() allocated, so call parse_events_error__exit() on both paths, as the other parse_events() callers do. The perf test attr core PMU probe takes this failure path on machines without a core PMU, where the leak then happens on every test run. Fixes: f081defccd93 ("perf python: Add parse_events function") Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://lore.kernel.org/r/sashiko-outbox-173525@kernel.org Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test attr: Fix record dwarf sample_type expectationArnaldo Carvalho de Melo
Since commit bdd051e24914 ("perf record: Split --data-mmap option"), record_opts__parse_callchain() sets record_data_mmap instead of record->sample_address for the DWARF unwind mode, so -d/--data and its implied PERF_SAMPLE_DATA_SRC are not enabled implicitly anymore. As a result, --call-graph dwarf no longer sets PERF_SAMPLE_ADDR and PERF_SAMPLE_DATA_SRC, making the test fail: expected sample_type=45359, got 12583 where 45359 (0xb12f) is: IP|TID|TIME|ADDR|CALLCHAIN|PERIOD|REGS_USER|STACK_USER|DATA_SRC and 12583 (0x3127) is: IP|TID|TIME|CALLCHAIN|PERIOD|REGS_USER|STACK_USER i.e. the values differ exactly by PERF_SAMPLE_ADDR (0x8) and PERF_SAMPLE_DATA_SRC (0x8000). The mmap_data=1 expectation is still correct as DWARF now enables record_data_mmap. This went unnoticed until tests/attr.sh stopped ignoring attr.py's return value. Fixes: bdd051e249141c79 ("perf record: Split --data-mmap option") Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-15perf test: Fix dso data testsNamhyung Kim
Now dso__binary_type() requires that the target file is a valid ELF file containing ".text" section. But the test only checks cached read/write operation on a file. Let's set the binary type to bypass the ELF check to read/write the file properly. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-15perf annotate: Simplify symbol__disassemble() with dso binary_typeNamhyung Kim
Now it should set the binary type of a DSO properly. No need to figure out a filename suitable for disassembly. Just call dso__find_binary_type() and dso__get_filename() for that type. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-15perf symbol: Do not set binary type from symtab typeNamhyung Kim
The DSO binary type is to access the binary (e.g. instruction) data while symtab type is for the symbol table. They may or may not be in the same file. We should track them separately and correctly. As special binaries already set their type before loading symbols, leave the binary type info and only update it when actually opening the DSO. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-15perf symbol: Set binary type for JIT map DSOsNamhyung Kim
The perf-<pid>.map files contain symbol name of JIT functions. As they don't have the binary data (instructions) no need to try for dso_data. Let's set the binary type regardless of the result of symbol loading so that it can be ignored. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-15perf tools: Factor out dso__find_binary_type()Namhyung Kim
Separate out the logic to detect binary type of a DSO. It checks if the candidate file contains ".text" section. There could be data-only DSOs but as our use cases focus on the code (perf annotate or intel PT), we can ignore them for now. But it also can fail due to open file limit. Handle the case by retrying with _dso__data_open_lock. Introduce bintype_searched flag and it accessors to prevent repeated (failed) search. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> [ Fixed the clang -Wthread-safety-analysis error: _dso__data_open_lock is not held on every path ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-14perf symbol: Get rid of machine_or_dso_e_machine()Namhyung Kim
The function tries to get e_machine from a DSO (preferred) or env from the machine. But currently it's only used for kernel DSO's during the load which refers to /proc/kallsyms most likely and it doesn't have an ELF header. Also machine->env would have proper information about the kernel so no need to check DSO in this case. Actually check DSO's e_machine requires a correct binary type to be set but it'd cause a recursive locking problem. I think it's ok to use machine->env info for the kernel. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-14perf symbol: Set binary/symtab type for split kallsymsNamhyung Kim
When it creates new DSOs for split kallsyms, set the binary and symtab type to KALLSYMS properly. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-14perf symbol: Update symtab type of vmlinux from build-id cacheNamhyung Kim
Currently dso__load_vmlinux() sets both binary type and symtab type to VMLINUX. To precisely track the symtab type of the kernel dso, update the type to build-id cache if it's loaded from there. It won't have any functional difference though. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-14perf tools: Try linked debug files for DSO debug infoNamhyung Kim
The dso__find_dbginfo_type() should try DSO_BINARY_TYPE__DEBUGLINK so it can follow the .gnu_debuglink and find the debug information in the separate file. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-14perf tools: Check ELF section type with nameNamhyung Kim
In filename__has_section(), it just checks the name of the section but it's possible that the section header is present without actual data. In that case, it'll have SHT_NOBITS type and can confuse the result. Update the function to check the section type as well. Normally we want to check if the section content is present in the file so it'd have SHT_PROGBITS. All the current callers of the function expect the section with SHT_PROGBITS type (even for debug info). Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-14perf tools: Remove redundant dso data initNamhyung Kim
The fd and status are initialized later with cache. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-13perf test: Update PE file test for other locationsNamhyung Kim
The test__pe_file_parsing() expects the test is in the tools/perf directory, but it could be root or a separate build directory. Let's update the logic to try other paths like in the shell_tests__dir_fd(). Also add some debug messages to inform users why it's skipped. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-13perf symbol: Set dso symtab type for libbfdNamhyung Kim
It missed to set the dso symtab type when the symbols are loaded by libbfd. When it happens both syms_ss and runtime_ss may not be set and won't call dso__load_sym(). Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-13perf symbol: Add missing symsrc__destroy() for libbfdNamhyung Kim
When libbfd loaded symbols and there's a pending syms_ss, it'd be lost or overwrite existing symbols. Let's destroy it before breaking the loop so that it can safely return from the function. Closes: https://lore.kernel.org/r/sashiko-outbox-162540@kernel.org Fixes: eac9a4342e5447ca ("perf symbols: Try reading the symbol table with libbfd") Reported-by: Sashiko <sashiko-bot@kernel.org> Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Remi Bernon <rbernon@codeweavers.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-13perf symbol: Fix symbol loading from libbfdNamhyung Kim
The dso__load() should return a positive number (number of symbols loaded) when it succeded to load symbols. But dso__load_bfd_symbols() only returns 0 and it's hard to check if it actually loaded symbols or not. Let's return the value of dso__has_symbol() and check it in dso__load() so that it can return 1 for success. Closes: https://lore.kernel.org/r/sashiko-outbox-162540@kernel.org Fixes: eac9a4342e5447ca ("perf symbols: Try reading the symbol table with libbfd") Reported-by: Sashiko <sashiko-bot@kernel.org> Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Remi Bernon <rbernon@codeweavers.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-13perf test attr: Source setup_python.sh instead of calling pythonArnaldo Carvalho de Melo
The "Perf attribute expectations test" (perf test 82) fails on machines that don't ship a bare 'python' binary, i.e. distributions that provide only python3 unless python-is-python3 or an equivalent is installed. Namhyung Kim hit this and posted the fix applied here in <asWLmvF-3YtoKJ7j@google.com>: /home/namhyung/project/linux/tools/perf/tests/shell/attr.sh: line 20: python: command not found ---- end(-1) ---- 82: Perf attribute expectations test : FAILED! attr.sh is the only shell test that still invokes python directly; do what the others do: source lib/setup_python.sh, which prefers python3, falls back to python and skips the test when no interpreter is found, then run $PYTHON. Fixes: 8519e4f44c2af722 ("perf test: Add a shell wrapper for "Setup struct perf_event_attr"") Reported-by: Namhyung Kim <namhyung@kernel.org> Suggested-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Ian Rogers <irogers@google.com> Link: https://lore.kernel.org/linux-perf-users/asWLmvF-3YtoKJ7j@google.com/ Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-13Merge branch 'tip/sched/urgent'Peter Zijlstra
Pickup dependencies; notably the RB-tree fix. Signed-off-by: Peter Zijlstra <peterz@infradead.org>
2026-10-07perf test: Add false_sharing workload exhibiting cross-CPU false sharingArnaldo Carvalho de Melo
Add a 'perf test -w false_sharing' workload that hammers one shared struct from several CPUs, shaped as a TCP connection: a read-mostly identity (five-tuple) shares a cacheline with per-packet rx counters (the false-sharing line), a second line has packet-path private tx and congestion control counters, and a third the connection config. The packet path runs in the main thread and up to four lookup threads sum the five-tuple and pull the config, reading one volatile shared instance directly so the accesses are PC-relative and resolvable by the data type profiler. Data type profiling of the workload with cacheline info: $ perf mem record -- perf test -r5 -w false_sharing [ perf record: Woken up 19 times to write data ] [ perf record: Captured and wrote 5.612 MB perf.data (72454 samples) ] $ perf report -s type,typecln -H --group --stdio # Total Lost Samples: 0 # # Samples: 72K of events 'cpu/mem-loads,ldlat=30/P, cpu/mem-stores/P' # Event count (approx.): 1261814616 # # Overhead Data Type / Data Type Cacheline # ................... ............................... # 88.99% 35.88% struct net_conn 56.43% 17.50% struct net_conn: cache-line 0 32.55% 0.00% struct net_conn: cache-line 2 0.01% 18.38% struct net_conn: cache-line 1 10.08% 63.03% (unknown) 10.08% 63.03% (unknown): cache-line 0 0.82% 0.13% int 0.82% 0.13% int: cache-line 0 0.01% 0.02% struct folio 0.01% 0.02% struct folio: cache-line 0 0.01% 0.03% Elf64_Addr 0.01% 0.03% Elf64_Addr: cache-line 0 0.01% 0.03% struct sched_entity 0.01% 0.03% struct sched_entity: cache-line 1 0.00% 0.00% struct sched_entity: cache-line 4 0.00% 0.00% struct sched_entity: cache-line 2 0.00% 0.00% struct sched_entity: cache-line 3 0.00% 0.00% struct sched_entity: cache-line 0 0.01% 0.00% struct task_group 0.01% 0.00% struct task_group: cache-line 4 0.00% 0.00% struct task_group: cache-line 5 0.00% 0.00% struct css_rstat_cpu 0.00% 0.00% struct css_rstat_cpu: cache-line 0 $ perf report -s type,typecln,typeoff -H --group --stdio # Total Lost Samples: 0 # # Samples: 72K of events 'cpu/mem-loads,ldlat=30/P, cpu/mem-stores/P' # Event count (approx.): 1261814616 # # Overhead Data Type / Data Type Cacheline / Data Type Offset # ...................... .................................................. # 88.99% 35.88% struct net_conn 56.43% 17.50% struct net_conn: cache-line 0 9.81% 0.00% struct net_conn +0xa (dport) 9.54% 0.00% struct net_conn +0x8 (sport) 9.53% 0.00% struct net_conn +0xc (state) 9.48% 0.00% struct net_conn +0xd (protocol) 9.27% 0.00% struct net_conn +0x4 (daddr) 8.79% 0.00% struct net_conn +0 (saddr) 0.00% 12.08% struct net_conn +0x10 (bytes_rx) 0.00% 1.71% struct net_conn +0x18 (packets_rx) 0.00% 2.80% struct net_conn +0x20 (rx_queue) 0.00% 0.91% struct net_conn +0x3c (last_ack) 32.55% 0.00% struct net_conn: cache-line 2 5.70% 0.00% struct net_conn +0x83 (rcv_wscale) 5.46% 0.00% struct net_conn +0x84 (keepalive_int) 5.43% 0.00% struct net_conn +0x82 (snd_wscale) 5.39% 0.00% struct net_conn +0x80 (mss) 5.34% 0.00% struct net_conn +0x88 (mark) 5.23% 0.00% struct net_conn +0x8c (priority) 0.01% 18.38% struct net_conn: cache-line 1 0.01% 0.05% struct net_conn +0x5c (retrans) 0.00% 4.83% struct net_conn +0x40 (bytes_tx) 0.00% 10.63% struct net_conn +0x48 (packets_tx) 0.00% 1.54% struct net_conn +0x58 (rtt_us) 0.00% 1.07% struct net_conn +0x50 (cwnd) 0.00% 0.25% struct net_conn +0x54 (ssthresh) 10.08% 63.03% (unknown) 10.08% 63.03% (unknown): cache-line 0 10.08% 63.03% (unknown) 0.82% 0.13% int 0.82% 0.13% int: cache-line 0 0.82% 0.13% int +0 (no field) 0.01% 0.02% struct folio 0.01% 0.02% struct folio: cache-line 0 0.01% 0.00% struct folio +0 (flags.f) 0.00% 0.01% struct folio +0x34 (_refcount.counter) 0.00% 0.00% struct folio +0x18 (mapping) Assisted-by: LLM Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-07perf report: Add --no-progress optionArnaldo Carvalho de Melo
Now that --progress is being added for the stdio case, wire up its counterpart for the browsers: the TUI and GTK ones present progress of their own and there is no way to turn it off. Install the no-op ui_progress ops, the ones already used until a backend sets theirs, after setup_browser() installed the ones of the browser in use. The phases are still counted, nothing is shown for them, and no second option is needed for it: parse-options provides --no-progress as the negation of --progress, report.progress_set saying that it was asked for, report.progress being false both when nothing was asked for and when --no-progress was. Suggested-by: Namhyung Kim <namhyung@kernel.org> Assisted-by: LLM Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-07perf report: Add --progress optionArnaldo Carvalho de Melo
Processing a large session with stdio output gives no feedback about which phase perf is in or how far along it is: ui_progress updates are only shown by the TUI. Add --progress, installing a stdio backend (ui/stdio/progress.c) that prints the phase title, percentage and counts: Processing events... [ 42.3%] 317M / 746M Phases can be nested, so the backend tracks the ones started to complete the right one on ui_progress__finish(); that requires init()/finish() pairs, fixed in ordered-events.c and the pipe and directory event processing. With a pager both stdout and stderr lead to it, so isatty(stderr) turns false and the updates end up printed one per line in the pager's output: use /dev/tty in that case, so that the updates keep updating in place, untouched by the pager. Assisted-by: LLM Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-07perf config: Serialize config file access with a mutexArnaldo Carvalho de Melo
Config file access shares the static parser state and, since perf_config__set_variable() became an entry point for background features, can run on more than one thread: a feature writing the config while perf top's display thread reads it. Serialize parsing and rewriting with config_mutex and the whole read-modify-write of perf_config__set_variable() with config_update_mutex; config_set_mutex comes before it, as building the set parses the config files. perf has its own mutex type, util/mutex.h; the file scope mutexes here use the DEFINE_MUTEX() static initializer added in the previous patch. The two lazy inits that system_path() and home_perfconfig() do would leak all but one of the strings racing on two threads, so they move to DO_ONCE(), added in the previous patch as well. bad_config() runs on the dispatching thread, outside config_mutex, so it stops reading config_file_name, which the parsing thread owns. Assisted-by: LLM Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-07perf mutex: Add DO_ONCE() for one-time initializationArnaldo Carvalho de Melo
For lazy init that more than one thread can race into, without pthread_once() so that it stays within perf's locking primitives and clang's -Wthread-safety keeps an eye on the mutexes involved. Mirrors the kernel's include/linux/once.h DO_ONCE(), dropping its static key fast path, unnecessary at these cold init paths: a per call site static bool plus a statically initialized mutex, double checked. As there, code reachable from more than one call site must go through a common helper. The lockless fast path reads ___done with an acquire, paired with a release store after fn(), so that fn()'s side effects are visible to threads taking the fast path, which the dropped static key used to guarantee. The __atomic builtins are used rather than smp_load_acquire()/ smp_store_release() because ThreadSanitizer understands them, avoiding reports on ___done and on what fn() initialized. Assisted-by: LLM Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-07perf mutex: Add DEFINE_MUTEX() static initializerArnaldo Carvalho de Melo
For file scope mutexes, so that they don't need a constructor function to initialize them at startup, mirroring PTHREAD_MUTEX_INITIALIZER while keeping the clang -Wthread-safety annotations of struct mutex. DEBUG=1 builds have mutex_init() set PTHREAD_MUTEX_ERRORCHECK, making the CHECK_ERR() paths in mutex_lock()/mutex_unlock() report relocking a held mutex and unlocking one that isn't held. PTHREAD_MUTEX_INITIALIZER gives a default type mutex, so statically initialized ones would silently lose that: use PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, a glibc extension, falling back to the default type in libcs that lack it. Assisted-by: LLM Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-07perf config: Make perf_etc_perfconfig() never return NULLArnaldo Carvalho de Melo
perf_etc_perfconfig() returns what system_path() gives, and that allocates, so on failure every caller dereferenced NULL, the pre-existing ones in perf_config_set__init() and in the daemon included. For the usual absolute ETC_PERFCONFIG system_path() just returns a strdup of it, so use ETC_PERFCONFIG itself when that fails. Assisted-by: LLM Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-07perf config: Move perf_config__set_variable() to util/config.cArnaldo Carvalho de Melo
Move perf_config__set_variable() out of the 'perf config' builtin so that opt-in features can persist their choice from outside it, e.g. util/debuginfo.c writing core.debuginfod=false when the user disables debuginfod for the rest of the session. The set_config() body becomes perf_config_set__write(), with the system_config choice as an argument, as the builtin's use_system_config/use_user_config statics are not available outside it. perf_config_set__write() checked fopen() but none of the fprintf()s or fclose(), so a write failure after truncating the file was reported as success. Harmless for the interactive 'perf config' this came from, but this makes it an entry point a background feature can call with no other feedback, so propagate those errors too. Assisted-by: LLM Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-07perf test attr: Fix wrong size expectation for eventsMichael Petlan
Although config4 and tee sample_simd_* fields has been added into 'struct perf_event_attr', the size expectation for the struct hasn't been adjusted. This hasn't been noticed, since the testcase's return value has been ignored after rewriting the testcase to python until previous commit. Fix that. Fixes: eb89aef367e47010 ("perf headers: Sync perf_event.h/perf_regs.h with the kernel headers") Fixes: 80cdf208117a36de ("tools headers UAPI: Sync linux/perf_event.h with the kernel sources") Signed-off-by: Michael Petlan <mpetlan@redhat.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> [ Updated it to take into account 80cdf208117a36de (sample_simd_* fields) 144 -> 176 ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-07perf test attr: Propagate the return value from the test to the wrapperMichael Petlan
Currently it does not matter what the python script actually returns, the test always passes, as the $err variable is always 0. Fix that. Fixes: 8519e4f44c2af722 ("perf test: Add a shell wrapper for "Setup struct perf_event_attr"") Signed-off-by: Michael Petlan <mpetlan@redhat.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-03perf test: Add a test for perf timechart --tuiAlice Rogers
Test launching ttimechart through 'perf timechart --tui', the error when there are no scheduler events, the --dump output with the -P, -T and -p options, and drive the textual app headless exercising the views and key bindings. Committer testing: root@x2:/home/acme/git/perf-tools-next# perf test "perf timechart --tui (ttimechart.py) test" 167: perf timechart --tui (ttimechart.py) test : Ok === Test Summary === Passed main tests : 1 Passed subtests : 0 Skipped tests : 0 Failed tests : 0 root@x2:/home/acme/git/perf-tools-next# perf test -vv "perf timechart --tui (ttimechart.py) test" 167: perf timechart --tui (ttimechart.py) test: ---- start ---- test child forked, pid 2833475 perf timechart --tui plumbing test perf timechart --tui plumbing test [Success] ttimechart no events test ttimechart no events test [Success] ttimechart dump test ttimechart dump test [Success] ttimechart headless UI test ttimechart headless UI test [Success] ---- end(0) ---- 167: perf timechart --tui (ttimechart.py) test : Ok === Test Summary === Passed main tests : 1 Passed subtests : 0 Skipped tests : 0 Failed tests : 0 root@x2:/home/acme/git/perf-tools-next# 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>
2026-10-03perf timechart: Add an interactive --tui modeAlice Rogers
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>
2026-10-03perf test: Add a test for the treport scriptAlice Rogers
Test launching treport through 'perf script', the error for a file that isn't a perf.data file, drive the textual app headless checking the profile matches one built without the UI and exercising the key bindings, and that quitting while loading stops the background load. Committer testing: root@x2:/home/acme/git/perf-tools-next# perf test "perf script treport test" 166: perf script treport test : Ok === Test Summary === Passed main tests : 1 Passed subtests : 0 Skipped tests : 0 Failed tests : 0 root@x2:/home/acme/git/perf-tools-next# perf test -vv "perf script treport test" 166: perf script treport test: ---- start ---- test child forked, pid 2829708 treport plumbing test treport plumbing test [Success] treport bad file test treport bad file test [Success] treport headless UI test treport headless UI test [Success] treport cancel test treport cancel test [Success] ---- end(0) ---- 166: perf script treport test : Ok === Test Summary === Passed main tests : 1 Passed subtests : 0 Skipped tests : 0 Failed tests : 0 root@x2:/home/acme/git/perf-tools-next# 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>
2026-10-03perf treport: Show the profile while it loadsAlice Rogers
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>
2026-10-03perf test: Add a test for the ilist scriptIan Rogers
Test launching ilist through perf script and perf list --tui, and drive the textual app headless: check the tree of PMUs and metrics, search for and select the software task-clock event checking its counters are shown, check a failed search shows an error and select a metric. Failing to open counters, for example for want of permissions, is tolerated as an error dialog is shown. 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>
2026-10-03perf list: Add a --tui option to launch ilistIan Rogers
Add a --tui option to perf list that launches the textual based ilist script through perf script, similar to perf timechart --tui. Rather than printing the events, the PMUs, events and metrics can be browsed interactively and the selected event or metric is counted on each CPU. Arguments after '--' are passed to the script. Assisted-by: Antigravity:gemini-3.1-pro 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>
2026-10-03perf python: Release the GIL while processing session eventsIan Rogers
When a python session reads from a pipe, perf_session__new() and perf_session__process_events() block waiting for data with the GIL held, freezing any other python threads such as a TUI thread. Release the GIL around both calls and acquire it with PyGILState_Ensure() in the tool and call-return callbacks that invoke python. 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>