]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
perf callchain: Add a for_each callback style API
authorIan Rogers <irogers@google.com>
Mon, 12 Aug 2024 22:41:19 +0000 (15:41 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 13 Aug 2024 18:28:19 +0000 (15:28 -0300)
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 <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Casey Chen <cachen@purestorage.com>
Cc: Colin Ian King <colin.i.king@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tom Zanussi <tzanussi@gmail.com>
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 <acme@redhat.com>
tools/perf/util/callchain.c
tools/perf/util/callchain.h

index 6d075648d2ccf43c464461547ba5562edb385a69..0d608e875fe96d39b1dc0602cd1a45a8a5ee3791 100644 (file)
@@ -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;
+}
index d5c66345ae313453efd55e687d5226b2eacc6f7f..76891f8e237303631f98223f4783471a40ae8179 100644 (file)
@@ -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 */