Re: [PATCH v5 23/58] perf python: Add LiveSession helper

sashiko-bot
2026-04-24T18:15:40Z

Sashiko AI review found 4 potential issue(s):
- [High] Unsupported events cause an inescapable infinite loop that starves the collection session.
- [High] The event reading loop fails to drain the CPU ring buffers, leading to excessive syscall overhead and dropped events.
- [Medium] A bare `except Exception: pass` block silently swallows all exceptions from the user-provided callback.
- [Medium] The loop silently discards `perf.RECORD_LOST` events, preventing the caller from detecting ring buffer overflows.
--

commit 8d1f04d2209b116868bc98675380c0d88ea3f54d
Author: Ian Rogers <irogers@google.com>

perf python: Add LiveSession helper

This commit adds a LiveSession class in tools/perf/python/perf_live.py to
support live event collection using perf.evlist and perf.parse_events. This
avoids the need to fork a separate perf record process.

> diff --git a/tools/perf/python/perf_live.py b/tools/perf/python/perf_live.py
> new file mode 100755
> index 00000000000000..d1dcbab1150b9d
> --- /dev/null
> +++ b/tools/perf/python/perf_live.py

[ ... ]

> + def run(self):
> + """Run the live session."""
> + self.evlist.open()
> + try:
> + self.evlist.mmap()
> + self.evlist.enable()
> +
> + while True:
> + # Poll for events with 100ms timeout
> + try:
> + self.evlist.poll(100)
> + except InterruptedError:
> + continue
> + for cpu in self.cpus:
> + try:
> + event = self.evlist.read_on_cpu(cpu)

If pyrf_evlist__read_on_cpu() encounters an unhandled event type like
PERF_RECORD_MMAP2, pyrf_event__new() returns NULL and sets a Python TypeError
before invoking perf_mmap__consume().

Because the event is never consumed, the ring buffer's tail pointer is not
advanced. The exception is then caught below, and on the next iteration poll()
returns immediately. Will this cause read_on_cpu() to read the exact same
unsupported event and lock the script in an infinite loop?

Also, since read_on_cpu() extracts only one event per call, does this loop
structure require invoking the poll() system call for every individual event?

If a burst of events occurs at high sampling frequencies, could this overhead
cause the script to lag and result in dropped events? Would it be better to
drain each CPU's queue completely before polling again?

> + if event and event.type == perf.RECORD_SAMPLE:
> + self.sample_callback(event)

By filtering strictly for perf.RECORD_SAMPLE, this loop silently drops
perf.RECORD_LOST events.

Could we add a mechanism to report lost samples or log a warning, so the
caller can detect when the kernel's perf ring buffer overflows?

> + except Exception:
> + pass

Will this generic exception handler silently discard errors originating from
the user-provided callback?

If a user introduces a typo or logic error in their callback, the error will
be hidden. Should exceptions from the callback be logged or allowed to
propagate to terminate the session?

> + except KeyboardInterrupt:
> + pass
> + finally:
> + self.evlist.close()

--
Sashiko AI review · https://sashiko.dev/#/patchset/20260424164721.2229025-1-irogers@google.com?part=23