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