diff options
Diffstat (limited to 'tools/perf/util/callchain.h')
| -rw-r--r-- | tools/perf/util/callchain.h | 104 |
1 files changed, 67 insertions, 37 deletions
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index c56c23dbbf72..2a52af8c80ac 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -1,12 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_CALLCHAIN_H #define __PERF_CALLCHAIN_H -#include "../perf.h" #include <linux/list.h> #include <linux/rbtree.h> -#include "event.h" -#include "map.h" -#include "symbol.h" +#include "map_symbol.h" +#include "branch.h" + +struct addr_location; +struct evsel; +struct ip_callchain; +struct map; +struct perf_sample; +struct thread; +struct hists; #define HELP_PAD "\t\t\t\t" @@ -87,8 +94,11 @@ enum chain_value { CCVAL_COUNT, }; +extern bool dwarf_callchain_users; + struct callchain_param { bool enabled; + bool defer; enum perf_call_graph_mode record_mode; u32 dump_size; enum chain_mode mode; @@ -107,20 +117,22 @@ extern struct callchain_param callchain_param; extern struct callchain_param callchain_param_default; struct callchain_list { + struct list_head list; u64 ip; struct map_symbol ms; + const char *srcline; + u64 branch_count; + u64 from_count; + u64 cycles_count; + u64 iter_count; + u64 iter_cycles; + struct branch_type_stat *brtype_stat; + u64 predicted_count; + u64 abort_count; struct /* for TUI */ { bool unfolded; bool has_children; }; - u64 branch_count; - u64 predicted_count; - u64 abort_count; - u64 cycles_count; - u64 iter_count; - u64 samples_count; - char *srcline; - struct list_head list; }; /* @@ -131,15 +143,24 @@ struct callchain_list { */ struct callchain_cursor_node { u64 ip; - struct map *map; - struct symbol *sym; + struct map_symbol ms; + const char *srcline; + /* Indicate valid cursor node for LBR stitch */ + bool valid; + bool branch; struct branch_flags branch_flags; + u64 branch_from; int nr_loop_iter; - int samples; + u64 iter_cycles; struct callchain_cursor_node *next; }; +struct stitch_list { + struct list_head node; + struct callchain_cursor_node cursor; +}; + struct callchain_cursor { u64 nr; struct callchain_cursor_node *first; @@ -148,8 +169,6 @@ struct callchain_cursor { struct callchain_cursor_node *curr; }; -extern __thread struct callchain_cursor callchain_cursor; - static inline void callchain_init(struct callchain_root *root) { INIT_LIST_HEAD(&root->node.val); @@ -180,29 +199,19 @@ int callchain_append(struct callchain_root *root, int callchain_merge(struct callchain_cursor *cursor, struct callchain_root *dst, struct callchain_root *src); -/* - * Initialize a cursor before adding entries inside, but keep - * the previously allocated entries as a cache. - */ -static inline void callchain_cursor_reset(struct callchain_cursor *cursor) -{ - struct callchain_cursor_node *node; - - cursor->nr = 0; - cursor->last = &cursor->first; - - for (node = cursor->first; node != NULL; node = node->next) - map__zput(node->map); -} +void callchain_cursor_reset(struct callchain_cursor *cursor); int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip, - struct map *map, struct symbol *sym, + struct map_symbol *ms, bool branch, struct branch_flags *flags, - int nr_loop_iter, int samples); + int nr_loop_iter, u64 iter_cycles, u64 branch_from, + const char *srcline); /* Close a cursor writing session. Initialize for the reader */ static inline void callchain_cursor_commit(struct callchain_cursor *cursor) { + if (cursor == NULL) + return; cursor->curr = cursor->first; cursor->pos = 0; } @@ -211,7 +220,7 @@ static inline void callchain_cursor_commit(struct callchain_cursor *cursor) static inline struct callchain_cursor_node * callchain_cursor_current(struct callchain_cursor *cursor) { - if (cursor->pos == cursor->nr) + if (cursor == NULL || cursor->pos == cursor->nr) return NULL; return cursor->curr; @@ -223,6 +232,8 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor) cursor->pos++; } +struct callchain_cursor *get_tls_callchain_cursor(void); + int callchain_cursor__copy(struct callchain_cursor *dst, struct callchain_cursor *src); @@ -240,7 +251,7 @@ int record_opts__parse_callchain(struct record_opts *record, int sample__resolve_callchain(struct perf_sample *sample, struct callchain_cursor *cursor, struct symbol **parent, - struct perf_evsel *evsel, struct addr_location *al, + struct evsel *evsel, struct addr_location *al, int max_stack); int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample); int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node, @@ -272,6 +283,8 @@ static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused, } #endif +void arch__add_leaf_frame_record_opts(struct record_opts *opts); + char *callchain_list__sym_name(struct callchain_list *cl, char *bf, size_t bfsize, bool show_dso); char *callchain_node__scnprintf_value(struct callchain_node *node, @@ -279,8 +292,7 @@ char *callchain_node__scnprintf_value(struct callchain_node *node, int callchain_node__fprintf_value(struct callchain_node *node, FILE *fp, u64 total); -int callchain_list_counts__printf_value(struct callchain_node *node, - struct callchain_list *clist, +int callchain_list_counts__printf_value(struct callchain_list *clist, FILE *fp, char *bf, int bfsize); void free_callchain(struct callchain_root *root); @@ -291,4 +303,22 @@ int callchain_branch_counts(struct callchain_root *root, u64 *branch_count, u64 *predicted_count, u64 *abort_count, u64 *cycles_count); +void callchain_param_setup(u64 sample_type, const char *arch); + +bool callchain_cnode_matched(struct callchain_node *base_cnode, + struct callchain_node *pair_cnode); + +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, + bool symbols, callchain_iter_fn cb, void *data); + +int sample__merge_deferred_callchain(struct perf_sample *sample_orig, + struct perf_sample *sample_callchain); + #endif /* __PERF_CALLCHAIN_H */ |
