aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung.kim@lge.com>2013-03-05 00:53:25 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-03-15 12:06:05 -0400
commitb1dd443296b4f8c6869eba790eec950f80392aea (patch)
tree1d0de8119e214001d96ad1663f5e537109017035 /tools/perf
parentbd64fcb8805d8e4575f95f0df22f43b74418a4ec (diff)
perf annotate: Add basic support to event group view
Add --group option to enable event grouping. When enabled, all the group members information will be shown with the leader so skip non-leader events. It only supports --stdio output currently. Later patches will extend additional features. $ perf annotate --group --stdio ... Percent | Source code & Disassembly of libpthread-2.15.so -------------------------------------------------------------------------------- : : : : Disassembly of section .text: : : 000000387dc0aa50 <__pthread_mutex_unlock_usercnt>: 8.08 2.40 5.29 : 387dc0aa50: mov %rdi,%rdx 0.00 0.00 0.00 : 387dc0aa53: mov 0x10(%rdi),%edi 0.00 0.00 0.00 : 387dc0aa56: mov %edi,%eax 0.00 0.80 0.00 : 387dc0aa58: and $0x7f,%eax 3.03 2.40 3.53 : 387dc0aa5b: test $0x7c,%dil 0.00 0.00 0.00 : 387dc0aa5f: jne 387dc0aaa9 <__pthread_mutex_unlock_use 0.00 0.00 0.00 : 387dc0aa61: test %eax,%eax 0.00 0.00 0.00 : 387dc0aa63: jne 387dc0aa85 <__pthread_mutex_unlock_use 0.00 0.00 0.00 : 387dc0aa65: and $0x80,%edi 0.00 0.00 0.00 : 387dc0aa6b: test %esi,%esi 3.03 5.60 7.06 : 387dc0aa6d: movl $0x0,0x8(%rdx) 0.00 0.00 0.59 : 387dc0aa74: je 387dc0aa7a <__pthread_mutex_unlock_use 0.00 0.00 0.00 : 387dc0aa76: subl $0x1,0xc(%rdx) 2.02 5.60 1.18 : 387dc0aa7a: mov %edi,%esi 0.00 0.00 0.00 : 387dc0aa7c: lock decl (%rdx) 83.84 83.20 82.35 : 387dc0aa7f: jne 387dc0aada <_L_unlock_586> 0.00 0.00 0.00 : 387dc0aa81: nop 0.00 0.00 0.00 : 387dc0aa82: xor %eax,%eax 0.00 0.00 0.00 : 387dc0aa84: retq ... Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Andi Kleen <andi@firstfloor.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Pekka Enberg <penberg@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1362462812-30885-6-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-annotate.txt3
-rw-r--r--tools/perf/builtin-annotate.c7
-rw-r--r--tools/perf/util/annotate.c64
3 files changed, 63 insertions, 11 deletions
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index 5ad07ef417f0..e9cd39a92dc2 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -93,6 +93,9 @@ OPTIONS
93--skip-missing:: 93--skip-missing::
94 Skip symbols that cannot be annotated. 94 Skip symbols that cannot be annotated.
95 95
96--group::
97 Show event group information together
98
96SEE ALSO 99SEE ALSO
97-------- 100--------
98linkperf:perf-record[1], linkperf:perf-report[1] 101linkperf:perf-record[1], linkperf:perf-report[1]
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 2f015a99481b..ae36f3cb5410 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -232,6 +232,11 @@ static int __cmd_annotate(struct perf_annotate *ann)
232 total_nr_samples += nr_samples; 232 total_nr_samples += nr_samples;
233 hists__collapse_resort(hists); 233 hists__collapse_resort(hists);
234 hists__output_resort(hists); 234 hists__output_resort(hists);
235
236 if (symbol_conf.event_group &&
237 !perf_evsel__is_group_leader(pos))
238 continue;
239
235 hists__find_annotations(hists, pos, ann); 240 hists__find_annotations(hists, pos, ann);
236 } 241 }
237 } 242 }
@@ -314,6 +319,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
314 "Specify disassembler style (e.g. -M intel for intel syntax)"), 319 "Specify disassembler style (e.g. -M intel for intel syntax)"),
315 OPT_STRING(0, "objdump", &objdump_path, "path", 320 OPT_STRING(0, "objdump", &objdump_path, "path",
316 "objdump binary to use for disassembly and annotations"), 321 "objdump binary to use for disassembly and annotations"),
322 OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
323 "Show event group information together"),
317 OPT_END() 324 OPT_END()
318 }; 325 };
319 326
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index ae71325d3dc7..0955cff5b0ef 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -638,7 +638,9 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
638 638
639 if (dl->offset != -1) { 639 if (dl->offset != -1) {
640 const char *path = NULL; 640 const char *path = NULL;
641 double percent; 641 double percent, max_percent = 0.0;
642 double *ppercents = &percent;
643 int i, nr_percent = 1;
642 const char *color; 644 const char *color;
643 struct annotation *notes = symbol__annotation(sym); 645 struct annotation *notes = symbol__annotation(sym);
644 s64 offset = dl->offset; 646 s64 offset = dl->offset;
@@ -647,10 +649,27 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
647 649
648 next = disasm__get_next_ip_line(&notes->src->source, dl); 650 next = disasm__get_next_ip_line(&notes->src->source, dl);
649 651
650 percent = disasm__calc_percent(notes, evsel->idx, offset, 652 if (symbol_conf.event_group &&
651 next ? next->offset : (s64) len, 653 perf_evsel__is_group_leader(evsel) &&
652 &path); 654 evsel->nr_members > 1) {
653 if (percent < min_pcnt) 655 nr_percent = evsel->nr_members;
656 ppercents = calloc(nr_percent, sizeof(double));
657 if (ppercents == NULL)
658 return -1;
659 }
660
661 for (i = 0; i < nr_percent; i++) {
662 percent = disasm__calc_percent(notes,
663 evsel->idx + i, offset,
664 next ? next->offset : (s64) len,
665 &path);
666
667 ppercents[i] = percent;
668 if (percent > max_percent)
669 max_percent = percent;
670 }
671
672 if (max_percent < min_pcnt)
654 return -1; 673 return -1;
655 674
656 if (max_lines && printed >= max_lines) 675 if (max_lines && printed >= max_lines)
@@ -665,7 +684,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
665 } 684 }
666 } 685 }
667 686
668 color = get_percent_color(percent); 687 color = get_percent_color(max_percent);
669 688
670 /* 689 /*
671 * Also color the filename and line if needed, with 690 * Also color the filename and line if needed, with
@@ -681,20 +700,35 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
681 } 700 }
682 } 701 }
683 702
684 color_fprintf(stdout, color, " %7.2f", percent); 703 for (i = 0; i < nr_percent; i++) {
704 percent = ppercents[i];
705 color = get_percent_color(percent);
706 color_fprintf(stdout, color, " %7.2f", percent);
707 }
708
685 printf(" : "); 709 printf(" : ");
686 color_fprintf(stdout, PERF_COLOR_MAGENTA, " %" PRIx64 ":", addr); 710 color_fprintf(stdout, PERF_COLOR_MAGENTA, " %" PRIx64 ":", addr);
687 color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", dl->line); 711 color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", dl->line);
712
713 if (ppercents != &percent)
714 free(ppercents);
715
688 } else if (max_lines && printed >= max_lines) 716 } else if (max_lines && printed >= max_lines)
689 return 1; 717 return 1;
690 else { 718 else {
719 int width = 8;
720
691 if (queue) 721 if (queue)
692 return -1; 722 return -1;
693 723
724 if (symbol_conf.event_group &&
725 perf_evsel__is_group_leader(evsel))
726 width *= evsel->nr_members;
727
694 if (!*dl->line) 728 if (!*dl->line)
695 printf(" :\n"); 729 printf(" %*s:\n", width, " ");
696 else 730 else
697 printf(" : %s\n", dl->line); 731 printf(" %*s: %s\n", width, " ", dl->line);
698 } 732 }
699 733
700 return 0; 734 return 0;
@@ -1077,6 +1111,8 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
1077 int printed = 2, queue_len = 0; 1111 int printed = 2, queue_len = 0;
1078 int more = 0; 1112 int more = 0;
1079 u64 len; 1113 u64 len;
1114 int width = 8;
1115 int namelen;
1080 1116
1081 filename = strdup(dso->long_name); 1117 filename = strdup(dso->long_name);
1082 if (!filename) 1118 if (!filename)
@@ -1088,9 +1124,15 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
1088 d_filename = basename(filename); 1124 d_filename = basename(filename);
1089 1125
1090 len = symbol__size(sym); 1126 len = symbol__size(sym);
1127 namelen = strlen(d_filename);
1128
1129 if (symbol_conf.event_group && perf_evsel__is_group_leader(evsel))
1130 width *= evsel->nr_members;
1091 1131
1092 printf(" Percent | Source code & Disassembly of %s\n", d_filename); 1132 printf(" %-*.*s| Source code & Disassembly of %s\n",
1093 printf("------------------------------------------------\n"); 1133 width, width, "Percent", d_filename);
1134 printf("-%-*.*s-------------------------------------\n",
1135 width+namelen, width+namelen, graph_dotted_line);
1094 1136
1095 if (verbose) 1137 if (verbose)
1096 symbol__annotate_hits(sym, evsel); 1138 symbol__annotate_hits(sym, evsel);