[PATCH 3/9] tools/perf: Add arch_record__collect_final_data to collect additional data before closing the event
From: Athira Rajeev <hidden>
Date: 2026-07-01 08:41:42
Also in:
linux-perf-users
Subsystem:
performance events subsystem, the rest · Maintainers:
Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Linus Torvalds
While collecting samples using "perf record", function "__cmd_record" checks if monitoring is done. Once recording is done, event list will be disabled using "evlist__disable". After this, event fd won't be read and event will be removed. Before removing the event, if any additional data needs to be captured/written to perf.data, currently its not possible. Introduce arch_record__collect_final_data to collect additional data before closing the event Signed-off-by: Athira Rajeev <redacted> --- tools/perf/builtin-record.c | 29 +++++++++++++++++++++++++++++ tools/perf/util/record.h | 4 ++++ 2 files changed, 33 insertions(+)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index ebd3ed0c9b3e..1312f7223455 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c@@ -2426,6 +2426,34 @@ static unsigned long record__waking(struct record *rec) return waking; } +/* + * Weak symbol - architecture can override to indicate if more + * data needs to be collected before finishing output. + * + * Returns: 1 if more data exists, 0 if collection is complete + */ +__weak int arch_perf_record__need_read(struct evlist *evlist __maybe_unused) +{ + return 0; /* Default: no arch-specific data to collect */ +} + +static void record__final_data(struct record *rec) +{ + /* + * Collect any remaining architecture-specific data. + * The arch code checks if more data exists, and we do the actual + * reading here since we have access to record__mmap_read_all(). + */ + while (arch_perf_record__need_read(rec->evlist)) { + if (record__mmap_read_all(rec, false) < 0) + break; + /* Re-enable events for next batch */ + evlist__enable(rec->evlist); + } + + return; +} + static int __cmd_record(struct record *rec, int argc, const char **argv) { int err;
@@ -2853,6 +2881,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) */ if (done && !disabled && !target__none(&opts->target)) { trigger_off(&auxtrace_snapshot_trigger); + record__final_data(rec); evlist__disable(rec->evlist); disabled = true; }
diff --git a/tools/perf/util/record.h b/tools/perf/util/record.h
index 93627c9a7338..21f51efd36fc 100644
--- a/tools/perf/util/record.h
+++ b/tools/perf/util/record.h@@ -8,6 +8,8 @@ #include <linux/stddef.h> #include <linux/perf_event.h> #include "util/target.h" +#include "util/evlist.h" +#include "util/util.h" struct option;
@@ -95,4 +97,6 @@ static inline bool record_opts__no_switch_events(const struct record_opts *opts) return opts->record_switch_events_set && !opts->record_switch_events; } +int arch_perf_record__need_read(struct evlist *evlist); + #endif // _PERF_RECORD_H
--
2.52.0