License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[linux-block.git] / tools / perf / util / callchain.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
8cb76d99 2/*
1b3a0e95 3 * Copyright (C) 2009-2011, Frederic Weisbecker <fweisbec@gmail.com>
8cb76d99
FW
4 *
5 * Handle the callchains from the stream in an ad-hoc radix tree and then
6 * sort them in an rbtree.
7 *
deac911c
FW
8 * Using a radix for code path provides a fast retrieval and factorizes
9 * memory use. Also that lets us use the paths in a hierarchical graph view.
10 *
8cb76d99
FW
11 */
12
fd20e811 13#include <inttypes.h>
8cb76d99
FW
14#include <stdlib.h>
15#include <stdio.h>
16#include <stdbool.h>
17#include <errno.h>
c0a8865e 18#include <math.h>
8cb76d99 19
b965bb41
FW
20#include "asm/bug.h"
21
99571ab3 22#include "hist.h"
b36f19d5 23#include "util.h"
2dc9fb1a
NK
24#include "sort.h"
25#include "machine.h"
8cb76d99 26#include "callchain.h"
b851dd49 27#include "branch.h"
8cb76d99 28
56e2e056
ACM
29#define CALLCHAIN_PARAM_DEFAULT \
30 .mode = CHAIN_GRAPH_ABS, \
31 .min_percent = 0.5, \
32 .order = ORDER_CALLEE, \
33 .key = CCKEY_FUNCTION, \
34 .value = CCVAL_PERCENT, \
35
36struct callchain_param callchain_param = {
37 CALLCHAIN_PARAM_DEFAULT
38};
39
40struct callchain_param callchain_param_default = {
41 CALLCHAIN_PARAM_DEFAULT
42};
43
47260645
NK
44__thread struct callchain_cursor callchain_cursor;
45
c3a6a8c4 46int parse_callchain_record_opt(const char *arg, struct callchain_param *param)
f7f084f4 47{
076a30c4 48 return parse_callchain_record(arg, param);
f7f084f4
NK
49}
50
2b9240ca
NK
51static int parse_callchain_mode(const char *value)
52{
53 if (!strncmp(value, "graph", strlen(value))) {
54 callchain_param.mode = CHAIN_GRAPH_ABS;
55 return 0;
56 }
57 if (!strncmp(value, "flat", strlen(value))) {
58 callchain_param.mode = CHAIN_FLAT;
59 return 0;
60 }
61 if (!strncmp(value, "fractal", strlen(value))) {
62 callchain_param.mode = CHAIN_GRAPH_REL;
63 return 0;
64 }
26e77924
NK
65 if (!strncmp(value, "folded", strlen(value))) {
66 callchain_param.mode = CHAIN_FOLDED;
67 return 0;
68 }
2b9240ca
NK
69 return -1;
70}
71
72static int parse_callchain_order(const char *value)
73{
74 if (!strncmp(value, "caller", strlen(value))) {
75 callchain_param.order = ORDER_CALLER;
792aeafa 76 callchain_param.order_set = true;
2b9240ca
NK
77 return 0;
78 }
79 if (!strncmp(value, "callee", strlen(value))) {
80 callchain_param.order = ORDER_CALLEE;
792aeafa 81 callchain_param.order_set = true;
2b9240ca
NK
82 return 0;
83 }
84 return -1;
85}
86
87static int parse_callchain_sort_key(const char *value)
88{
89 if (!strncmp(value, "function", strlen(value))) {
90 callchain_param.key = CCKEY_FUNCTION;
91 return 0;
92 }
93 if (!strncmp(value, "address", strlen(value))) {
94 callchain_param.key = CCKEY_ADDRESS;
95 return 0;
96 }
5dfa210e
MW
97 if (!strncmp(value, "srcline", strlen(value))) {
98 callchain_param.key = CCKEY_SRCLINE;
99 return 0;
100 }
8b7bad58
AK
101 if (!strncmp(value, "branch", strlen(value))) {
102 callchain_param.branch_callstack = 1;
103 return 0;
104 }
2b9240ca
NK
105 return -1;
106}
107
f2af0086
NK
108static int parse_callchain_value(const char *value)
109{
110 if (!strncmp(value, "percent", strlen(value))) {
111 callchain_param.value = CCVAL_PERCENT;
112 return 0;
113 }
114 if (!strncmp(value, "period", strlen(value))) {
115 callchain_param.value = CCVAL_PERIOD;
116 return 0;
117 }
118 if (!strncmp(value, "count", strlen(value))) {
119 callchain_param.value = CCVAL_COUNT;
120 return 0;
121 }
122 return -1;
123}
124
56e2e056
ACM
125static int get_stack_size(const char *str, unsigned long *_size)
126{
127 char *endptr;
128 unsigned long size;
129 unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
130
131 size = strtoul(str, &endptr, 0);
132
133 do {
134 if (*endptr)
135 break;
136
137 size = round_up(size, sizeof(u64));
138 if (!size || size > max_size)
139 break;
140
141 *_size = size;
142 return 0;
143
144 } while (0);
145
146 pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
147 max_size, str);
148 return -1;
149}
150
a2c10d39
NK
151static int
152__parse_callchain_report_opt(const char *arg, bool allow_record_opt)
cff6bb46 153{
e8232f1a 154 char *tok;
dadafc31 155 char *endptr, *saveptr = NULL;
e8232f1a 156 bool minpcnt_set = false;
a2c10d39
NK
157 bool record_opt_set = false;
158 bool try_stack_size = false;
cff6bb46 159
30234f09 160 callchain_param.enabled = true;
cff6bb46
DZ
161 symbol_conf.use_callchain = true;
162
163 if (!arg)
164 return 0;
165
dadafc31 166 while ((tok = strtok_r((char *)arg, ",", &saveptr)) != NULL) {
e8232f1a
NK
167 if (!strncmp(tok, "none", strlen(tok))) {
168 callchain_param.mode = CHAIN_NONE;
30234f09 169 callchain_param.enabled = false;
e8232f1a
NK
170 symbol_conf.use_callchain = false;
171 return 0;
172 }
173
2b9240ca
NK
174 if (!parse_callchain_mode(tok) ||
175 !parse_callchain_order(tok) ||
f2af0086
NK
176 !parse_callchain_sort_key(tok) ||
177 !parse_callchain_value(tok)) {
2b9240ca 178 /* parsing ok - move on to the next */
a2c10d39
NK
179 try_stack_size = false;
180 goto next;
181 } else if (allow_record_opt && !record_opt_set) {
182 if (parse_callchain_record(tok, &callchain_param))
183 goto try_numbers;
184
185 /* assume that number followed by 'dwarf' is stack size */
186 if (callchain_param.record_mode == CALLCHAIN_DWARF)
187 try_stack_size = true;
188
189 record_opt_set = true;
190 goto next;
191 }
192
193try_numbers:
194 if (try_stack_size) {
195 unsigned long size = 0;
196
197 if (get_stack_size(tok, &size) < 0)
198 return -1;
199 callchain_param.dump_size = size;
200 try_stack_size = false;
2b9240ca
NK
201 } else if (!minpcnt_set) {
202 /* try to get the min percent */
e8232f1a
NK
203 callchain_param.min_percent = strtod(tok, &endptr);
204 if (tok == endptr)
205 return -1;
206 minpcnt_set = true;
207 } else {
208 /* try print limit at last */
209 callchain_param.print_limit = strtoul(tok, &endptr, 0);
210 if (tok == endptr)
211 return -1;
212 }
a2c10d39 213next:
e8232f1a 214 arg = NULL;
cff6bb46
DZ
215 }
216
cff6bb46
DZ
217 if (callchain_register_param(&callchain_param) < 0) {
218 pr_err("Can't register callchain params\n");
219 return -1;
220 }
221 return 0;
222}
223
a2c10d39
NK
224int parse_callchain_report_opt(const char *arg)
225{
226 return __parse_callchain_report_opt(arg, false);
227}
228
229int parse_callchain_top_opt(const char *arg)
230{
231 return __parse_callchain_report_opt(arg, true);
232}
233
56e2e056
ACM
234int parse_callchain_record(const char *arg, struct callchain_param *param)
235{
236 char *tok, *name, *saveptr = NULL;
237 char *buf;
238 int ret = -1;
239
240 /* We need buffer that we know we can write to. */
241 buf = malloc(strlen(arg) + 1);
242 if (!buf)
243 return -ENOMEM;
244
245 strcpy(buf, arg);
246
247 tok = strtok_r((char *)buf, ",", &saveptr);
248 name = tok ? : (char *)buf;
249
250 do {
251 /* Framepointer style */
252 if (!strncmp(name, "fp", sizeof("fp"))) {
253 if (!strtok_r(NULL, ",", &saveptr)) {
254 param->record_mode = CALLCHAIN_FP;
255 ret = 0;
256 } else
257 pr_err("callchain: No more arguments "
258 "needed for --call-graph fp\n");
259 break;
260
261 /* Dwarf style */
262 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
263 const unsigned long default_stack_dump_size = 8192;
264
265 ret = 0;
266 param->record_mode = CALLCHAIN_DWARF;
267 param->dump_size = default_stack_dump_size;
268
269 tok = strtok_r(NULL, ",", &saveptr);
270 if (tok) {
271 unsigned long size = 0;
272
273 ret = get_stack_size(tok, &size);
274 param->dump_size = size;
275 }
276 } else if (!strncmp(name, "lbr", sizeof("lbr"))) {
277 if (!strtok_r(NULL, ",", &saveptr)) {
278 param->record_mode = CALLCHAIN_LBR;
279 ret = 0;
280 } else
281 pr_err("callchain: No more arguments "
282 "needed for --call-graph lbr\n");
283 break;
284 } else {
285 pr_err("callchain: Unknown --call-graph option "
286 "value: %s\n", arg);
287 break;
288 }
289
290 } while (0);
291
292 free(buf);
293 return ret;
294}
295
2b9240ca
NK
296int perf_callchain_config(const char *var, const char *value)
297{
298 char *endptr;
299
8e99b6d4 300 if (!strstarts(var, "call-graph."))
2b9240ca
NK
301 return 0;
302 var += sizeof("call-graph.") - 1;
303
304 if (!strcmp(var, "record-mode"))
c3a6a8c4 305 return parse_callchain_record_opt(value, &callchain_param);
2b9240ca
NK
306 if (!strcmp(var, "dump-size")) {
307 unsigned long size = 0;
308 int ret;
309
310 ret = get_stack_size(value, &size);
311 callchain_param.dump_size = size;
312
313 return ret;
314 }
9789e7e9
MZ
315 if (!strcmp(var, "print-type")){
316 int ret;
317 ret = parse_callchain_mode(value);
318 if (ret == -1)
319 pr_err("Invalid callchain mode: %s\n", value);
320 return ret;
321 }
322 if (!strcmp(var, "order")){
323 int ret;
324 ret = parse_callchain_order(value);
325 if (ret == -1)
326 pr_err("Invalid callchain order: %s\n", value);
327 return ret;
328 }
329 if (!strcmp(var, "sort-key")){
330 int ret;
331 ret = parse_callchain_sort_key(value);
332 if (ret == -1)
333 pr_err("Invalid callchain sort key: %s\n", value);
334 return ret;
335 }
2b9240ca
NK
336 if (!strcmp(var, "threshold")) {
337 callchain_param.min_percent = strtod(value, &endptr);
ecc4c561
ACM
338 if (value == endptr) {
339 pr_err("Invalid callchain threshold: %s\n", value);
2b9240ca 340 return -1;
ecc4c561 341 }
2b9240ca
NK
342 }
343 if (!strcmp(var, "print-limit")) {
344 callchain_param.print_limit = strtod(value, &endptr);
ecc4c561
ACM
345 if (value == endptr) {
346 pr_err("Invalid callchain print limit: %s\n", value);
2b9240ca 347 return -1;
ecc4c561 348 }
2b9240ca
NK
349 }
350
351 return 0;
352}
353
deac911c 354static void
4eb3e478
FW
355rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
356 enum chain_mode mode)
8cb76d99
FW
357{
358 struct rb_node **p = &root->rb_node;
359 struct rb_node *parent = NULL;
360 struct callchain_node *rnode;
f08c3154 361 u64 chain_cumul = callchain_cumul_hits(chain);
8cb76d99
FW
362
363 while (*p) {
1953287b
FW
364 u64 rnode_cumul;
365
8cb76d99
FW
366 parent = *p;
367 rnode = rb_entry(parent, struct callchain_node, rb_node);
f08c3154 368 rnode_cumul = callchain_cumul_hits(rnode);
8cb76d99 369
4eb3e478 370 switch (mode) {
805d127d 371 case CHAIN_FLAT:
26e77924 372 case CHAIN_FOLDED:
4eb3e478
FW
373 if (rnode->hit < chain->hit)
374 p = &(*p)->rb_left;
375 else
376 p = &(*p)->rb_right;
377 break;
805d127d
FW
378 case CHAIN_GRAPH_ABS: /* Falldown */
379 case CHAIN_GRAPH_REL:
1953287b 380 if (rnode_cumul < chain_cumul)
4eb3e478
FW
381 p = &(*p)->rb_left;
382 else
383 p = &(*p)->rb_right;
384 break;
83a0944f 385 case CHAIN_NONE:
4eb3e478
FW
386 default:
387 break;
388 }
8cb76d99
FW
389 }
390
391 rb_link_node(&chain->rb_node, parent, p);
392 rb_insert_color(&chain->rb_node, root);
393}
394
805d127d
FW
395static void
396__sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node,
397 u64 min_hit)
398{
e369517c 399 struct rb_node *n;
805d127d
FW
400 struct callchain_node *child;
401
e369517c
NK
402 n = rb_first(&node->rb_root_in);
403 while (n) {
404 child = rb_entry(n, struct callchain_node, rb_node_in);
405 n = rb_next(n);
406
805d127d 407 __sort_chain_flat(rb_root, child, min_hit);
e369517c 408 }
805d127d
FW
409
410 if (node->hit && node->hit >= min_hit)
411 rb_insert_callchain(rb_root, node, CHAIN_FLAT);
412}
413
8cb76d99
FW
414/*
415 * Once we get every callchains from the stream, we can now
416 * sort them by hit
417 */
805d127d 418static void
d2009c51 419sort_chain_flat(struct rb_root *rb_root, struct callchain_root *root,
1d037ca1 420 u64 min_hit, struct callchain_param *param __maybe_unused)
805d127d 421{
0356218a 422 *rb_root = RB_ROOT;
d2009c51 423 __sort_chain_flat(rb_root, &root->node, min_hit);
805d127d
FW
424}
425
426static void __sort_chain_graph_abs(struct callchain_node *node,
427 u64 min_hit)
8cb76d99 428{
e369517c 429 struct rb_node *n;
8cb76d99
FW
430 struct callchain_node *child;
431
805d127d 432 node->rb_root = RB_ROOT;
e369517c
NK
433 n = rb_first(&node->rb_root_in);
434
435 while (n) {
436 child = rb_entry(n, struct callchain_node, rb_node_in);
437 n = rb_next(n);
8cb76d99 438
805d127d 439 __sort_chain_graph_abs(child, min_hit);
f08c3154 440 if (callchain_cumul_hits(child) >= min_hit)
805d127d
FW
441 rb_insert_callchain(&node->rb_root, child,
442 CHAIN_GRAPH_ABS);
443 }
444}
445
446static void
d2009c51 447sort_chain_graph_abs(struct rb_root *rb_root, struct callchain_root *chain_root,
1d037ca1 448 u64 min_hit, struct callchain_param *param __maybe_unused)
805d127d 449{
d2009c51
FW
450 __sort_chain_graph_abs(&chain_root->node, min_hit);
451 rb_root->rb_node = chain_root->node.rb_root.rb_node;
4eb3e478
FW
452}
453
805d127d
FW
454static void __sort_chain_graph_rel(struct callchain_node *node,
455 double min_percent)
4eb3e478 456{
e369517c 457 struct rb_node *n;
4eb3e478 458 struct callchain_node *child;
805d127d 459 u64 min_hit;
4eb3e478
FW
460
461 node->rb_root = RB_ROOT;
c0a8865e 462 min_hit = ceil(node->children_hit * min_percent);
4eb3e478 463
e369517c
NK
464 n = rb_first(&node->rb_root_in);
465 while (n) {
466 child = rb_entry(n, struct callchain_node, rb_node_in);
467 n = rb_next(n);
468
805d127d 469 __sort_chain_graph_rel(child, min_percent);
f08c3154 470 if (callchain_cumul_hits(child) >= min_hit)
805d127d
FW
471 rb_insert_callchain(&node->rb_root, child,
472 CHAIN_GRAPH_REL);
4eb3e478
FW
473 }
474}
475
805d127d 476static void
d2009c51 477sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_root *chain_root,
1d037ca1 478 u64 min_hit __maybe_unused, struct callchain_param *param)
4eb3e478 479{
d2009c51
FW
480 __sort_chain_graph_rel(&chain_root->node, param->min_percent / 100.0);
481 rb_root->rb_node = chain_root->node.rb_root.rb_node;
8cb76d99
FW
482}
483
16537f13 484int callchain_register_param(struct callchain_param *param)
805d127d
FW
485{
486 switch (param->mode) {
487 case CHAIN_GRAPH_ABS:
488 param->sort = sort_chain_graph_abs;
489 break;
490 case CHAIN_GRAPH_REL:
491 param->sort = sort_chain_graph_rel;
492 break;
493 case CHAIN_FLAT:
26e77924 494 case CHAIN_FOLDED:
805d127d
FW
495 param->sort = sort_chain_flat;
496 break;
83a0944f 497 case CHAIN_NONE:
805d127d
FW
498 default:
499 return -1;
500 }
501 return 0;
502}
503
deac911c
FW
504/*
505 * Create a child for a parent. If inherit_children, then the new child
506 * will become the new parent of it's parent children
507 */
508static struct callchain_node *
509create_child(struct callchain_node *parent, bool inherit_children)
8cb76d99
FW
510{
511 struct callchain_node *new;
512
cdd5b75b 513 new = zalloc(sizeof(*new));
8cb76d99
FW
514 if (!new) {
515 perror("not enough memory to create child for code path tree");
516 return NULL;
517 }
518 new->parent = parent;
8cb76d99 519 INIT_LIST_HEAD(&new->val);
4b3a3212 520 INIT_LIST_HEAD(&new->parent_val);
deac911c
FW
521
522 if (inherit_children) {
e369517c
NK
523 struct rb_node *n;
524 struct callchain_node *child;
525
526 new->rb_root_in = parent->rb_root_in;
527 parent->rb_root_in = RB_ROOT;
deac911c 528
e369517c
NK
529 n = rb_first(&new->rb_root_in);
530 while (n) {
531 child = rb_entry(n, struct callchain_node, rb_node_in);
532 child->parent = new;
533 n = rb_next(n);
534 }
deac911c 535
e369517c
NK
536 /* make it the first child */
537 rb_link_node(&new->rb_node_in, NULL, &parent->rb_root_in.rb_node);
538 rb_insert_color(&new->rb_node_in, &parent->rb_root_in);
deac911c 539 }
8cb76d99
FW
540
541 return new;
542}
543
301fde27 544
deac911c
FW
545/*
546 * Fill the node with callchain values
547 */
8451cbb9 548static int
1b3a0e95 549fill_node(struct callchain_node *node, struct callchain_cursor *cursor)
8cb76d99 550{
1b3a0e95
FW
551 struct callchain_cursor_node *cursor_node;
552
553 node->val_nr = cursor->nr - cursor->pos;
554 if (!node->val_nr)
555 pr_warning("Warning: empty node in callchain tree\n");
8cb76d99 556
1b3a0e95
FW
557 cursor_node = callchain_cursor_current(cursor);
558
559 while (cursor_node) {
8cb76d99
FW
560 struct callchain_list *call;
561
cdd5b75b 562 call = zalloc(sizeof(*call));
8cb76d99
FW
563 if (!call) {
564 perror("not enough memory for the code path tree");
8451cbb9 565 return -1;
8cb76d99 566 }
1b3a0e95
FW
567 call->ip = cursor_node->ip;
568 call->ms.sym = cursor_node->sym;
9c68ae98 569 call->ms.map = map__get(cursor_node->map);
3dd029ef
JY
570
571 if (cursor_node->branch) {
572 call->branch_count = 1;
573
a1a8bed3
JY
574 if (cursor_node->branch_from) {
575 /*
576 * branch_from is set with value somewhere else
577 * to imply it's "to" of a branch.
578 */
579 call->brtype_stat.branch_to = true;
580
581 if (cursor_node->branch_flags.predicted)
582 call->predicted_count = 1;
583
584 if (cursor_node->branch_flags.abort)
585 call->abort_count = 1;
586
587 branch_type_count(&call->brtype_stat,
588 &cursor_node->branch_flags,
589 cursor_node->branch_from,
590 cursor_node->ip);
591 } else {
592 /*
593 * It's "from" of a branch
594 */
595 call->brtype_stat.branch_to = false;
596 call->cycles_count =
597 cursor_node->branch_flags.cycles;
598 call->iter_count = cursor_node->nr_loop_iter;
c4ee0625 599 call->iter_cycles = cursor_node->iter_cycles;
a1a8bed3 600 }
3dd029ef
JY
601 }
602
8cb76d99 603 list_add_tail(&call->list, &node->val);
1b3a0e95
FW
604
605 callchain_cursor_advance(cursor);
606 cursor_node = callchain_cursor_current(cursor);
8cb76d99 607 }
8451cbb9 608 return 0;
8cb76d99
FW
609}
610
e369517c 611static struct callchain_node *
1b3a0e95
FW
612add_child(struct callchain_node *parent,
613 struct callchain_cursor *cursor,
614 u64 period)
8cb76d99
FW
615{
616 struct callchain_node *new;
617
deac911c 618 new = create_child(parent, false);
7565bd39
NK
619 if (new == NULL)
620 return NULL;
621
8451cbb9
NK
622 if (fill_node(new, cursor) < 0) {
623 struct callchain_list *call, *tmp;
624
625 list_for_each_entry_safe(call, tmp, &new->val, list) {
626 list_del(&call->list);
9c68ae98 627 map__zput(call->ms.map);
8451cbb9
NK
628 free(call);
629 }
630 free(new);
631 return NULL;
632 }
8cb76d99 633
1953287b 634 new->children_hit = 0;
108553e1 635 new->hit = period;
5e47f8ff
NK
636 new->children_count = 0;
637 new->count = 1;
e369517c
NK
638 return new;
639}
640
2d713b80
NK
641enum match_result {
642 MATCH_ERROR = -1,
643 MATCH_EQ,
644 MATCH_LT,
645 MATCH_GT,
646};
647
5dfa210e
MW
648static enum match_result match_chain_srcline(struct callchain_cursor_node *node,
649 struct callchain_list *cnode)
650{
7d4df089
MW
651 char *left = NULL;
652 char *right = NULL;
653 enum match_result ret = MATCH_EQ;
654 int cmp;
655
656 if (cnode->ms.map)
657 left = get_srcline(cnode->ms.map->dso,
5dfa210e
MW
658 map__rip_2objdump(cnode->ms.map, cnode->ip),
659 cnode->ms.sym, true, false);
7d4df089
MW
660 if (node->map)
661 right = get_srcline(node->map->dso,
5dfa210e
MW
662 map__rip_2objdump(node->map, node->ip),
663 node->sym, true, false);
5dfa210e
MW
664
665 if (left && right)
666 cmp = strcmp(left, right);
667 else if (!left && right)
668 cmp = 1;
669 else if (left && !right)
670 cmp = -1;
671 else if (cnode->ip == node->ip)
672 cmp = 0;
673 else
674 cmp = (cnode->ip < node->ip) ? -1 : 1;
675
676 if (cmp != 0)
677 ret = cmp < 0 ? MATCH_LT : MATCH_GT;
678
679 free_srcline(left);
680 free_srcline(right);
681 return ret;
682}
683
2d713b80
NK
684static enum match_result match_chain(struct callchain_cursor_node *node,
685 struct callchain_list *cnode)
e369517c
NK
686{
687 struct symbol *sym = node->sym;
2d713b80 688 u64 left, right;
c1fbc0cf
RB
689 struct dso *left_dso = NULL;
690 struct dso *right_dso = NULL;
e369517c 691
5dfa210e
MW
692 if (callchain_param.key == CCKEY_SRCLINE) {
693 enum match_result match = match_chain_srcline(node, cnode);
694
695 if (match != MATCH_ERROR)
696 return match;
697 }
698
699 if (cnode->ms.sym && sym && callchain_param.key == CCKEY_FUNCTION) {
2d713b80
NK
700 left = cnode->ms.sym->start;
701 right = sym->start;
c1fbc0cf
RB
702 left_dso = cnode->ms.map->dso;
703 right_dso = node->map->dso;
2d713b80
NK
704 } else {
705 left = cnode->ip;
706 right = node->ip;
707 }
708
c1fbc0cf 709 if (left == right && left_dso == right_dso) {
3dd029ef
JY
710 if (node->branch) {
711 cnode->branch_count++;
712
a1a8bed3
JY
713 if (node->branch_from) {
714 /*
715 * It's "to" of a branch
716 */
717 cnode->brtype_stat.branch_to = true;
718
719 if (node->branch_flags.predicted)
720 cnode->predicted_count++;
721
722 if (node->branch_flags.abort)
723 cnode->abort_count++;
724
725 branch_type_count(&cnode->brtype_stat,
726 &node->branch_flags,
727 node->branch_from,
728 node->ip);
729 } else {
730 /*
731 * It's "from" of a branch
732 */
733 cnode->brtype_stat.branch_to = false;
734 cnode->cycles_count +=
735 node->branch_flags.cycles;
736 cnode->iter_count += node->nr_loop_iter;
c4ee0625 737 cnode->iter_cycles += node->iter_cycles;
a1a8bed3 738 }
3dd029ef
JY
739 }
740
2d713b80 741 return MATCH_EQ;
3dd029ef 742 }
2d713b80
NK
743
744 return left > right ? MATCH_GT : MATCH_LT;
8cb76d99
FW
745}
746
deac911c
FW
747/*
748 * Split the parent in two parts (a new child is created) and
749 * give a part of its callchain to the created child.
750 * Then create another child to host the given callchain of new branch
751 */
f2bb4c5a 752static int
1b3a0e95
FW
753split_add_child(struct callchain_node *parent,
754 struct callchain_cursor *cursor,
755 struct callchain_list *to_split,
756 u64 idx_parents, u64 idx_local, u64 period)
8cb76d99
FW
757{
758 struct callchain_node *new;
deac911c 759 struct list_head *old_tail;
f37a291c 760 unsigned int idx_total = idx_parents + idx_local;
8cb76d99
FW
761
762 /* split */
deac911c 763 new = create_child(parent, true);
f2bb4c5a
NK
764 if (new == NULL)
765 return -1;
deac911c
FW
766
767 /* split the callchain and move a part to the new child */
768 old_tail = parent->val.prev;
769 list_del_range(&to_split->list, old_tail);
770 new->val.next = &to_split->list;
771 new->val.prev = old_tail;
772 to_split->list.prev = &new->val;
773 old_tail->next = &new->val;
8cb76d99 774
deac911c
FW
775 /* split the hits */
776 new->hit = parent->hit;
1953287b 777 new->children_hit = parent->children_hit;
f08c3154 778 parent->children_hit = callchain_cumul_hits(new);
deac911c
FW
779 new->val_nr = parent->val_nr - idx_local;
780 parent->val_nr = idx_local;
5e47f8ff
NK
781 new->count = parent->count;
782 new->children_count = parent->children_count;
783 parent->children_count = callchain_cumul_counts(new);
deac911c
FW
784
785 /* create a new child for the new branch if any */
1b3a0e95 786 if (idx_total < cursor->nr) {
e369517c
NK
787 struct callchain_node *first;
788 struct callchain_list *cnode;
789 struct callchain_cursor_node *node;
790 struct rb_node *p, **pp;
791
deac911c 792 parent->hit = 0;
108553e1 793 parent->children_hit += period;
5e47f8ff
NK
794 parent->count = 0;
795 parent->children_count += 1;
e369517c
NK
796
797 node = callchain_cursor_current(cursor);
798 new = add_child(parent, cursor, period);
7565bd39 799 if (new == NULL)
f2bb4c5a 800 return -1;
e369517c
NK
801
802 /*
803 * This is second child since we moved parent's children
804 * to new (first) child above.
805 */
806 p = parent->rb_root_in.rb_node;
807 first = rb_entry(p, struct callchain_node, rb_node_in);
808 cnode = list_first_entry(&first->val, struct callchain_list,
809 list);
810
2d713b80 811 if (match_chain(node, cnode) == MATCH_LT)
e369517c
NK
812 pp = &p->rb_left;
813 else
814 pp = &p->rb_right;
815
816 rb_link_node(&new->rb_node_in, p, pp);
817 rb_insert_color(&new->rb_node_in, &parent->rb_root_in);
deac911c 818 } else {
108553e1 819 parent->hit = period;
5e47f8ff 820 parent->count = 1;
deac911c 821 }
f2bb4c5a 822 return 0;
8cb76d99
FW
823}
824
2d713b80 825static enum match_result
1b3a0e95
FW
826append_chain(struct callchain_node *root,
827 struct callchain_cursor *cursor,
828 u64 period);
8cb76d99 829
dca0d122 830static int
1b3a0e95
FW
831append_chain_children(struct callchain_node *root,
832 struct callchain_cursor *cursor,
833 u64 period)
8cb76d99
FW
834{
835 struct callchain_node *rnode;
e369517c
NK
836 struct callchain_cursor_node *node;
837 struct rb_node **p = &root->rb_root_in.rb_node;
838 struct rb_node *parent = NULL;
839
840 node = callchain_cursor_current(cursor);
841 if (!node)
dca0d122 842 return -1;
8cb76d99
FW
843
844 /* lookup in childrens */
e369517c 845 while (*p) {
2d713b80 846 enum match_result ret;
f37a291c 847
e369517c
NK
848 parent = *p;
849 rnode = rb_entry(parent, struct callchain_node, rb_node_in);
e369517c 850
b965bb41
FW
851 /* If at least first entry matches, rely to children */
852 ret = append_chain(rnode, cursor, period);
2d713b80 853 if (ret == MATCH_EQ)
1953287b 854 goto inc_children_hit;
dca0d122
NK
855 if (ret == MATCH_ERROR)
856 return -1;
e369517c 857
2d713b80 858 if (ret == MATCH_LT)
e369517c
NK
859 p = &parent->rb_left;
860 else
861 p = &parent->rb_right;
8cb76d99 862 }
deac911c 863 /* nothing in children, add to the current node */
e369517c 864 rnode = add_child(root, cursor, period);
7565bd39 865 if (rnode == NULL)
dca0d122 866 return -1;
7565bd39 867
e369517c
NK
868 rb_link_node(&rnode->rb_node_in, parent, p);
869 rb_insert_color(&rnode->rb_node_in, &root->rb_root_in);
e05b876c 870
1953287b 871inc_children_hit:
108553e1 872 root->children_hit += period;
5e47f8ff 873 root->children_count++;
dca0d122 874 return 0;
8cb76d99
FW
875}
876
2d713b80 877static enum match_result
1b3a0e95
FW
878append_chain(struct callchain_node *root,
879 struct callchain_cursor *cursor,
880 u64 period)
8cb76d99
FW
881{
882 struct callchain_list *cnode;
1b3a0e95 883 u64 start = cursor->pos;
8cb76d99 884 bool found = false;
1b3a0e95 885 u64 matches;
2d713b80 886 enum match_result cmp = MATCH_ERROR;
8cb76d99 887
deac911c
FW
888 /*
889 * Lookup in the current node
890 * If we have a symbol, then compare the start to match
99571ab3
AK
891 * anywhere inside a function, unless function
892 * mode is disabled.
deac911c 893 */
8cb76d99 894 list_for_each_entry(cnode, &root->val, list) {
1b3a0e95 895 struct callchain_cursor_node *node;
301fde27 896
1b3a0e95
FW
897 node = callchain_cursor_current(cursor);
898 if (!node)
deac911c 899 break;
301fde27 900
b965bb41 901 cmp = match_chain(node, cnode);
2d713b80 902 if (cmp != MATCH_EQ)
8cb76d99 903 break;
301fde27 904
e369517c 905 found = true;
1b3a0e95
FW
906
907 callchain_cursor_advance(cursor);
8cb76d99
FW
908 }
909
e369517c 910 /* matches not, relay no the parent */
1b3a0e95 911 if (!found) {
2d713b80 912 WARN_ONCE(cmp == MATCH_ERROR, "Chain comparison error\n");
b965bb41 913 return cmp;
1b3a0e95
FW
914 }
915
916 matches = cursor->pos - start;
8cb76d99
FW
917
918 /* we match only a part of the node. Split it and add the new chain */
1b3a0e95 919 if (matches < root->val_nr) {
f2bb4c5a
NK
920 if (split_add_child(root, cursor, cnode, start, matches,
921 period) < 0)
922 return MATCH_ERROR;
923
2d713b80 924 return MATCH_EQ;
8cb76d99
FW
925 }
926
927 /* we match 100% of the path, increment the hit */
1b3a0e95 928 if (matches == root->val_nr && cursor->pos == cursor->nr) {
108553e1 929 root->hit += period;
5e47f8ff 930 root->count++;
2d713b80 931 return MATCH_EQ;
8cb76d99
FW
932 }
933
deac911c 934 /* We match the node and still have a part remaining */
dca0d122
NK
935 if (append_chain_children(root, cursor, period) < 0)
936 return MATCH_ERROR;
deac911c 937
2d713b80 938 return MATCH_EQ;
8cb76d99
FW
939}
940
1b3a0e95
FW
941int callchain_append(struct callchain_root *root,
942 struct callchain_cursor *cursor,
943 u64 period)
8cb76d99 944{
1b3a0e95 945 if (!cursor->nr)
301fde27
FW
946 return 0;
947
1b3a0e95 948 callchain_cursor_commit(cursor);
301fde27 949
dca0d122
NK
950 if (append_chain_children(&root->node, cursor, period) < 0)
951 return -1;
d2009c51 952
1b3a0e95
FW
953 if (cursor->nr > root->max_depth)
954 root->max_depth = cursor->nr;
301fde27
FW
955
956 return 0;
8cb76d99 957}
612d4fd7
FW
958
959static int
1b3a0e95
FW
960merge_chain_branch(struct callchain_cursor *cursor,
961 struct callchain_node *dst, struct callchain_node *src)
612d4fd7 962{
1b3a0e95 963 struct callchain_cursor_node **old_last = cursor->last;
e369517c 964 struct callchain_node *child;
612d4fd7 965 struct callchain_list *list, *next_list;
e369517c 966 struct rb_node *n;
1b3a0e95 967 int old_pos = cursor->nr;
612d4fd7
FW
968 int err = 0;
969
970 list_for_each_entry_safe(list, next_list, &src->val, list) {
1b3a0e95 971 callchain_cursor_append(cursor, list->ip,
410024db 972 list->ms.map, list->ms.sym,
b851dd49 973 false, NULL, 0, 0, 0);
612d4fd7 974 list_del(&list->list);
9c68ae98 975 map__zput(list->ms.map);
612d4fd7
FW
976 free(list);
977 }
978
1b3a0e95
FW
979 if (src->hit) {
980 callchain_cursor_commit(cursor);
dca0d122
NK
981 if (append_chain_children(dst, cursor, src->hit) < 0)
982 return -1;
1b3a0e95 983 }
612d4fd7 984
e369517c
NK
985 n = rb_first(&src->rb_root_in);
986 while (n) {
987 child = container_of(n, struct callchain_node, rb_node_in);
988 n = rb_next(n);
989 rb_erase(&child->rb_node_in, &src->rb_root_in);
990
1b3a0e95 991 err = merge_chain_branch(cursor, dst, child);
612d4fd7
FW
992 if (err)
993 break;
994
612d4fd7
FW
995 free(child);
996 }
997
1b3a0e95
FW
998 cursor->nr = old_pos;
999 cursor->last = old_last;
612d4fd7
FW
1000
1001 return err;
1002}
1003
1b3a0e95
FW
1004int callchain_merge(struct callchain_cursor *cursor,
1005 struct callchain_root *dst, struct callchain_root *src)
1006{
1007 return merge_chain_branch(cursor, &dst->node, &src->node);
1008}
1009
1010int callchain_cursor_append(struct callchain_cursor *cursor,
410024db
JY
1011 u64 ip, struct map *map, struct symbol *sym,
1012 bool branch, struct branch_flags *flags,
c4ee0625 1013 int nr_loop_iter, u64 iter_cycles, u64 branch_from)
612d4fd7 1014{
1b3a0e95 1015 struct callchain_cursor_node *node = *cursor->last;
612d4fd7 1016
1b3a0e95 1017 if (!node) {
91b98804 1018 node = calloc(1, sizeof(*node));
1b3a0e95
FW
1019 if (!node)
1020 return -ENOMEM;
612d4fd7 1021
1b3a0e95
FW
1022 *cursor->last = node;
1023 }
612d4fd7 1024
1b3a0e95 1025 node->ip = ip;
9c68ae98
KJ
1026 map__zput(node->map);
1027 node->map = map__get(map);
1b3a0e95 1028 node->sym = sym;
410024db
JY
1029 node->branch = branch;
1030 node->nr_loop_iter = nr_loop_iter;
c4ee0625 1031 node->iter_cycles = iter_cycles;
410024db
JY
1032
1033 if (flags)
1034 memcpy(&node->branch_flags, flags,
1035 sizeof(struct branch_flags));
612d4fd7 1036
b851dd49 1037 node->branch_from = branch_from;
1b3a0e95 1038 cursor->nr++;
612d4fd7 1039
1b3a0e95
FW
1040 cursor->last = &node->next;
1041
1042 return 0;
612d4fd7 1043}
2dc9fb1a 1044
91d7b2de
ACM
1045int sample__resolve_callchain(struct perf_sample *sample,
1046 struct callchain_cursor *cursor, struct symbol **parent,
2dc9fb1a
NK
1047 struct perf_evsel *evsel, struct addr_location *al,
1048 int max_stack)
1049{
b49a821e 1050 if (sample->callchain == NULL && !symbol_conf.show_branchflag_count)
2dc9fb1a
NK
1051 return 0;
1052
7a13aa28 1053 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain ||
b49a821e 1054 perf_hpp_list.parent || symbol_conf.show_branchflag_count) {
91d7b2de 1055 return thread__resolve_callchain(al->thread, cursor, evsel, sample,
cc8b7c2b 1056 parent, al, max_stack);
2dc9fb1a
NK
1057 }
1058 return 0;
1059}
1060
1061int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample)
1062{
b49a821e
JY
1063 if ((!symbol_conf.use_callchain || sample->callchain == NULL) &&
1064 !symbol_conf.show_branchflag_count)
2dc9fb1a
NK
1065 return 0;
1066 return callchain_append(he->callchain, &callchain_cursor, sample->period);
1067}
c7405d85
NK
1068
1069int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node,
1070 bool hide_unresolved)
1071{
1072 al->map = node->map;
1073 al->sym = node->sym;
1074 if (node->map)
1075 al->addr = node->map->map_ip(node->map, node->ip);
1076 else
1077 al->addr = node->ip;
1078
1079 if (al->sym == NULL) {
1080 if (hide_unresolved)
1081 return 0;
1082 if (al->map == NULL)
1083 goto out;
1084 }
1085
1086 if (al->map->groups == &al->machine->kmaps) {
1087 if (machine__is_host(al->machine)) {
1088 al->cpumode = PERF_RECORD_MISC_KERNEL;
1089 al->level = 'k';
1090 } else {
1091 al->cpumode = PERF_RECORD_MISC_GUEST_KERNEL;
1092 al->level = 'g';
1093 }
1094 } else {
1095 if (machine__is_host(al->machine)) {
1096 al->cpumode = PERF_RECORD_MISC_USER;
1097 al->level = '.';
1098 } else if (perf_guest) {
1099 al->cpumode = PERF_RECORD_MISC_GUEST_USER;
1100 al->level = 'u';
1101 } else {
1102 al->cpumode = PERF_RECORD_MISC_HYPERVISOR;
1103 al->level = 'H';
1104 }
1105 }
1106
1107out:
1108 return 1;
1109}
2989ccaa
AK
1110
1111char *callchain_list__sym_name(struct callchain_list *cl,
1112 char *bf, size_t bfsize, bool show_dso)
1113{
5dfa210e
MW
1114 bool show_addr = callchain_param.key == CCKEY_ADDRESS;
1115 bool show_srcline = show_addr || callchain_param.key == CCKEY_SRCLINE;
2989ccaa
AK
1116 int printed;
1117
1118 if (cl->ms.sym) {
5dfa210e 1119 if (show_srcline && cl->ms.map && !cl->srcline)
23f0981b
AK
1120 cl->srcline = get_srcline(cl->ms.map->dso,
1121 map__rip_2objdump(cl->ms.map,
85c116a6 1122 cl->ip),
5dfa210e 1123 cl->ms.sym, false, show_addr);
23f0981b
AK
1124 if (cl->srcline)
1125 printed = scnprintf(bf, bfsize, "%s %s",
1126 cl->ms.sym->name, cl->srcline);
1127 else
1128 printed = scnprintf(bf, bfsize, "%s", cl->ms.sym->name);
2989ccaa
AK
1129 } else
1130 printed = scnprintf(bf, bfsize, "%#" PRIx64, cl->ip);
1131
1132 if (show_dso)
1133 scnprintf(bf + printed, bfsize - printed, " %s",
1134 cl->ms.map ?
1135 cl->ms.map->dso->short_name :
1136 "unknown");
1137
1138 return bf;
1139}
d114960c 1140
5ab250ca
NK
1141char *callchain_node__scnprintf_value(struct callchain_node *node,
1142 char *bf, size_t bfsize, u64 total)
1143{
1144 double percent = 0.0;
1145 u64 period = callchain_cumul_hits(node);
f2af0086 1146 unsigned count = callchain_cumul_counts(node);
5ab250ca 1147
f2af0086 1148 if (callchain_param.mode == CHAIN_FOLDED) {
5ab250ca 1149 period = node->hit;
f2af0086
NK
1150 count = node->count;
1151 }
5ab250ca 1152
f2af0086
NK
1153 switch (callchain_param.value) {
1154 case CCVAL_PERIOD:
1155 scnprintf(bf, bfsize, "%"PRIu64, period);
1156 break;
1157 case CCVAL_COUNT:
1158 scnprintf(bf, bfsize, "%u", count);
1159 break;
1160 case CCVAL_PERCENT:
1161 default:
1162 if (total)
1163 percent = period * 100.0 / total;
1164 scnprintf(bf, bfsize, "%.2f%%", percent);
1165 break;
1166 }
5ab250ca
NK
1167 return bf;
1168}
1169
1170int callchain_node__fprintf_value(struct callchain_node *node,
1171 FILE *fp, u64 total)
1172{
1173 double percent = 0.0;
1174 u64 period = callchain_cumul_hits(node);
f2af0086 1175 unsigned count = callchain_cumul_counts(node);
5ab250ca 1176
f2af0086 1177 if (callchain_param.mode == CHAIN_FOLDED) {
5ab250ca 1178 period = node->hit;
f2af0086
NK
1179 count = node->count;
1180 }
5ab250ca 1181
f2af0086
NK
1182 switch (callchain_param.value) {
1183 case CCVAL_PERIOD:
1184 return fprintf(fp, "%"PRIu64, period);
1185 case CCVAL_COUNT:
1186 return fprintf(fp, "%u", count);
1187 case CCVAL_PERCENT:
1188 default:
1189 if (total)
1190 percent = period * 100.0 / total;
1191 return percent_color_fprintf(fp, "%.2f%%", percent);
1192 }
1193 return 0;
5ab250ca
NK
1194}
1195
3dd029ef
JY
1196static void callchain_counts_value(struct callchain_node *node,
1197 u64 *branch_count, u64 *predicted_count,
1198 u64 *abort_count, u64 *cycles_count)
1199{
1200 struct callchain_list *clist;
1201
1202 list_for_each_entry(clist, &node->val, list) {
1203 if (branch_count)
1204 *branch_count += clist->branch_count;
1205
1206 if (predicted_count)
1207 *predicted_count += clist->predicted_count;
1208
1209 if (abort_count)
1210 *abort_count += clist->abort_count;
1211
1212 if (cycles_count)
1213 *cycles_count += clist->cycles_count;
1214 }
1215}
1216
1217static int callchain_node_branch_counts_cumul(struct callchain_node *node,
1218 u64 *branch_count,
1219 u64 *predicted_count,
1220 u64 *abort_count,
1221 u64 *cycles_count)
1222{
1223 struct callchain_node *child;
1224 struct rb_node *n;
1225
1226 n = rb_first(&node->rb_root_in);
1227 while (n) {
1228 child = rb_entry(n, struct callchain_node, rb_node_in);
1229 n = rb_next(n);
1230
1231 callchain_node_branch_counts_cumul(child, branch_count,
1232 predicted_count,
1233 abort_count,
1234 cycles_count);
1235
1236 callchain_counts_value(child, branch_count,
1237 predicted_count, abort_count,
1238 cycles_count);
1239 }
1240
1241 return 0;
1242}
1243
1244int callchain_branch_counts(struct callchain_root *root,
1245 u64 *branch_count, u64 *predicted_count,
1246 u64 *abort_count, u64 *cycles_count)
1247{
1248 if (branch_count)
1249 *branch_count = 0;
1250
1251 if (predicted_count)
1252 *predicted_count = 0;
1253
1254 if (abort_count)
1255 *abort_count = 0;
1256
1257 if (cycles_count)
1258 *cycles_count = 0;
1259
1260 return callchain_node_branch_counts_cumul(&root->node,
1261 branch_count,
1262 predicted_count,
1263 abort_count,
1264 cycles_count);
1265}
1266
8d51735f
JY
1267static int count_pri64_printf(int idx, const char *str, u64 value, char *bf, int bfsize)
1268{
1269 int printed;
1270
1271 printed = scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value);
1272
1273 return printed;
1274}
1275
a1a8bed3
JY
1276static int count_float_printf(int idx, const char *str, float value,
1277 char *bf, int bfsize, float threshold)
8d51735f
JY
1278{
1279 int printed;
1280
a1a8bed3
JY
1281 if (threshold != 0.0 && value < threshold)
1282 return 0;
1283
8d51735f
JY
1284 printed = scnprintf(bf, bfsize, "%s%s:%.1f%%", (idx) ? " " : " (", str, value);
1285
1286 return printed;
1287}
1288
a1a8bed3
JY
1289static int branch_to_str(char *bf, int bfsize,
1290 u64 branch_count, u64 predicted_count,
1291 u64 abort_count,
1292 struct branch_type_stat *brtype_stat)
3dd029ef 1293{
b851dd49 1294 int printed, i = 0;
3dd029ef 1295
b851dd49
JY
1296 printed = branch_type_str(brtype_stat, bf, bfsize);
1297 if (printed)
1298 i++;
1299
8d51735f
JY
1300 if (predicted_count < branch_count) {
1301 printed += count_float_printf(i++, "predicted",
1302 predicted_count * 100.0 / branch_count,
a1a8bed3 1303 bf + printed, bfsize - printed, 0.0);
8d51735f 1304 }
3dd029ef 1305
8d51735f
JY
1306 if (abort_count) {
1307 printed += count_float_printf(i++, "abort",
1308 abort_count * 100.0 / branch_count,
a1a8bed3 1309 bf + printed, bfsize - printed, 0.1);
c1dfcfad 1310 }
3dd029ef 1311
a1a8bed3
JY
1312 if (i)
1313 printed += scnprintf(bf + printed, bfsize - printed, ")");
1314
1315 return printed;
1316}
1317
1318static int branch_from_str(char *bf, int bfsize,
1319 u64 branch_count,
1320 u64 cycles_count, u64 iter_count,
c4ee0625 1321 u64 iter_cycles)
a1a8bed3
JY
1322{
1323 int printed = 0, i = 0;
1324 u64 cycles;
1325
8d51735f
JY
1326 cycles = cycles_count / branch_count;
1327 if (cycles) {
1328 printed += count_pri64_printf(i++, "cycles",
1329 cycles,
1330 bf + printed, bfsize - printed);
3dd029ef
JY
1331 }
1332
c4ee0625
JY
1333 if (iter_count) {
1334 printed += count_pri64_printf(i++, "iter",
1335 iter_count,
1336 bf + printed, bfsize - printed);
1337
1338 printed += count_pri64_printf(i++, "avg_cycles",
1339 iter_cycles / iter_count,
8d51735f 1340 bf + printed, bfsize - printed);
c1dfcfad 1341 }
3dd029ef 1342
8d51735f 1343 if (i)
a1a8bed3 1344 printed += scnprintf(bf + printed, bfsize - printed, ")");
c1dfcfad 1345
a1a8bed3
JY
1346 return printed;
1347}
1348
1349static int counts_str_build(char *bf, int bfsize,
1350 u64 branch_count, u64 predicted_count,
1351 u64 abort_count, u64 cycles_count,
c4ee0625 1352 u64 iter_count, u64 iter_cycles,
a1a8bed3
JY
1353 struct branch_type_stat *brtype_stat)
1354{
1355 int printed;
1356
1357 if (branch_count == 0)
1358 return scnprintf(bf, bfsize, " (calltrace)");
1359
1360 if (brtype_stat->branch_to) {
1361 printed = branch_to_str(bf, bfsize, branch_count,
1362 predicted_count, abort_count, brtype_stat);
1363 } else {
1364 printed = branch_from_str(bf, bfsize, branch_count,
c4ee0625 1365 cycles_count, iter_count, iter_cycles);
a1a8bed3
JY
1366 }
1367
1368 if (!printed)
1369 bf[0] = 0;
1370
1371 return printed;
c1dfcfad
JY
1372}
1373
1374static int callchain_counts_printf(FILE *fp, char *bf, int bfsize,
1375 u64 branch_count, u64 predicted_count,
1376 u64 abort_count, u64 cycles_count,
c4ee0625 1377 u64 iter_count, u64 iter_cycles,
b851dd49 1378 struct branch_type_stat *brtype_stat)
c1dfcfad 1379{
b851dd49 1380 char str[256];
c1dfcfad
JY
1381
1382 counts_str_build(str, sizeof(str), branch_count,
1383 predicted_count, abort_count, cycles_count,
c4ee0625 1384 iter_count, iter_cycles, brtype_stat);
3dd029ef
JY
1385
1386 if (fp)
c1dfcfad 1387 return fprintf(fp, "%s", str);
3dd029ef 1388
c1dfcfad 1389 return scnprintf(bf, bfsize, "%s", str);
3dd029ef
JY
1390}
1391
c4ee0625 1392int callchain_list_counts__printf_value(struct callchain_list *clist,
3dd029ef
JY
1393 FILE *fp, char *bf, int bfsize)
1394{
1395 u64 branch_count, predicted_count;
1396 u64 abort_count, cycles_count;
c4ee0625 1397 u64 iter_count, iter_cycles;
3dd029ef
JY
1398
1399 branch_count = clist->branch_count;
1400 predicted_count = clist->predicted_count;
1401 abort_count = clist->abort_count;
1402 cycles_count = clist->cycles_count;
c4ee0625
JY
1403 iter_count = clist->iter_count;
1404 iter_cycles = clist->iter_cycles;
3dd029ef
JY
1405
1406 return callchain_counts_printf(fp, bf, bfsize, branch_count,
1407 predicted_count, abort_count,
c4ee0625 1408 cycles_count, iter_count, iter_cycles,
b851dd49 1409 &clist->brtype_stat);
3dd029ef
JY
1410}
1411
d114960c
NK
1412static void free_callchain_node(struct callchain_node *node)
1413{
1414 struct callchain_list *list, *tmp;
1415 struct callchain_node *child;
1416 struct rb_node *n;
1417
4b3a3212
NK
1418 list_for_each_entry_safe(list, tmp, &node->parent_val, list) {
1419 list_del(&list->list);
9c68ae98 1420 map__zput(list->ms.map);
4b3a3212
NK
1421 free(list);
1422 }
1423
d114960c
NK
1424 list_for_each_entry_safe(list, tmp, &node->val, list) {
1425 list_del(&list->list);
9c68ae98 1426 map__zput(list->ms.map);
d114960c
NK
1427 free(list);
1428 }
1429
1430 n = rb_first(&node->rb_root_in);
1431 while (n) {
1432 child = container_of(n, struct callchain_node, rb_node_in);
1433 n = rb_next(n);
1434 rb_erase(&child->rb_node_in, &node->rb_root_in);
1435
1436 free_callchain_node(child);
1437 free(child);
1438 }
1439}
1440
1441void free_callchain(struct callchain_root *root)
1442{
1443 if (!symbol_conf.use_callchain)
1444 return;
1445
1446 free_callchain_node(&root->node);
1447}
4b3a3212 1448
42b276a2
NK
1449static u64 decay_callchain_node(struct callchain_node *node)
1450{
1451 struct callchain_node *child;
1452 struct rb_node *n;
1453 u64 child_hits = 0;
1454
1455 n = rb_first(&node->rb_root_in);
1456 while (n) {
1457 child = container_of(n, struct callchain_node, rb_node_in);
1458
1459 child_hits += decay_callchain_node(child);
1460 n = rb_next(n);
1461 }
1462
1463 node->hit = (node->hit * 7) / 8;
1464 node->children_hit = child_hits;
1465
1466 return node->hit;
1467}
1468
1469void decay_callchain(struct callchain_root *root)
1470{
1471 if (!symbol_conf.use_callchain)
1472 return;
1473
1474 decay_callchain_node(&root->node);
1475}
1476
4b3a3212
NK
1477int callchain_node__make_parent_list(struct callchain_node *node)
1478{
1479 struct callchain_node *parent = node->parent;
1480 struct callchain_list *chain, *new;
1481 LIST_HEAD(head);
1482
1483 while (parent) {
1484 list_for_each_entry_reverse(chain, &parent->val, list) {
1485 new = malloc(sizeof(*new));
1486 if (new == NULL)
1487 goto out;
1488 *new = *chain;
1489 new->has_children = false;
9c68ae98 1490 map__get(new->ms.map);
4b3a3212
NK
1491 list_add_tail(&new->list, &head);
1492 }
1493 parent = parent->parent;
1494 }
1495
1496 list_for_each_entry_safe_reverse(chain, new, &head, list)
1497 list_move_tail(&chain->list, &node->parent_val);
1498
1499 if (!list_empty(&node->parent_val)) {
1500 chain = list_first_entry(&node->parent_val, struct callchain_list, list);
1501 chain->has_children = rb_prev(&node->rb_node) || rb_next(&node->rb_node);
1502
1503 chain = list_first_entry(&node->val, struct callchain_list, list);
1504 chain->has_children = false;
1505 }
1506 return 0;
1507
1508out:
1509 list_for_each_entry_safe(chain, new, &head, list) {
1510 list_del(&chain->list);
9c68ae98 1511 map__zput(chain->ms.map);
4b3a3212
NK
1512 free(chain);
1513 }
1514 return -ENOMEM;
1515}
571f1eb9
NK
1516
1517int callchain_cursor__copy(struct callchain_cursor *dst,
1518 struct callchain_cursor *src)
1519{
1520 int rc = 0;
1521
1522 callchain_cursor_reset(dst);
1523 callchain_cursor_commit(src);
1524
1525 while (true) {
1526 struct callchain_cursor_node *node;
1527
1528 node = callchain_cursor_current(src);
1529 if (node == NULL)
1530 break;
1531
1532 rc = callchain_cursor_append(dst, node->ip, node->map, node->sym,
1533 node->branch, &node->branch_flags,
c4ee0625
JY
1534 node->nr_loop_iter,
1535 node->iter_cycles,
b851dd49 1536 node->branch_from);
571f1eb9
NK
1537 if (rc)
1538 break;
1539
1540 callchain_cursor_advance(src);
1541 }
1542
1543 return rc;
1544}