root/tools/perf/util/callchain.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. callchain_init
  2. callchain_cumul_hits
  3. callchain_cumul_counts
  4. callchain_cursor_commit
  5. callchain_cursor_current
  6. callchain_cursor_advance
  7. callchain_cursor_snapshot
  8. arch_skip_callchain_idx

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #ifndef __PERF_CALLCHAIN_H
   3 #define __PERF_CALLCHAIN_H
   4 
   5 #include <linux/list.h>
   6 #include <linux/rbtree.h>
   7 #include "map_symbol.h"
   8 #include "branch.h"
   9 
  10 struct addr_location;
  11 struct evsel;
  12 struct ip_callchain;
  13 struct map;
  14 struct perf_sample;
  15 struct thread;
  16 
  17 #define HELP_PAD "\t\t\t\t"
  18 
  19 #define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace):\n\n"
  20 
  21 # define RECORD_MODE_HELP  HELP_PAD "record_mode:\tcall graph recording mode (fp|dwarf|lbr)\n"
  22 
  23 #define RECORD_SIZE_HELP                                                \
  24         HELP_PAD "record_size:\tif record_mode is 'dwarf', max size of stack recording (<bytes>)\n" \
  25         HELP_PAD "\t\tdefault: 8192 (bytes)\n"
  26 
  27 #define CALLCHAIN_RECORD_HELP  CALLCHAIN_HELP RECORD_MODE_HELP RECORD_SIZE_HELP
  28 
  29 #define CALLCHAIN_REPORT_HELP                                           \
  30         HELP_PAD "print_type:\tcall graph printing style (graph|flat|fractal|folded|none)\n" \
  31         HELP_PAD "threshold:\tminimum call graph inclusion threshold (<percent>)\n" \
  32         HELP_PAD "print_limit:\tmaximum number of call graph entry (<number>)\n" \
  33         HELP_PAD "order:\t\tcall graph order (caller|callee)\n" \
  34         HELP_PAD "sort_key:\tcall graph sort key (function|address)\n"  \
  35         HELP_PAD "branch:\t\tinclude last branch info to call graph (branch)\n" \
  36         HELP_PAD "value:\t\tcall graph value (percent|period|count)\n"
  37 
  38 enum perf_call_graph_mode {
  39         CALLCHAIN_NONE,
  40         CALLCHAIN_FP,
  41         CALLCHAIN_DWARF,
  42         CALLCHAIN_LBR,
  43         CALLCHAIN_MAX
  44 };
  45 
  46 enum chain_mode {
  47         CHAIN_NONE,
  48         CHAIN_FLAT,
  49         CHAIN_GRAPH_ABS,
  50         CHAIN_GRAPH_REL,
  51         CHAIN_FOLDED,
  52 };
  53 
  54 enum chain_order {
  55         ORDER_CALLER,
  56         ORDER_CALLEE
  57 };
  58 
  59 struct callchain_node {
  60         struct callchain_node   *parent;
  61         struct list_head        val;
  62         struct list_head        parent_val;
  63         struct rb_node          rb_node_in; /* to insert nodes in an rbtree */
  64         struct rb_node          rb_node;    /* to sort nodes in an output tree */
  65         struct rb_root          rb_root_in; /* input tree of children */
  66         struct rb_root          rb_root;    /* sorted output tree of children */
  67         unsigned int            val_nr;
  68         unsigned int            count;
  69         unsigned int            children_count;
  70         u64                     hit;
  71         u64                     children_hit;
  72 };
  73 
  74 struct callchain_root {
  75         u64                     max_depth;
  76         struct callchain_node   node;
  77 };
  78 
  79 struct callchain_param;
  80 
  81 typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_root *,
  82                                  u64, struct callchain_param *);
  83 
  84 enum chain_key {
  85         CCKEY_FUNCTION,
  86         CCKEY_ADDRESS,
  87         CCKEY_SRCLINE
  88 };
  89 
  90 enum chain_value {
  91         CCVAL_PERCENT,
  92         CCVAL_PERIOD,
  93         CCVAL_COUNT,
  94 };
  95 
  96 extern bool dwarf_callchain_users;
  97 
  98 struct callchain_param {
  99         bool                    enabled;
 100         enum perf_call_graph_mode record_mode;
 101         u32                     dump_size;
 102         enum chain_mode         mode;
 103         u16                     max_stack;
 104         u32                     print_limit;
 105         double                  min_percent;
 106         sort_chain_func_t       sort;
 107         enum chain_order        order;
 108         bool                    order_set;
 109         enum chain_key          key;
 110         bool                    branch_callstack;
 111         enum chain_value        value;
 112 };
 113 
 114 extern struct callchain_param callchain_param;
 115 extern struct callchain_param callchain_param_default;
 116 
 117 struct callchain_list {
 118         u64                     ip;
 119         struct map_symbol       ms;
 120         struct /* for TUI */ {
 121                 bool            unfolded;
 122                 bool            has_children;
 123         };
 124         u64                     branch_count;
 125         u64                     from_count;
 126         u64                     predicted_count;
 127         u64                     abort_count;
 128         u64                     cycles_count;
 129         u64                     iter_count;
 130         u64                     iter_cycles;
 131         struct branch_type_stat brtype_stat;
 132         const char              *srcline;
 133         struct list_head        list;
 134 };
 135 
 136 /*
 137  * A callchain cursor is a single linked list that
 138  * let one feed a callchain progressively.
 139  * It keeps persistent allocated entries to minimize
 140  * allocations.
 141  */
 142 struct callchain_cursor_node {
 143         u64                             ip;
 144         struct map                      *map;
 145         struct symbol                   *sym;
 146         const char                      *srcline;
 147         bool                            branch;
 148         struct branch_flags             branch_flags;
 149         u64                             branch_from;
 150         int                             nr_loop_iter;
 151         u64                             iter_cycles;
 152         struct callchain_cursor_node    *next;
 153 };
 154 
 155 struct callchain_cursor {
 156         u64                             nr;
 157         struct callchain_cursor_node    *first;
 158         struct callchain_cursor_node    **last;
 159         u64                             pos;
 160         struct callchain_cursor_node    *curr;
 161 };
 162 
 163 extern __thread struct callchain_cursor callchain_cursor;
 164 
 165 static inline void callchain_init(struct callchain_root *root)
 166 {
 167         INIT_LIST_HEAD(&root->node.val);
 168         INIT_LIST_HEAD(&root->node.parent_val);
 169 
 170         root->node.parent = NULL;
 171         root->node.hit = 0;
 172         root->node.children_hit = 0;
 173         root->node.rb_root_in = RB_ROOT;
 174         root->max_depth = 0;
 175 }
 176 
 177 static inline u64 callchain_cumul_hits(struct callchain_node *node)
 178 {
 179         return node->hit + node->children_hit;
 180 }
 181 
 182 static inline unsigned callchain_cumul_counts(struct callchain_node *node)
 183 {
 184         return node->count + node->children_count;
 185 }
 186 
 187 int callchain_register_param(struct callchain_param *param);
 188 int callchain_append(struct callchain_root *root,
 189                      struct callchain_cursor *cursor,
 190                      u64 period);
 191 
 192 int callchain_merge(struct callchain_cursor *cursor,
 193                     struct callchain_root *dst, struct callchain_root *src);
 194 
 195 void callchain_cursor_reset(struct callchain_cursor *cursor);
 196 
 197 int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
 198                             struct map *map, struct symbol *sym,
 199                             bool branch, struct branch_flags *flags,
 200                             int nr_loop_iter, u64 iter_cycles, u64 branch_from,
 201                             const char *srcline);
 202 
 203 /* Close a cursor writing session. Initialize for the reader */
 204 static inline void callchain_cursor_commit(struct callchain_cursor *cursor)
 205 {
 206         cursor->curr = cursor->first;
 207         cursor->pos = 0;
 208 }
 209 
 210 /* Cursor reading iteration helpers */
 211 static inline struct callchain_cursor_node *
 212 callchain_cursor_current(struct callchain_cursor *cursor)
 213 {
 214         if (cursor->pos == cursor->nr)
 215                 return NULL;
 216 
 217         return cursor->curr;
 218 }
 219 
 220 static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
 221 {
 222         cursor->curr = cursor->curr->next;
 223         cursor->pos++;
 224 }
 225 
 226 int callchain_cursor__copy(struct callchain_cursor *dst,
 227                            struct callchain_cursor *src);
 228 
 229 struct option;
 230 struct hist_entry;
 231 
 232 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
 233 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
 234 
 235 struct record_opts;
 236 
 237 int record_opts__parse_callchain(struct record_opts *record,
 238                                  struct callchain_param *callchain,
 239                                  const char *arg, bool unset);
 240 
 241 int sample__resolve_callchain(struct perf_sample *sample,
 242                               struct callchain_cursor *cursor, struct symbol **parent,
 243                               struct evsel *evsel, struct addr_location *al,
 244                               int max_stack);
 245 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample);
 246 int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node,
 247                         bool hide_unresolved);
 248 
 249 extern const char record_callchain_help[];
 250 int parse_callchain_record(const char *arg, struct callchain_param *param);
 251 int parse_callchain_record_opt(const char *arg, struct callchain_param *param);
 252 int parse_callchain_report_opt(const char *arg);
 253 int parse_callchain_top_opt(const char *arg);
 254 int perf_callchain_config(const char *var, const char *value);
 255 
 256 static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
 257                                              struct callchain_cursor *src)
 258 {
 259         *dest = *src;
 260 
 261         dest->first = src->curr;
 262         dest->nr -= src->pos;
 263 }
 264 
 265 #ifdef HAVE_SKIP_CALLCHAIN_IDX
 266 int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain);
 267 #else
 268 static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused,
 269                         struct ip_callchain *chain __maybe_unused)
 270 {
 271         return -1;
 272 }
 273 #endif
 274 
 275 char *callchain_list__sym_name(struct callchain_list *cl,
 276                                char *bf, size_t bfsize, bool show_dso);
 277 char *callchain_node__scnprintf_value(struct callchain_node *node,
 278                                       char *bf, size_t bfsize, u64 total);
 279 int callchain_node__fprintf_value(struct callchain_node *node,
 280                                   FILE *fp, u64 total);
 281 
 282 int callchain_list_counts__printf_value(struct callchain_list *clist,
 283                                         FILE *fp, char *bf, int bfsize);
 284 
 285 void free_callchain(struct callchain_root *root);
 286 void decay_callchain(struct callchain_root *root);
 287 int callchain_node__make_parent_list(struct callchain_node *node);
 288 
 289 int callchain_branch_counts(struct callchain_root *root,
 290                             u64 *branch_count, u64 *predicted_count,
 291                             u64 *abort_count, u64 *cycles_count);
 292 
 293 #endif  /* __PERF_CALLCHAIN_H */

/* [<][>][^][v][top][bottom][index][help] */