From 1a9d080d19c3303569614ed4c3b43a39aacd90d7 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 12 Aug 2024 15:41:19 -0700 Subject: [PATCH] perf callchain: Add a for_each callback style API Add a for_each callback style API to callchain with sample__for_each_callchain_node(). Possibly in the future such an API can avoid the overhead of constructing the call chain list. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Casey Chen Cc: Colin Ian King Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Mark Rutland Cc: Peter Zijlstra Cc: Tom Zanussi Link: https://lore.kernel.org/r/20240812224119.744968-1-irogers@google.com [ Split from a larger patch that introduced the API and use it ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/callchain.c | 35 +++++++++++++++++++++++++++++++++++ tools/perf/util/callchain.h | 6 ++++++ 2 files changed, 41 insertions(+) diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 6d075648d2cc..0d608e875fe9 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1797,3 +1797,38 @@ s64 callchain_avg_cycles(struct callchain_node *cnode) return cycles; } + +int sample__for_each_callchain_node(struct thread *thread, struct evsel *evsel, + struct perf_sample *sample, int max_stack, + callchain_iter_fn cb, void *data) +{ + struct callchain_cursor *cursor = get_tls_callchain_cursor(); + int ret; + + if (!cursor) + return -ENOMEM; + + /* Fill in the callchain. */ + ret = thread__resolve_callchain(thread, cursor, evsel, sample, + /*parent=*/NULL, /*root_al=*/NULL, + max_stack); + if (ret) + return ret; + + /* Switch from writing the callchain to reading it. */ + callchain_cursor_commit(cursor); + + while (1) { + struct callchain_cursor_node *node = callchain_cursor_current(cursor); + + if (!node) + break; + + ret = cb(node, data); + if (ret) + return ret; + + callchain_cursor_advance(cursor); + } + return 0; +} diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index d5c66345ae31..76891f8e2373 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -311,4 +311,10 @@ u64 callchain_total_hits(struct hists *hists); s64 callchain_avg_cycles(struct callchain_node *cnode); +typedef int (*callchain_iter_fn)(struct callchain_cursor_node *node, void *data); + +int sample__for_each_callchain_node(struct thread *thread, struct evsel *evsel, + struct perf_sample *sample, int max_stack, + callchain_iter_fn cb, void *data); + #endif /* __PERF_CALLCHAIN_H */ -- 2.50.1