summaryrefslogtreecommitdiff
path: root/tools/perf/python
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2026-06-15 18:15:43 -0700
committerNamhyung Kim <namhyung@kernel.org>2026-06-30 10:17:19 -0700
commit270e3f076b509c24d8cf69dde11db12d64706113 (patch)
treef38ba22403918d53fd0c686d35520d31f27440fa /tools/perf/python
parentfed8332b0e0ba9dec1729f0422f0b0d96f7893f2 (diff)
downloadlinux-270e3f076b509c24d8cf69dde11db12d64706113.tar.gz
linux-270e3f076b509c24d8cf69dde11db12d64706113.zip
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>
Diffstat (limited to 'tools/perf/python')
-rwxr-xr-xtools/perf/python/perf_live.py59
1 files changed, 59 insertions, 0 deletions
diff --git a/tools/perf/python/perf_live.py b/tools/perf/python/perf_live.py
new file mode 100755
index 000000000000..616b5f657463
--- /dev/null
+++ b/tools/perf/python/perf_live.py
@@ -0,0 +1,59 @@
+# 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()