Files
laptops-kernel/tools/perf/python/perf_live.py
Ian RogersandNamhyung Kim 270e3f076b perf python: Add LiveSession helper
Add LiveSession class in tools/perf/python/perf_live.py to support
live event collection using perf.evlist and perf.parse_events,
avoiding the need to fork a separate perf record process.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Gemini:gemini-3.1-pro-preview
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alice Rogers <alice.mei.rogers@gmail.com>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-06-30 10:17:19 -07:00

60 lines
2.0 KiB
Python
Executable File

# SPDX-License-Identifier: GPL-2.0
"""
Live event session helper using perf.evlist.
This module provides a LiveSession class that allows running a callback
for each event collected live from the system, similar to perf.session
but without requiring a perf.data file.
"""
import perf
class LiveSession:
"""Represents a live event collection session."""
def __init__(self, event_string: str, sample_callback):
self.event_string = event_string
self.sample_callback = sample_callback
# Create a cpu map for all online CPUs
self.cpus = perf.cpu_map()
# Parse events and set maps
self.evlist = perf.parse_events(self.event_string, self.cpus)
self.evlist.config()
def run(self):
"""Run the live session."""
try:
self.evlist.open()
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:
for _ in range(1000): # Limit to 1000 events per CPU per poll to prevent starvation
try:
event = self.evlist.read_on_cpu(cpu)
except TypeError as e:
if "Unknown CPU" in str(e):
# CPU might be unmapped or offline, wait for mmap event
break
if "Unexpected header type" in str(e):
# Ignore valid but unsupported event types
continue
raise
if event is None:
break
if event.type == perf.RECORD_SAMPLE:
self.sample_callback(event)
except KeyboardInterrupt:
pass
finally:
self.evlist.close()