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