diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-02-08 12:29:25 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-02-08 12:29:25 -0500 |
commit | d5e3d747007fdb541e57ed72e020ff0b94db3470 (patch) | |
tree | 96dc1bf70895e24f3b85f44ee03cd0896105762a /tools/perf | |
parent | ce6f4fab4059cd72638a0cfa596a8ee2c79c1c8e (diff) |
perf annotate: Fix annotate context lines regression
The live annotation done in 'perf top' needs to limit the context before
lines that aren't filtered out by the min percent filter, if we don't do
that, the screen in a tty often is not enough for showing what is
interesting: lines with hits and a few source code lines before it.
Reported-by: Mike Galbraith <efault@gmx.de>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/builtin-top.c | 2 | ||||
-rw-r--r-- | tools/perf/util/annotate.c | 47 | ||||
-rw-r--r-- | tools/perf/util/annotate.h | 3 |
3 files changed, 43 insertions, 9 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 7dbf22d096b8..210c736e6db4 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -231,7 +231,7 @@ static void show_details(struct sym_entry *syme) | |||
231 | printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); | 231 | printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); |
232 | 232 | ||
233 | more = symbol__annotate_printf(symbol, syme->map, top.sym_evsel->idx, | 233 | more = symbol__annotate_printf(symbol, syme->map, top.sym_evsel->idx, |
234 | 0, sym_pcnt_filter, top.print_entries); | 234 | 0, sym_pcnt_filter, top.print_entries, 4); |
235 | if (top.zero) | 235 | if (top.zero) |
236 | symbol__annotate_zero_histogram(symbol, top.sym_evsel->idx); | 236 | symbol__annotate_zero_histogram(symbol, top.sym_evsel->idx); |
237 | else | 237 | else |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index c777bdaf91da..02976b895f27 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -111,7 +111,8 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head, | |||
111 | 111 | ||
112 | static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, | 112 | static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, |
113 | int evidx, u64 len, int min_pcnt, | 113 | int evidx, u64 len, int min_pcnt, |
114 | int printed, int max_lines) | 114 | int printed, int max_lines, |
115 | struct objdump_line *queue) | ||
115 | { | 116 | { |
116 | static const char *prev_line; | 117 | static const char *prev_line; |
117 | static const char *prev_color; | 118 | static const char *prev_color; |
@@ -150,6 +151,15 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, | |||
150 | if (max_lines && printed >= max_lines) | 151 | if (max_lines && printed >= max_lines) |
151 | return 1; | 152 | return 1; |
152 | 153 | ||
154 | if (queue != NULL) { | ||
155 | list_for_each_entry_from(queue, ¬es->src->source, node) { | ||
156 | if (queue == oline) | ||
157 | break; | ||
158 | objdump_line__print(queue, sym, evidx, len, | ||
159 | 0, 0, 1, NULL); | ||
160 | } | ||
161 | } | ||
162 | |||
153 | color = get_percent_color(percent); | 163 | color = get_percent_color(percent); |
154 | 164 | ||
155 | /* | 165 | /* |
@@ -172,6 +182,9 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym, | |||
172 | } else if (max_lines && printed >= max_lines) | 182 | } else if (max_lines && printed >= max_lines) |
173 | return 1; | 183 | return 1; |
174 | else { | 184 | else { |
185 | if (queue) | ||
186 | return -1; | ||
187 | |||
175 | if (!*oline->line) | 188 | if (!*oline->line) |
176 | printf(" :\n"); | 189 | printf(" :\n"); |
177 | else | 190 | else |
@@ -452,13 +465,14 @@ static void symbol__annotate_hits(struct symbol *sym, int evidx) | |||
452 | } | 465 | } |
453 | 466 | ||
454 | int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, | 467 | int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, |
455 | bool full_paths, int min_pcnt, int max_lines) | 468 | bool full_paths, int min_pcnt, int max_lines, |
469 | int context) | ||
456 | { | 470 | { |
457 | struct dso *dso = map->dso; | 471 | struct dso *dso = map->dso; |
458 | const char *filename = dso->long_name, *d_filename; | 472 | const char *filename = dso->long_name, *d_filename; |
459 | struct annotation *notes = symbol__annotation(sym); | 473 | struct annotation *notes = symbol__annotation(sym); |
460 | struct objdump_line *pos; | 474 | struct objdump_line *pos, *queue = NULL; |
461 | int printed = 2; | 475 | int printed = 2, queue_len = 0; |
462 | int more = 0; | 476 | int more = 0; |
463 | u64 len; | 477 | u64 len; |
464 | 478 | ||
@@ -476,10 +490,20 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, | |||
476 | symbol__annotate_hits(sym, evidx); | 490 | symbol__annotate_hits(sym, evidx); |
477 | 491 | ||
478 | list_for_each_entry(pos, ¬es->src->source, node) { | 492 | list_for_each_entry(pos, ¬es->src->source, node) { |
493 | if (context && queue == NULL) { | ||
494 | queue = pos; | ||
495 | queue_len = 0; | ||
496 | } | ||
497 | |||
479 | switch (objdump_line__print(pos, sym, evidx, len, min_pcnt, | 498 | switch (objdump_line__print(pos, sym, evidx, len, min_pcnt, |
480 | printed, max_lines)) { | 499 | printed, max_lines, queue)) { |
481 | case 0: | 500 | case 0: |
482 | ++printed; | 501 | ++printed; |
502 | if (context) { | ||
503 | printed += queue_len; | ||
504 | queue = NULL; | ||
505 | queue_len = 0; | ||
506 | } | ||
483 | break; | 507 | break; |
484 | case 1: | 508 | case 1: |
485 | /* filtered by max_lines */ | 509 | /* filtered by max_lines */ |
@@ -487,7 +511,16 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, | |||
487 | break; | 511 | break; |
488 | case -1: | 512 | case -1: |
489 | default: | 513 | default: |
490 | /* filtered by min_pcnt */ | 514 | /* |
515 | * Filtered by min_pcnt or non IP lines when | ||
516 | * context != 0 | ||
517 | */ | ||
518 | if (!context) | ||
519 | break; | ||
520 | if (queue_len == context) | ||
521 | queue = list_entry(queue->node.next, typeof(*queue), node); | ||
522 | else | ||
523 | ++queue_len; | ||
491 | break; | 524 | break; |
492 | } | 525 | } |
493 | } | 526 | } |
@@ -550,7 +583,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, | |||
550 | } | 583 | } |
551 | 584 | ||
552 | symbol__annotate_printf(sym, map, evidx, full_paths, | 585 | symbol__annotate_printf(sym, map, evidx, full_paths, |
553 | min_pcnt, max_lines); | 586 | min_pcnt, max_lines, 0); |
554 | if (print_lines) | 587 | if (print_lines) |
555 | symbol__free_source_line(sym, len); | 588 | symbol__free_source_line(sym, len); |
556 | 589 | ||
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index b237c8678c22..e848803fcd48 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
@@ -78,7 +78,8 @@ void symbol__annotate_zero_histograms(struct symbol *sym); | |||
78 | int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); | 78 | int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); |
79 | int symbol__annotate_init(struct map *map __used, struct symbol *sym); | 79 | int symbol__annotate_init(struct map *map __used, struct symbol *sym); |
80 | int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, | 80 | int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, |
81 | bool full_paths, int min_pcnt, int max_lines); | 81 | bool full_paths, int min_pcnt, int max_lines, |
82 | int context); | ||
82 | void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); | 83 | void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); |
83 | void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); | 84 | void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); |
84 | void objdump_line_list__purge(struct list_head *head); | 85 | void objdump_line_list__purge(struct list_head *head); |