diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-06-18 01:01:03 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-18 01:21:54 -0400 |
commit | b25bcf2f133b1e6216c3d40be394756107d3880f (patch) | |
tree | 6bc2e9fde711b5f22a3bb56ab8dcca335211feb1 /tools | |
parent | 5aa75a0fd4bc6402899e06fdb853cab024d65055 (diff) |
perf report: Tidy up the "--parent <regex>" and "--sort parent" call-chain features
Instead of the ambigious 'call' naming use the much more
specific 'parent' naming:
- rename --call <regex> to --parent <regex>
- rename --sort call to --sort parent
- rename [unmatched] to [other] - to signal that this is not
an error but the inverse set
Also add pagefaults to the default parent-symbol pattern too,
as it's a 'syscall overhead category' in a sense.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-report.c | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 707f60ce32fd..986834623b43 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -44,8 +44,8 @@ static int full_paths; | |||
44 | static unsigned long page_size; | 44 | static unsigned long page_size; |
45 | static unsigned long mmap_window = 32; | 45 | static unsigned long mmap_window = 32; |
46 | 46 | ||
47 | static char *call = "^sys_"; | 47 | static char *parent_pattern = "^sys_|^do_page_fault"; |
48 | static regex_t call_regex; | 48 | static regex_t parent_regex; |
49 | 49 | ||
50 | struct ip_chain_event { | 50 | struct ip_chain_event { |
51 | __u16 nr; | 51 | __u16 nr; |
@@ -465,7 +465,7 @@ struct hist_entry { | |||
465 | struct map *map; | 465 | struct map *map; |
466 | struct dso *dso; | 466 | struct dso *dso; |
467 | struct symbol *sym; | 467 | struct symbol *sym; |
468 | struct symbol *call; | 468 | struct symbol *parent; |
469 | __u64 ip; | 469 | __u64 ip; |
470 | char level; | 470 | char level; |
471 | 471 | ||
@@ -618,13 +618,13 @@ static struct sort_entry sort_sym = { | |||
618 | .print = sort__sym_print, | 618 | .print = sort__sym_print, |
619 | }; | 619 | }; |
620 | 620 | ||
621 | /* --sort call */ | 621 | /* --sort parent */ |
622 | 622 | ||
623 | static int64_t | 623 | static int64_t |
624 | sort__call_cmp(struct hist_entry *left, struct hist_entry *right) | 624 | sort__parent_cmp(struct hist_entry *left, struct hist_entry *right) |
625 | { | 625 | { |
626 | struct symbol *sym_l = left->call; | 626 | struct symbol *sym_l = left->parent; |
627 | struct symbol *sym_r = right->call; | 627 | struct symbol *sym_r = right->parent; |
628 | 628 | ||
629 | if (!sym_l || !sym_r) | 629 | if (!sym_l || !sym_r) |
630 | return cmp_null(sym_l, sym_r); | 630 | return cmp_null(sym_l, sym_r); |
@@ -633,23 +633,23 @@ sort__call_cmp(struct hist_entry *left, struct hist_entry *right) | |||
633 | } | 633 | } |
634 | 634 | ||
635 | static size_t | 635 | static size_t |
636 | sort__call_print(FILE *fp, struct hist_entry *self) | 636 | sort__parent_print(FILE *fp, struct hist_entry *self) |
637 | { | 637 | { |
638 | size_t ret = 0; | 638 | size_t ret = 0; |
639 | 639 | ||
640 | ret += fprintf(fp, "%-20s", self->call ? self->call->name : "[unmatched]"); | 640 | ret += fprintf(fp, "%-20s", self->parent ? self->parent->name : "[other]"); |
641 | 641 | ||
642 | return ret; | 642 | return ret; |
643 | } | 643 | } |
644 | 644 | ||
645 | static struct sort_entry sort_call = { | 645 | static struct sort_entry sort_parent = { |
646 | .header = "Callchain symbol ", | 646 | .header = "Parent symbol ", |
647 | .cmp = sort__call_cmp, | 647 | .cmp = sort__parent_cmp, |
648 | .print = sort__call_print, | 648 | .print = sort__parent_print, |
649 | }; | 649 | }; |
650 | 650 | ||
651 | static int sort__need_collapse = 0; | 651 | static int sort__need_collapse = 0; |
652 | static int sort__has_call = 0; | 652 | static int sort__has_parent = 0; |
653 | 653 | ||
654 | struct sort_dimension { | 654 | struct sort_dimension { |
655 | char *name; | 655 | char *name; |
@@ -662,7 +662,7 @@ static struct sort_dimension sort_dimensions[] = { | |||
662 | { .name = "comm", .entry = &sort_comm, }, | 662 | { .name = "comm", .entry = &sort_comm, }, |
663 | { .name = "dso", .entry = &sort_dso, }, | 663 | { .name = "dso", .entry = &sort_dso, }, |
664 | { .name = "symbol", .entry = &sort_sym, }, | 664 | { .name = "symbol", .entry = &sort_sym, }, |
665 | { .name = "call", .entry = &sort_call, }, | 665 | { .name = "parent", .entry = &sort_parent, }, |
666 | }; | 666 | }; |
667 | 667 | ||
668 | static LIST_HEAD(hist_entry__sort_list); | 668 | static LIST_HEAD(hist_entry__sort_list); |
@@ -683,16 +683,17 @@ static int sort_dimension__add(char *tok) | |||
683 | if (sd->entry->collapse) | 683 | if (sd->entry->collapse) |
684 | sort__need_collapse = 1; | 684 | sort__need_collapse = 1; |
685 | 685 | ||
686 | if (sd->entry == &sort_call) { | 686 | if (sd->entry == &sort_parent) { |
687 | int ret = regcomp(&call_regex, call, REG_EXTENDED); | 687 | int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED); |
688 | if (ret) { | 688 | if (ret) { |
689 | char err[BUFSIZ]; | 689 | char err[BUFSIZ]; |
690 | 690 | ||
691 | regerror(ret, &call_regex, err, sizeof(err)); | 691 | regerror(ret, &parent_regex, err, sizeof(err)); |
692 | fprintf(stderr, "Invalid regex: %s\n%s", call, err); | 692 | fprintf(stderr, "Invalid regex: %s\n%s", |
693 | parent_pattern, err); | ||
693 | exit(-1); | 694 | exit(-1); |
694 | } | 695 | } |
695 | sort__has_call = 1; | 696 | sort__has_parent = 1; |
696 | } | 697 | } |
697 | 698 | ||
698 | list_add_tail(&sd->entry->list, &hist_entry__sort_list); | 699 | list_add_tail(&sd->entry->list, &hist_entry__sort_list); |
@@ -831,7 +832,7 @@ static struct symbol *call__match(struct symbol *sym) | |||
831 | if (!sym) | 832 | if (!sym) |
832 | return NULL; | 833 | return NULL; |
833 | 834 | ||
834 | if (sym->name && !regexec(&call_regex, sym->name, 0, NULL, 0)) | 835 | if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0)) |
835 | return sym; | 836 | return sym; |
836 | 837 | ||
837 | return NULL; | 838 | return NULL; |
@@ -844,7 +845,7 @@ static struct symbol *call__match(struct symbol *sym) | |||
844 | static int | 845 | static int |
845 | hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, | 846 | hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, |
846 | struct symbol *sym, __u64 ip, struct ip_chain_event *chain, | 847 | struct symbol *sym, __u64 ip, struct ip_chain_event *chain, |
847 | char level, __u64 count) | 848 | char level, __u64 count) |
848 | { | 849 | { |
849 | struct rb_node **p = &hist.rb_node; | 850 | struct rb_node **p = &hist.rb_node; |
850 | struct rb_node *parent = NULL; | 851 | struct rb_node *parent = NULL; |
@@ -860,7 +861,7 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, | |||
860 | }; | 861 | }; |
861 | int cmp; | 862 | int cmp; |
862 | 863 | ||
863 | if (sort__has_call && chain) { | 864 | if (sort__has_parent && chain) { |
864 | int i, nr = chain->hv; | 865 | int i, nr = chain->hv; |
865 | struct symbol *sym; | 866 | struct symbol *sym; |
866 | struct dso *dso; | 867 | struct dso *dso; |
@@ -870,22 +871,22 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, | |||
870 | ip = chain->ips[nr + i]; | 871 | ip = chain->ips[nr + i]; |
871 | dso = kernel_dso; | 872 | dso = kernel_dso; |
872 | sym = resolve_symbol(thread, NULL, &dso, &ip); | 873 | sym = resolve_symbol(thread, NULL, &dso, &ip); |
873 | entry.call = call__match(sym); | 874 | entry.parent = call__match(sym); |
874 | if (entry.call) | 875 | if (entry.parent) |
875 | goto got_call; | 876 | goto got_parent; |
876 | } | 877 | } |
877 | nr += i; | 878 | nr += i; |
878 | 879 | ||
879 | for (i = 0; i < chain->user; i++) { | 880 | for (i = 0; i < chain->user; i++) { |
880 | ip = chain->ips[nr + i]; | 881 | ip = chain->ips[nr + i]; |
881 | sym = resolve_symbol(thread, NULL, NULL, &ip); | 882 | sym = resolve_symbol(thread, NULL, NULL, &ip); |
882 | entry.call = call__match(sym); | 883 | entry.parent = call__match(sym); |
883 | if (entry.call) | 884 | if (entry.parent) |
884 | goto got_call; | 885 | goto got_parent; |
885 | } | 886 | } |
886 | nr += i; | 887 | nr += i; |
887 | } | 888 | } |
888 | got_call: | 889 | got_parent: |
889 | 890 | ||
890 | while (*p != NULL) { | 891 | while (*p != NULL) { |
891 | parent = *p; | 892 | parent = *p; |
@@ -1457,11 +1458,11 @@ static const struct option options[] = { | |||
1457 | "dump raw trace in ASCII"), | 1458 | "dump raw trace in ASCII"), |
1458 | OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), | 1459 | OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), |
1459 | OPT_STRING('s', "sort", &sort_order, "key[,key2...]", | 1460 | OPT_STRING('s', "sort", &sort_order, "key[,key2...]", |
1460 | "sort by key(s): pid, comm, dso, symbol. Default: pid,symbol"), | 1461 | "sort by key(s): pid, comm, dso, symbol, parent"), |
1461 | OPT_BOOLEAN('P', "full-paths", &full_paths, | 1462 | OPT_BOOLEAN('P', "full-paths", &full_paths, |
1462 | "Don't shorten the pathnames taking into account the cwd"), | 1463 | "Don't shorten the pathnames taking into account the cwd"), |
1463 | OPT_STRING('c', "call", &call, "regex", | 1464 | OPT_STRING('p', "parent", &parent_pattern, "regex", |
1464 | "regex to use for --sort call"), | 1465 | "regex filter to identify parent, see: '--sort parent'"), |
1465 | OPT_END() | 1466 | OPT_END() |
1466 | }; | 1467 | }; |
1467 | 1468 | ||