Thread (10 messages) 10 messages, 1 author, 7d ago
COOLING7d

[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

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help