1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2009-2011, Frederic Weisbecker <fweisbec@gmail.com> 4 * 5 * Handle the callchains from the stream in an ad-hoc radix tree and then 6 * sort them in an rbtree. 7 * 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 * 11 */ 12 13 #include <inttypes.h> 14 #include <stdlib.h> 15 #include <stdio.h> 16 #include <stdbool.h> 17 #include <errno.h> 18 #include <math.h> 19 20 #include "asm/bug.h" 21 22 #include "hist.h" 23 #include "util.h" 24 #include "sort.h" 25 #include "machine.h" 26 #include "callchain.h" 27 #include "branch.h" 28 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 36 struct callchain_param callchain_param = { 37 CALLCHAIN_PARAM_DEFAULT 38 }; 39 40 struct callchain_param callchain_param_default = { 41 CALLCHAIN_PARAM_DEFAULT 42 }; 43 44 __thread struct callchain_cursor callchain_cursor; 45 46 int parse_callchain_record_opt(const char *arg, struct callchain_param *param) 47 { 48 return parse_callchain_record(arg, param); 49 } 50 51 static 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 } 65 if (!strncmp(value, "folded", strlen(value))) { 66 callchain_param.mode = CHAIN_FOLDED; 67 return 0; 68 } 69 return -1; 70 } 71 72 static int parse_callchain_order(const char *value) 73 { 74 if (!strncmp(value, "caller", strlen(value))) { 75 callchain_param.order = ORDER_CALLER; 76 callchain_param.order_set = true; 77 return 0; 78 } 79 if (!strncmp(value, "callee", strlen(value))) { 80 callchain_param.order = ORDER_CALLEE; 81 callchain_param.order_set = true; 82 return 0; 83 } 84 return -1; 85 } 86 87 static 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 } 97 if (!strncmp(value, "srcline", strlen(value))) { 98 callchain_param.key = CCKEY_SRCLINE; 99 return 0; 100 } 101 if (!strncmp(value, "branch", strlen(value))) { 102 callchain_param.branch_callstack = 1; 103 return 0; 104 } 105 return -1; 106 } 107 108 static 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 125 static 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 151 static int 152 __parse_callchain_report_opt(const char *arg, bool allow_record_opt) 153 { 154 char *tok; 155 char *endptr, *saveptr = NULL; 156 bool minpcnt_set = false; 157 bool record_opt_set = false; 158 bool try_stack_size = false; 159 160 callchain_param.enabled = true; 161 symbol_conf.use_callchain = true; 162 163 if (!arg) 164 return 0; 165 166 while ((tok = strtok_r((char *)arg, ",", &saveptr)) != NULL) { 167 if (!strncmp(tok, "none", strlen(tok))) { 168 callchain_param.mode = CHAIN_NONE; 169 callchain_param.enabled = false; 170 symbol_conf.use_callchain = false; 171 return 0; 172 } 173 174 if (!parse_callchain_mode(tok) || 175 !parse_callchain_order(tok) || 176 !parse_callchain_sort_key(tok) || 177 !parse_callchain_value(tok)) { 178 /* parsing ok - move on to the next */ 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 193 try_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; 201 } else if (!minpcnt_set) { 202 /* try to get the min percent */ 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 } 213 next: 214 arg = NULL; 215 } 216 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 224 int parse_callchain_report_opt(const char *arg) 225 { 226 return __parse_callchain_report_opt(arg, false); 227 } 228 229 int parse_callchain_top_opt(const char *arg) 230 { 231 return __parse_callchain_report_opt(arg, true); 232 } 233 234 int 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 296 int perf_callchain_config(const char *var, const char *value) 297 { 298 char *endptr; 299 300 if (!strstarts(var, "call-graph.")) 301 return 0; 302 var += sizeof("call-graph.") - 1; 303 304 if (!strcmp(var, "record-mode")) 305 return parse_callchain_record_opt(value, &callchain_param); 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 } 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 } 336 if (!strcmp(var, "threshold")) { 337 callchain_param.min_percent = strtod(value, &endptr); 338 if (value == endptr) { 339 pr_err("Invalid callchain threshold: %s\n", value); 340 return -1; 341 } 342 } 343 if (!strcmp(var, "print-limit")) { 344 callchain_param.print_limit = strtod(value, &endptr); 345 if (value == endptr) { 346 pr_err("Invalid callchain print limit: %s\n", value); 347 return -1; 348 } 349 } 350 351 return 0; 352 } 353 354 static void 355 rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, 356 enum chain_mode mode) 357 { 358 struct rb_node **p = &root->rb_node; 359 struct rb_node *parent = NULL; 360 struct callchain_node *rnode; 361 u64 chain_cumul = callchain_cumul_hits(chain); 362 363 while (*p) { 364 u64 rnode_cumul; 365 366 parent = *p; 367 rnode = rb_entry(parent, struct callchain_node, rb_node); 368 rnode_cumul = callchain_cumul_hits(rnode); 369 370 switch (mode) { 371 case CHAIN_FLAT: 372 case CHAIN_FOLDED: 373 if (rnode->hit < chain->hit) 374 p = &(*p)->rb_left; 375 else 376 p = &(*p)->rb_right; 377 break; 378 case CHAIN_GRAPH_ABS: /* Falldown */ 379 case CHAIN_GRAPH_REL: 380 if (rnode_cumul < chain_cumul) 381 p = &(*p)->rb_left; 382 else 383 p = &(*p)->rb_right; 384 break; 385 case CHAIN_NONE: 386 default: 387 break; 388 } 389 } 390 391 rb_link_node(&chain->rb_node, parent, p); 392 rb_insert_color(&chain->rb_node, root); 393 } 394 395 static void 396 __sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node, 397 u64 min_hit) 398 { 399 struct rb_node *n; 400 struct callchain_node *child; 401 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 407 __sort_chain_flat(rb_root, child, min_hit); 408 } 409 410 if (node->hit && node->hit >= min_hit) 411 rb_insert_callchain(rb_root, node, CHAIN_FLAT); 412 } 413 414 /* 415 * Once we get every callchains from the stream, we can now 416 * sort them by hit 417 */ 418 static void 419 sort_chain_flat(struct rb_root *rb_root, struct callchain_root *root, 420 u64 min_hit, struct callchain_param *param __maybe_unused) 421 { 422 *rb_root = RB_ROOT; 423 __sort_chain_flat(rb_root, &root->node, min_hit); 424 } 425 426 static void __sort_chain_graph_abs(struct callchain_node *node, 427 u64 min_hit) 428 { 429 struct rb_node *n; 430 struct callchain_node *child; 431 432 node->rb_root = RB_ROOT; 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); 438 439 __sort_chain_graph_abs(child, min_hit); 440 if (callchain_cumul_hits(child) >= min_hit) 441 rb_insert_callchain(&node->rb_root, child, 442 CHAIN_GRAPH_ABS); 443 } 444 } 445 446 static void 447 sort_chain_graph_abs(struct rb_root *rb_root, struct callchain_root *chain_root, 448 u64 min_hit, struct callchain_param *param __maybe_unused) 449 { 450 __sort_chain_graph_abs(&chain_root->node, min_hit); 451 rb_root->rb_node = chain_root->node.rb_root.rb_node; 452 } 453 454 static void __sort_chain_graph_rel(struct callchain_node *node, 455 double min_percent) 456 { 457 struct rb_node *n; 458 struct callchain_node *child; 459 u64 min_hit; 460 461 node->rb_root = RB_ROOT; 462 min_hit = ceil(node->children_hit * min_percent); 463 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 469 __sort_chain_graph_rel(child, min_percent); 470 if (callchain_cumul_hits(child) >= min_hit) 471 rb_insert_callchain(&node->rb_root, child, 472 CHAIN_GRAPH_REL); 473 } 474 } 475 476 static void 477 sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_root *chain_root, 478 u64 min_hit __maybe_unused, struct callchain_param *param) 479 { 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; 482 } 483 484 int callchain_register_param(struct callchain_param *param) 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: 494 case CHAIN_FOLDED: 495 param->sort = sort_chain_flat; 496 break; 497 case CHAIN_NONE: 498 default: 499 return -1; 500 } 501 return 0; 502 } 503 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 */ 508 static struct callchain_node * 509 create_child(struct callchain_node *parent, bool inherit_children) 510 { 511 struct callchain_node *new; 512 513 new = zalloc(sizeof(*new)); 514 if (!new) { 515 perror("not enough memory to create child for code path tree"); 516 return NULL; 517 } 518 new->parent = parent; 519 INIT_LIST_HEAD(&new->val); 520 INIT_LIST_HEAD(&new->parent_val); 521 522 if (inherit_children) { 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; 528 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 } 535 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); 539 } 540 541 return new; 542 } 543 544 545 /* 546 * Fill the node with callchain values 547 */ 548 static int 549 fill_node(struct callchain_node *node, struct callchain_cursor *cursor) 550 { 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"); 556 557 cursor_node = callchain_cursor_current(cursor); 558 559 while (cursor_node) { 560 struct callchain_list *call; 561 562 call = zalloc(sizeof(*call)); 563 if (!call) { 564 perror("not enough memory for the code path tree"); 565 return -1; 566 } 567 call->ip = cursor_node->ip; 568 call->ms.sym = cursor_node->sym; 569 call->ms.map = map__get(cursor_node->map); 570 call->srcline = cursor_node->srcline; 571 572 if (cursor_node->branch) { 573 call->branch_count = 1; 574 575 if (cursor_node->branch_from) { 576 /* 577 * branch_from is set with value somewhere else 578 * to imply it's "to" of a branch. 579 */ 580 call->brtype_stat.branch_to = true; 581 582 if (cursor_node->branch_flags.predicted) 583 call->predicted_count = 1; 584 585 if (cursor_node->branch_flags.abort) 586 call->abort_count = 1; 587 588 branch_type_count(&call->brtype_stat, 589 &cursor_node->branch_flags, 590 cursor_node->branch_from, 591 cursor_node->ip); 592 } else { 593 /* 594 * It's "from" of a branch 595 */ 596 call->brtype_stat.branch_to = false; 597 call->cycles_count = 598 cursor_node->branch_flags.cycles; 599 call->iter_count = cursor_node->nr_loop_iter; 600 call->iter_cycles = cursor_node->iter_cycles; 601 } 602 } 603 604 list_add_tail(&call->list, &node->val); 605 606 callchain_cursor_advance(cursor); 607 cursor_node = callchain_cursor_current(cursor); 608 } 609 return 0; 610 } 611 612 static struct callchain_node * 613 add_child(struct callchain_node *parent, 614 struct callchain_cursor *cursor, 615 u64 period) 616 { 617 struct callchain_node *new; 618 619 new = create_child(parent, false); 620 if (new == NULL) 621 return NULL; 622 623 if (fill_node(new, cursor) < 0) { 624 struct callchain_list *call, *tmp; 625 626 list_for_each_entry_safe(call, tmp, &new->val, list) { 627 list_del(&call->list); 628 map__zput(call->ms.map); 629 free(call); 630 } 631 free(new); 632 return NULL; 633 } 634 635 new->children_hit = 0; 636 new->hit = period; 637 new->children_count = 0; 638 new->count = 1; 639 return new; 640 } 641 642 enum match_result { 643 MATCH_ERROR = -1, 644 MATCH_EQ, 645 MATCH_LT, 646 MATCH_GT, 647 }; 648 649 static enum match_result match_chain_strings(const char *left, 650 const char *right) 651 { 652 enum match_result ret = MATCH_EQ; 653 int cmp; 654 655 if (left && right) 656 cmp = strcmp(left, right); 657 else if (!left && right) 658 cmp = 1; 659 else if (left && !right) 660 cmp = -1; 661 else 662 return MATCH_ERROR; 663 664 if (cmp != 0) 665 ret = cmp < 0 ? MATCH_LT : MATCH_GT; 666 667 return ret; 668 } 669 670 /* 671 * We need to always use relative addresses because we're aggregating 672 * callchains from multiple threads, i.e. different address spaces, so 673 * comparing absolute addresses make no sense as a symbol in a DSO may end up 674 * in a different address when used in a different binary or even the same 675 * binary but with some sort of address randomization technique, thus we need 676 * to compare just relative addresses. -acme 677 */ 678 static enum match_result match_chain_dso_addresses(struct map *left_map, u64 left_ip, 679 struct map *right_map, u64 right_ip) 680 { 681 struct dso *left_dso = left_map ? left_map->dso : NULL; 682 struct dso *right_dso = right_map ? right_map->dso : NULL; 683 684 if (left_dso != right_dso) 685 return left_dso < right_dso ? MATCH_LT : MATCH_GT; 686 687 if (left_ip != right_ip) 688 return left_ip < right_ip ? MATCH_LT : MATCH_GT; 689 690 return MATCH_EQ; 691 } 692 693 static enum match_result match_chain(struct callchain_cursor_node *node, 694 struct callchain_list *cnode) 695 { 696 enum match_result match = MATCH_ERROR; 697 698 switch (callchain_param.key) { 699 case CCKEY_SRCLINE: 700 match = match_chain_strings(cnode->srcline, node->srcline); 701 if (match != MATCH_ERROR) 702 break; 703 /* otherwise fall-back to symbol-based comparison below */ 704 __fallthrough; 705 case CCKEY_FUNCTION: 706 if (node->sym && cnode->ms.sym) { 707 /* 708 * Compare inlined frames based on their symbol name 709 * because different inlined frames will have the same 710 * symbol start. Otherwise do a faster comparison based 711 * on the symbol start address. 712 */ 713 if (cnode->ms.sym->inlined || node->sym->inlined) { 714 match = match_chain_strings(cnode->ms.sym->name, 715 node->sym->name); 716 if (match != MATCH_ERROR) 717 break; 718 } else { 719 match = match_chain_dso_addresses(cnode->ms.map, cnode->ms.sym->start, 720 node->map, node->sym->start); 721 break; 722 } 723 } 724 /* otherwise fall-back to IP-based comparison below */ 725 __fallthrough; 726 case CCKEY_ADDRESS: 727 default: 728 match = match_chain_dso_addresses(cnode->ms.map, cnode->ip, node->map, node->ip); 729 break; 730 } 731 732 if (match == MATCH_EQ && node->branch) { 733 cnode->branch_count++; 734 735 if (node->branch_from) { 736 /* 737 * It's "to" of a branch 738 */ 739 cnode->brtype_stat.branch_to = true; 740 741 if (node->branch_flags.predicted) 742 cnode->predicted_count++; 743 744 if (node->branch_flags.abort) 745 cnode->abort_count++; 746 747 branch_type_count(&cnode->brtype_stat, 748 &node->branch_flags, 749 node->branch_from, 750 node->ip); 751 } else { 752 /* 753 * It's "from" of a branch 754 */ 755 cnode->brtype_stat.branch_to = false; 756 cnode->cycles_count += node->branch_flags.cycles; 757 cnode->iter_count += node->nr_loop_iter; 758 cnode->iter_cycles += node->iter_cycles; 759 } 760 } 761 762 return match; 763 } 764 765 /* 766 * Split the parent in two parts (a new child is created) and 767 * give a part of its callchain to the created child. 768 * Then create another child to host the given callchain of new branch 769 */ 770 static int 771 split_add_child(struct callchain_node *parent, 772 struct callchain_cursor *cursor, 773 struct callchain_list *to_split, 774 u64 idx_parents, u64 idx_local, u64 period) 775 { 776 struct callchain_node *new; 777 struct list_head *old_tail; 778 unsigned int idx_total = idx_parents + idx_local; 779 780 /* split */ 781 new = create_child(parent, true); 782 if (new == NULL) 783 return -1; 784 785 /* split the callchain and move a part to the new child */ 786 old_tail = parent->val.prev; 787 list_del_range(&to_split->list, old_tail); 788 new->val.next = &to_split->list; 789 new->val.prev = old_tail; 790 to_split->list.prev = &new->val; 791 old_tail->next = &new->val; 792 793 /* split the hits */ 794 new->hit = parent->hit; 795 new->children_hit = parent->children_hit; 796 parent->children_hit = callchain_cumul_hits(new); 797 new->val_nr = parent->val_nr - idx_local; 798 parent->val_nr = idx_local; 799 new->count = parent->count; 800 new->children_count = parent->children_count; 801 parent->children_count = callchain_cumul_counts(new); 802 803 /* create a new child for the new branch if any */ 804 if (idx_total < cursor->nr) { 805 struct callchain_node *first; 806 struct callchain_list *cnode; 807 struct callchain_cursor_node *node; 808 struct rb_node *p, **pp; 809 810 parent->hit = 0; 811 parent->children_hit += period; 812 parent->count = 0; 813 parent->children_count += 1; 814 815 node = callchain_cursor_current(cursor); 816 new = add_child(parent, cursor, period); 817 if (new == NULL) 818 return -1; 819 820 /* 821 * This is second child since we moved parent's children 822 * to new (first) child above. 823 */ 824 p = parent->rb_root_in.rb_node; 825 first = rb_entry(p, struct callchain_node, rb_node_in); 826 cnode = list_first_entry(&first->val, struct callchain_list, 827 list); 828 829 if (match_chain(node, cnode) == MATCH_LT) 830 pp = &p->rb_left; 831 else 832 pp = &p->rb_right; 833 834 rb_link_node(&new->rb_node_in, p, pp); 835 rb_insert_color(&new->rb_node_in, &parent->rb_root_in); 836 } else { 837 parent->hit = period; 838 parent->count = 1; 839 } 840 return 0; 841 } 842 843 static enum match_result 844 append_chain(struct callchain_node *root, 845 struct callchain_cursor *cursor, 846 u64 period); 847 848 static int 849 append_chain_children(struct callchain_node *root, 850 struct callchain_cursor *cursor, 851 u64 period) 852 { 853 struct callchain_node *rnode; 854 struct callchain_cursor_node *node; 855 struct rb_node **p = &root->rb_root_in.rb_node; 856 struct rb_node *parent = NULL; 857 858 node = callchain_cursor_current(cursor); 859 if (!node) 860 return -1; 861 862 /* lookup in childrens */ 863 while (*p) { 864 enum match_result ret; 865 866 parent = *p; 867 rnode = rb_entry(parent, struct callchain_node, rb_node_in); 868 869 /* If at least first entry matches, rely to children */ 870 ret = append_chain(rnode, cursor, period); 871 if (ret == MATCH_EQ) 872 goto inc_children_hit; 873 if (ret == MATCH_ERROR) 874 return -1; 875 876 if (ret == MATCH_LT) 877 p = &parent->rb_left; 878 else 879 p = &parent->rb_right; 880 } 881 /* nothing in children, add to the current node */ 882 rnode = add_child(root, cursor, period); 883 if (rnode == NULL) 884 return -1; 885 886 rb_link_node(&rnode->rb_node_in, parent, p); 887 rb_insert_color(&rnode->rb_node_in, &root->rb_root_in); 888 889 inc_children_hit: 890 root->children_hit += period; 891 root->children_count++; 892 return 0; 893 } 894 895 static enum match_result 896 append_chain(struct callchain_node *root, 897 struct callchain_cursor *cursor, 898 u64 period) 899 { 900 struct callchain_list *cnode; 901 u64 start = cursor->pos; 902 bool found = false; 903 u64 matches; 904 enum match_result cmp = MATCH_ERROR; 905 906 /* 907 * Lookup in the current node 908 * If we have a symbol, then compare the start to match 909 * anywhere inside a function, unless function 910 * mode is disabled. 911 */ 912 list_for_each_entry(cnode, &root->val, list) { 913 struct callchain_cursor_node *node; 914 915 node = callchain_cursor_current(cursor); 916 if (!node) 917 break; 918 919 cmp = match_chain(node, cnode); 920 if (cmp != MATCH_EQ) 921 break; 922 923 found = true; 924 925 callchain_cursor_advance(cursor); 926 } 927 928 /* matches not, relay no the parent */ 929 if (!found) { 930 WARN_ONCE(cmp == MATCH_ERROR, "Chain comparison error\n"); 931 return cmp; 932 } 933 934 matches = cursor->pos - start; 935 936 /* we match only a part of the node. Split it and add the new chain */ 937 if (matches < root->val_nr) { 938 if (split_add_child(root, cursor, cnode, start, matches, 939 period) < 0) 940 return MATCH_ERROR; 941 942 return MATCH_EQ; 943 } 944 945 /* we match 100% of the path, increment the hit */ 946 if (matches == root->val_nr && cursor->pos == cursor->nr) { 947 root->hit += period; 948 root->count++; 949 return MATCH_EQ; 950 } 951 952 /* We match the node and still have a part remaining */ 953 if (append_chain_children(root, cursor, period) < 0) 954 return MATCH_ERROR; 955 956 return MATCH_EQ; 957 } 958 959 int callchain_append(struct callchain_root *root, 960 struct callchain_cursor *cursor, 961 u64 period) 962 { 963 if (!cursor->nr) 964 return 0; 965 966 callchain_cursor_commit(cursor); 967 968 if (append_chain_children(&root->node, cursor, period) < 0) 969 return -1; 970 971 if (cursor->nr > root->max_depth) 972 root->max_depth = cursor->nr; 973 974 return 0; 975 } 976 977 static int 978 merge_chain_branch(struct callchain_cursor *cursor, 979 struct callchain_node *dst, struct callchain_node *src) 980 { 981 struct callchain_cursor_node **old_last = cursor->last; 982 struct callchain_node *child; 983 struct callchain_list *list, *next_list; 984 struct rb_node *n; 985 int old_pos = cursor->nr; 986 int err = 0; 987 988 list_for_each_entry_safe(list, next_list, &src->val, list) { 989 callchain_cursor_append(cursor, list->ip, 990 list->ms.map, list->ms.sym, 991 false, NULL, 0, 0, 0, list->srcline); 992 list_del(&list->list); 993 map__zput(list->ms.map); 994 free(list); 995 } 996 997 if (src->hit) { 998 callchain_cursor_commit(cursor); 999 if (append_chain_children(dst, cursor, src->hit) < 0) 1000 return -1; 1001 } 1002 1003 n = rb_first(&src->rb_root_in); 1004 while (n) { 1005 child = container_of(n, struct callchain_node, rb_node_in); 1006 n = rb_next(n); 1007 rb_erase(&child->rb_node_in, &src->rb_root_in); 1008 1009 err = merge_chain_branch(cursor, dst, child); 1010 if (err) 1011 break; 1012 1013 free(child); 1014 } 1015 1016 cursor->nr = old_pos; 1017 cursor->last = old_last; 1018 1019 return err; 1020 } 1021 1022 int callchain_merge(struct callchain_cursor *cursor, 1023 struct callchain_root *dst, struct callchain_root *src) 1024 { 1025 return merge_chain_branch(cursor, &dst->node, &src->node); 1026 } 1027 1028 int callchain_cursor_append(struct callchain_cursor *cursor, 1029 u64 ip, struct map *map, struct symbol *sym, 1030 bool branch, struct branch_flags *flags, 1031 int nr_loop_iter, u64 iter_cycles, u64 branch_from, 1032 const char *srcline) 1033 { 1034 struct callchain_cursor_node *node = *cursor->last; 1035 1036 if (!node) { 1037 node = calloc(1, sizeof(*node)); 1038 if (!node) 1039 return -ENOMEM; 1040 1041 *cursor->last = node; 1042 } 1043 1044 node->ip = ip; 1045 map__zput(node->map); 1046 node->map = map__get(map); 1047 node->sym = sym; 1048 node->branch = branch; 1049 node->nr_loop_iter = nr_loop_iter; 1050 node->iter_cycles = iter_cycles; 1051 node->srcline = srcline; 1052 1053 if (flags) 1054 memcpy(&node->branch_flags, flags, 1055 sizeof(struct branch_flags)); 1056 1057 node->branch_from = branch_from; 1058 cursor->nr++; 1059 1060 cursor->last = &node->next; 1061 1062 return 0; 1063 } 1064 1065 int sample__resolve_callchain(struct perf_sample *sample, 1066 struct callchain_cursor *cursor, struct symbol **parent, 1067 struct perf_evsel *evsel, struct addr_location *al, 1068 int max_stack) 1069 { 1070 if (sample->callchain == NULL && !symbol_conf.show_branchflag_count) 1071 return 0; 1072 1073 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain || 1074 perf_hpp_list.parent || symbol_conf.show_branchflag_count) { 1075 return thread__resolve_callchain(al->thread, cursor, evsel, sample, 1076 parent, al, max_stack); 1077 } 1078 return 0; 1079 } 1080 1081 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample) 1082 { 1083 if ((!symbol_conf.use_callchain || sample->callchain == NULL) && 1084 !symbol_conf.show_branchflag_count) 1085 return 0; 1086 return callchain_append(he->callchain, &callchain_cursor, sample->period); 1087 } 1088 1089 int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node, 1090 bool hide_unresolved) 1091 { 1092 al->map = node->map; 1093 al->sym = node->sym; 1094 al->srcline = node->srcline; 1095 al->addr = node->ip; 1096 1097 if (al->sym == NULL) { 1098 if (hide_unresolved) 1099 return 0; 1100 if (al->map == NULL) 1101 goto out; 1102 } 1103 1104 if (al->map->groups == &al->machine->kmaps) { 1105 if (machine__is_host(al->machine)) { 1106 al->cpumode = PERF_RECORD_MISC_KERNEL; 1107 al->level = 'k'; 1108 } else { 1109 al->cpumode = PERF_RECORD_MISC_GUEST_KERNEL; 1110 al->level = 'g'; 1111 } 1112 } else { 1113 if (machine__is_host(al->machine)) { 1114 al->cpumode = PERF_RECORD_MISC_USER; 1115 al->level = '.'; 1116 } else if (perf_guest) { 1117 al->cpumode = PERF_RECORD_MISC_GUEST_USER; 1118 al->level = 'u'; 1119 } else { 1120 al->cpumode = PERF_RECORD_MISC_HYPERVISOR; 1121 al->level = 'H'; 1122 } 1123 } 1124 1125 out: 1126 return 1; 1127 } 1128 1129 char *callchain_list__sym_name(struct callchain_list *cl, 1130 char *bf, size_t bfsize, bool show_dso) 1131 { 1132 bool show_addr = callchain_param.key == CCKEY_ADDRESS; 1133 bool show_srcline = show_addr || callchain_param.key == CCKEY_SRCLINE; 1134 int printed; 1135 1136 if (cl->ms.sym) { 1137 const char *inlined = cl->ms.sym->inlined ? " (inlined)" : ""; 1138 1139 if (show_srcline && cl->srcline) 1140 printed = scnprintf(bf, bfsize, "%s %s%s", 1141 cl->ms.sym->name, cl->srcline, 1142 inlined); 1143 else 1144 printed = scnprintf(bf, bfsize, "%s%s", 1145 cl->ms.sym->name, inlined); 1146 } else 1147 printed = scnprintf(bf, bfsize, "%#" PRIx64, cl->ip); 1148 1149 if (show_dso) 1150 scnprintf(bf + printed, bfsize - printed, " %s", 1151 cl->ms.map ? 1152 cl->ms.map->dso->short_name : 1153 "unknown"); 1154 1155 return bf; 1156 } 1157 1158 char *callchain_node__scnprintf_value(struct callchain_node *node, 1159 char *bf, size_t bfsize, u64 total) 1160 { 1161 double percent = 0.0; 1162 u64 period = callchain_cumul_hits(node); 1163 unsigned count = callchain_cumul_counts(node); 1164 1165 if (callchain_param.mode == CHAIN_FOLDED) { 1166 period = node->hit; 1167 count = node->count; 1168 } 1169 1170 switch (callchain_param.value) { 1171 case CCVAL_PERIOD: 1172 scnprintf(bf, bfsize, "%"PRIu64, period); 1173 break; 1174 case CCVAL_COUNT: 1175 scnprintf(bf, bfsize, "%u", count); 1176 break; 1177 case CCVAL_PERCENT: 1178 default: 1179 if (total) 1180 percent = period * 100.0 / total; 1181 scnprintf(bf, bfsize, "%.2f%%", percent); 1182 break; 1183 } 1184 return bf; 1185 } 1186 1187 int callchain_node__fprintf_value(struct callchain_node *node, 1188 FILE *fp, u64 total) 1189 { 1190 double percent = 0.0; 1191 u64 period = callchain_cumul_hits(node); 1192 unsigned count = callchain_cumul_counts(node); 1193 1194 if (callchain_param.mode == CHAIN_FOLDED) { 1195 period = node->hit; 1196 count = node->count; 1197 } 1198 1199 switch (callchain_param.value) { 1200 case CCVAL_PERIOD: 1201 return fprintf(fp, "%"PRIu64, period); 1202 case CCVAL_COUNT: 1203 return fprintf(fp, "%u", count); 1204 case CCVAL_PERCENT: 1205 default: 1206 if (total) 1207 percent = period * 100.0 / total; 1208 return percent_color_fprintf(fp, "%.2f%%", percent); 1209 } 1210 return 0; 1211 } 1212 1213 static void callchain_counts_value(struct callchain_node *node, 1214 u64 *branch_count, u64 *predicted_count, 1215 u64 *abort_count, u64 *cycles_count) 1216 { 1217 struct callchain_list *clist; 1218 1219 list_for_each_entry(clist, &node->val, list) { 1220 if (branch_count) 1221 *branch_count += clist->branch_count; 1222 1223 if (predicted_count) 1224 *predicted_count += clist->predicted_count; 1225 1226 if (abort_count) 1227 *abort_count += clist->abort_count; 1228 1229 if (cycles_count) 1230 *cycles_count += clist->cycles_count; 1231 } 1232 } 1233 1234 static int callchain_node_branch_counts_cumul(struct callchain_node *node, 1235 u64 *branch_count, 1236 u64 *predicted_count, 1237 u64 *abort_count, 1238 u64 *cycles_count) 1239 { 1240 struct callchain_node *child; 1241 struct rb_node *n; 1242 1243 n = rb_first(&node->rb_root_in); 1244 while (n) { 1245 child = rb_entry(n, struct callchain_node, rb_node_in); 1246 n = rb_next(n); 1247 1248 callchain_node_branch_counts_cumul(child, branch_count, 1249 predicted_count, 1250 abort_count, 1251 cycles_count); 1252 1253 callchain_counts_value(child, branch_count, 1254 predicted_count, abort_count, 1255 cycles_count); 1256 } 1257 1258 return 0; 1259 } 1260 1261 int callchain_branch_counts(struct callchain_root *root, 1262 u64 *branch_count, u64 *predicted_count, 1263 u64 *abort_count, u64 *cycles_count) 1264 { 1265 if (branch_count) 1266 *branch_count = 0; 1267 1268 if (predicted_count) 1269 *predicted_count = 0; 1270 1271 if (abort_count) 1272 *abort_count = 0; 1273 1274 if (cycles_count) 1275 *cycles_count = 0; 1276 1277 return callchain_node_branch_counts_cumul(&root->node, 1278 branch_count, 1279 predicted_count, 1280 abort_count, 1281 cycles_count); 1282 } 1283 1284 static int count_pri64_printf(int idx, const char *str, u64 value, char *bf, int bfsize) 1285 { 1286 int printed; 1287 1288 printed = scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value); 1289 1290 return printed; 1291 } 1292 1293 static int count_float_printf(int idx, const char *str, float value, 1294 char *bf, int bfsize, float threshold) 1295 { 1296 int printed; 1297 1298 if (threshold != 0.0 && value < threshold) 1299 return 0; 1300 1301 printed = scnprintf(bf, bfsize, "%s%s:%.1f%%", (idx) ? " " : " (", str, value); 1302 1303 return printed; 1304 } 1305 1306 static int branch_to_str(char *bf, int bfsize, 1307 u64 branch_count, u64 predicted_count, 1308 u64 abort_count, 1309 struct branch_type_stat *brtype_stat) 1310 { 1311 int printed, i = 0; 1312 1313 printed = branch_type_str(brtype_stat, bf, bfsize); 1314 if (printed) 1315 i++; 1316 1317 if (predicted_count < branch_count) { 1318 printed += count_float_printf(i++, "predicted", 1319 predicted_count * 100.0 / branch_count, 1320 bf + printed, bfsize - printed, 0.0); 1321 } 1322 1323 if (abort_count) { 1324 printed += count_float_printf(i++, "abort", 1325 abort_count * 100.0 / branch_count, 1326 bf + printed, bfsize - printed, 0.1); 1327 } 1328 1329 if (i) 1330 printed += scnprintf(bf + printed, bfsize - printed, ")"); 1331 1332 return printed; 1333 } 1334 1335 static int branch_from_str(char *bf, int bfsize, 1336 u64 branch_count, 1337 u64 cycles_count, u64 iter_count, 1338 u64 iter_cycles) 1339 { 1340 int printed = 0, i = 0; 1341 u64 cycles; 1342 1343 cycles = cycles_count / branch_count; 1344 if (cycles) { 1345 printed += count_pri64_printf(i++, "cycles", 1346 cycles, 1347 bf + printed, bfsize - printed); 1348 } 1349 1350 if (iter_count) { 1351 printed += count_pri64_printf(i++, "iter", 1352 iter_count, 1353 bf + printed, bfsize - printed); 1354 1355 printed += count_pri64_printf(i++, "avg_cycles", 1356 iter_cycles / iter_count, 1357 bf + printed, bfsize - printed); 1358 } 1359 1360 if (i) 1361 printed += scnprintf(bf + printed, bfsize - printed, ")"); 1362 1363 return printed; 1364 } 1365 1366 static int counts_str_build(char *bf, int bfsize, 1367 u64 branch_count, u64 predicted_count, 1368 u64 abort_count, u64 cycles_count, 1369 u64 iter_count, u64 iter_cycles, 1370 struct branch_type_stat *brtype_stat) 1371 { 1372 int printed; 1373 1374 if (branch_count == 0) 1375 return scnprintf(bf, bfsize, " (calltrace)"); 1376 1377 if (brtype_stat->branch_to) { 1378 printed = branch_to_str(bf, bfsize, branch_count, 1379 predicted_count, abort_count, brtype_stat); 1380 } else { 1381 printed = branch_from_str(bf, bfsize, branch_count, 1382 cycles_count, iter_count, iter_cycles); 1383 } 1384 1385 if (!printed) 1386 bf[0] = 0; 1387 1388 return printed; 1389 } 1390 1391 static int callchain_counts_printf(FILE *fp, char *bf, int bfsize, 1392 u64 branch_count, u64 predicted_count, 1393 u64 abort_count, u64 cycles_count, 1394 u64 iter_count, u64 iter_cycles, 1395 struct branch_type_stat *brtype_stat) 1396 { 1397 char str[256]; 1398 1399 counts_str_build(str, sizeof(str), branch_count, 1400 predicted_count, abort_count, cycles_count, 1401 iter_count, iter_cycles, brtype_stat); 1402 1403 if (fp) 1404 return fprintf(fp, "%s", str); 1405 1406 return scnprintf(bf, bfsize, "%s", str); 1407 } 1408 1409 int callchain_list_counts__printf_value(struct callchain_list *clist, 1410 FILE *fp, char *bf, int bfsize) 1411 { 1412 u64 branch_count, predicted_count; 1413 u64 abort_count, cycles_count; 1414 u64 iter_count, iter_cycles; 1415 1416 branch_count = clist->branch_count; 1417 predicted_count = clist->predicted_count; 1418 abort_count = clist->abort_count; 1419 cycles_count = clist->cycles_count; 1420 iter_count = clist->iter_count; 1421 iter_cycles = clist->iter_cycles; 1422 1423 return callchain_counts_printf(fp, bf, bfsize, branch_count, 1424 predicted_count, abort_count, 1425 cycles_count, iter_count, iter_cycles, 1426 &clist->brtype_stat); 1427 } 1428 1429 static void free_callchain_node(struct callchain_node *node) 1430 { 1431 struct callchain_list *list, *tmp; 1432 struct callchain_node *child; 1433 struct rb_node *n; 1434 1435 list_for_each_entry_safe(list, tmp, &node->parent_val, list) { 1436 list_del(&list->list); 1437 map__zput(list->ms.map); 1438 free(list); 1439 } 1440 1441 list_for_each_entry_safe(list, tmp, &node->val, list) { 1442 list_del(&list->list); 1443 map__zput(list->ms.map); 1444 free(list); 1445 } 1446 1447 n = rb_first(&node->rb_root_in); 1448 while (n) { 1449 child = container_of(n, struct callchain_node, rb_node_in); 1450 n = rb_next(n); 1451 rb_erase(&child->rb_node_in, &node->rb_root_in); 1452 1453 free_callchain_node(child); 1454 free(child); 1455 } 1456 } 1457 1458 void free_callchain(struct callchain_root *root) 1459 { 1460 if (!symbol_conf.use_callchain) 1461 return; 1462 1463 free_callchain_node(&root->node); 1464 } 1465 1466 static u64 decay_callchain_node(struct callchain_node *node) 1467 { 1468 struct callchain_node *child; 1469 struct rb_node *n; 1470 u64 child_hits = 0; 1471 1472 n = rb_first(&node->rb_root_in); 1473 while (n) { 1474 child = container_of(n, struct callchain_node, rb_node_in); 1475 1476 child_hits += decay_callchain_node(child); 1477 n = rb_next(n); 1478 } 1479 1480 node->hit = (node->hit * 7) / 8; 1481 node->children_hit = child_hits; 1482 1483 return node->hit; 1484 } 1485 1486 void decay_callchain(struct callchain_root *root) 1487 { 1488 if (!symbol_conf.use_callchain) 1489 return; 1490 1491 decay_callchain_node(&root->node); 1492 } 1493 1494 int callchain_node__make_parent_list(struct callchain_node *node) 1495 { 1496 struct callchain_node *parent = node->parent; 1497 struct callchain_list *chain, *new; 1498 LIST_HEAD(head); 1499 1500 while (parent) { 1501 list_for_each_entry_reverse(chain, &parent->val, list) { 1502 new = malloc(sizeof(*new)); 1503 if (new == NULL) 1504 goto out; 1505 *new = *chain; 1506 new->has_children = false; 1507 map__get(new->ms.map); 1508 list_add_tail(&new->list, &head); 1509 } 1510 parent = parent->parent; 1511 } 1512 1513 list_for_each_entry_safe_reverse(chain, new, &head, list) 1514 list_move_tail(&chain->list, &node->parent_val); 1515 1516 if (!list_empty(&node->parent_val)) { 1517 chain = list_first_entry(&node->parent_val, struct callchain_list, list); 1518 chain->has_children = rb_prev(&node->rb_node) || rb_next(&node->rb_node); 1519 1520 chain = list_first_entry(&node->val, struct callchain_list, list); 1521 chain->has_children = false; 1522 } 1523 return 0; 1524 1525 out: 1526 list_for_each_entry_safe(chain, new, &head, list) { 1527 list_del(&chain->list); 1528 map__zput(chain->ms.map); 1529 free(chain); 1530 } 1531 return -ENOMEM; 1532 } 1533 1534 int callchain_cursor__copy(struct callchain_cursor *dst, 1535 struct callchain_cursor *src) 1536 { 1537 int rc = 0; 1538 1539 callchain_cursor_reset(dst); 1540 callchain_cursor_commit(src); 1541 1542 while (true) { 1543 struct callchain_cursor_node *node; 1544 1545 node = callchain_cursor_current(src); 1546 if (node == NULL) 1547 break; 1548 1549 rc = callchain_cursor_append(dst, node->ip, node->map, node->sym, 1550 node->branch, &node->branch_flags, 1551 node->nr_loop_iter, 1552 node->iter_cycles, 1553 node->branch_from, node->srcline); 1554 if (rc) 1555 break; 1556 1557 callchain_cursor_advance(src); 1558 } 1559 1560 return rc; 1561 } 1562