aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill Smelkov <kirr@landau.phys.spbu.ru>2010-02-03 13:52:08 -0500
committerIngo Molnar <mingo@elte.hu>2010-02-04 03:33:28 -0500
commit6cff0e8dbaa4d5d822a814e5028683d7e71c3291 (patch)
treec18d3d87b33b0d22b73990e0f7168b40149c00c5
parent7a2b6209863626cf8362e5ff4653491558f91e67 (diff)
perf top: Teach it to autolocate vmlinux
By relying on logic in dso__load_kernel_sym(), we can automatically load vmlinux. The only thing which needs to be adjusted, is how --sym-annotate option is handled - now we can't rely on vmlinux been loaded until full successful pass of dso__load_vmlinux(), but that's not the case if we'll do sym_filter_entry setup in symbol_filter(). So move this step right after event__process_sample() where we know the whole dso__load_kernel_sym() pass is done. By the way, though conceptually similar `perf top` still can't annotate userspace - see next patches with fixes. Signed-off-by: Kirill Smelkov <kirr@landau.phys.spbu.ru> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Mike Galbraith <efault@gmx.de> LKML-Reference: <1265223128-11786-9-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--tools/perf/Documentation/perf-top.txt2
-rw-r--r--tools/perf/builtin-top.c39
2 files changed, 24 insertions, 17 deletions
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index 4a7d558dc309..785b9fc32a46 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -74,7 +74,7 @@ OPTIONS
74 74
75-s <symbol>:: 75-s <symbol>::
76--sym-annotate=<symbol>:: 76--sym-annotate=<symbol>::
77 Annotate this symbol. Requires -k option. 77 Annotate this symbol.
78 78
79-v:: 79-v::
80--verbose:: 80--verbose::
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 1fc018e048e1..83c09c8f28ed 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -94,6 +94,7 @@ struct source_line {
94 94
95static char *sym_filter = NULL; 95static char *sym_filter = NULL;
96struct sym_entry *sym_filter_entry = NULL; 96struct sym_entry *sym_filter_entry = NULL;
97struct sym_entry *sym_filter_entry_sched = NULL;
97static int sym_pcnt_filter = 5; 98static int sym_pcnt_filter = 5;
98static int sym_counter = 0; 99static int sym_counter = 0;
99static int display_weighted = -1; 100static int display_weighted = -1;
@@ -695,11 +696,9 @@ static void print_mapped_keys(void)
695 696
696 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter); 697 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter);
697 698
698 if (symbol_conf.vmlinux_name) { 699 fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter);
699 fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter); 700 fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL");
700 fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL"); 701 fprintf(stdout, "\t[S] stop annotation.\n");
701 fprintf(stdout, "\t[S] stop annotation.\n");
702 }
703 702
704 if (nr_counters > 1) 703 if (nr_counters > 1)
705 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0); 704 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0);
@@ -725,14 +724,13 @@ static int key_mapped(int c)
725 case 'Q': 724 case 'Q':
726 case 'K': 725 case 'K':
727 case 'U': 726 case 'U':
727 case 'F':
728 case 's':
729 case 'S':
728 return 1; 730 return 1;
729 case 'E': 731 case 'E':
730 case 'w': 732 case 'w':
731 return nr_counters > 1 ? 1 : 0; 733 return nr_counters > 1 ? 1 : 0;
732 case 'F':
733 case 's':
734 case 'S':
735 return symbol_conf.vmlinux_name ? 1 : 0;
736 default: 734 default:
737 break; 735 break;
738 } 736 }
@@ -910,8 +908,12 @@ static int symbol_filter(struct map *map, struct symbol *sym)
910 syme = symbol__priv(sym); 908 syme = symbol__priv(sym);
911 syme->map = map; 909 syme->map = map;
912 syme->src = NULL; 910 syme->src = NULL;
913 if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) 911
914 sym_filter_entry = syme; 912 if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) {
913 /* schedule initial sym_filter_entry setup */
914 sym_filter_entry_sched = syme;
915 sym_filter = NULL;
916 }
915 917
916 for (i = 0; skip_symbols[i]; i++) { 918 for (i = 0; skip_symbols[i]; i++) {
917 if (!strcmp(skip_symbols[i], name)) { 919 if (!strcmp(skip_symbols[i], name)) {
@@ -976,6 +978,13 @@ static void event__process_sample(const event_t *self,
976 return; 978 return;
977 } 979 }
978 980
981 /* let's see, whether we need to install initial sym_filter_entry */
982 if (sym_filter_entry_sched) {
983 sym_filter_entry = sym_filter_entry_sched;
984 sym_filter_entry_sched = NULL;
985 parse_source(sym_filter_entry);
986 }
987
979 syme = symbol__priv(al.sym); 988 syme = symbol__priv(al.sym);
980 if (!syme->skip) { 989 if (!syme->skip) {
981 syme->count[counter]++; 990 syme->count[counter]++;
@@ -1270,7 +1279,7 @@ static const struct option options[] = {
1270 OPT_BOOLEAN('i', "inherit", &inherit, 1279 OPT_BOOLEAN('i', "inherit", &inherit,
1271 "child tasks inherit counters"), 1280 "child tasks inherit counters"),
1272 OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name", 1281 OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name",
1273 "symbol to annotate - requires -k option"), 1282 "symbol to annotate"),
1274 OPT_BOOLEAN('z', "zero", &zero, 1283 OPT_BOOLEAN('z', "zero", &zero,
1275 "zero history across updates"), 1284 "zero history across updates"),
1276 OPT_INTEGER('F', "freq", &freq, 1285 OPT_INTEGER('F', "freq", &freq,
@@ -1306,16 +1315,14 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1306 1315
1307 symbol_conf.priv_size = (sizeof(struct sym_entry) + 1316 symbol_conf.priv_size = (sizeof(struct sym_entry) +
1308 (nr_counters + 1) * sizeof(unsigned long)); 1317 (nr_counters + 1) * sizeof(unsigned long));
1309 if (symbol_conf.vmlinux_name == NULL) 1318
1310 symbol_conf.try_vmlinux_path = true; 1319 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
1311 if (symbol__init() < 0) 1320 if (symbol__init() < 0)
1312 return -1; 1321 return -1;
1313 1322
1314 if (delay_secs < 1) 1323 if (delay_secs < 1)
1315 delay_secs = 1; 1324 delay_secs = 1;
1316 1325
1317 parse_source(sym_filter_entry);
1318
1319 /* 1326 /*
1320 * User specified count overrides default frequency. 1327 * User specified count overrides default frequency.
1321 */ 1328 */