From 78f7defedbb4da73b9a07635c357c1afcaa55c8f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 4 Feb 2011 09:45:46 -0200 Subject: perf annotate: Move annotate functions to util/ They will be used by perf top, so that we have just one set of routines to do annotation. Rename "struct sym_priv" to "struct annotation", etc, to clarify this code a bit. Rename "struct sym_ext" to "struct source_line", to give it a meaningful name, that clarifies that it is a the result of an addr2line call, that is sorted by percentage one particular source code line appeared in the annotation. And since we're moving things around also rename 'sym_hist->ip' to 'sym_hist->addr' as we want to do data structure annotation at some point. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 tools/perf/util/annotate.h (limited to 'tools/perf/util/annotate.h') diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h new file mode 100644 index 000000000000..6e2fbc205299 --- /dev/null +++ b/tools/perf/util/annotate.h @@ -0,0 +1,65 @@ +#ifndef __PERF_ANNOTATE_H +#define __PERF_ANNOTATE_H + +#include +#include "types.h" +#include "symbol.h" +#include +#include + +struct objdump_line { + struct list_head node; + s64 offset; + char *line; +}; + +void objdump_line__free(struct objdump_line *self); +struct objdump_line *objdump__get_next_ip_line(struct list_head *head, + struct objdump_line *pos); + +struct sym_hist { + u64 sum; + u64 addr[0]; +}; + +struct source_line { + struct rb_node node; + double percent; + char *path; +}; + +struct annotation { + struct sym_hist *histogram; + struct source_line *src_line; +}; + +struct sannotation { + struct annotation annotation; + struct symbol symbol; +}; + +static inline struct annotation *symbol__annotation(struct symbol *sym) +{ + struct sannotation *a = container_of(sym, struct sannotation, symbol); + return &a->annotation; +} + +int symbol__inc_addr_samples(struct symbol *sym, struct map *map, u64 addr); + +int symbol__annotate(struct symbol *sym, struct map *map, + struct list_head *head, size_t privsize); + +int symbol__tty_annotate(struct symbol *sym, struct map *map, + bool print_lines, bool full_paths); + +#ifdef NO_NEWT_SUPPORT +static inline int symbol__tui_annotate(symbol *sym __used, + struct map *map __used) +{ + return 0; +} +#else +int symbol__tui_annotate(struct symbol *sym, struct map *map); +#endif + +#endif /* __PERF_ANNOTATE_H */ -- cgit v1.2.2 From 2f525d0148ef2734c8a172201e5e1e9167a8a5fd Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 4 Feb 2011 13:43:24 -0200 Subject: perf annotate: Support multiple histograms in annotation The perf annotate tool continues aggregating everything on just one histograms, but to support the top model add support for one histogram perf evsel in the evlist. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.h | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'tools/perf/util/annotate.h') diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 6e2fbc205299..0a5069ca6dd7 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -28,9 +28,21 @@ struct source_line { char *path; }; +/** struct annotation - symbols with hits have this attached as in sannotation + * + * @histogram: Array of addr hit histograms per event being monitored + * @src_line: If 'print_lines' is specified, per source code line percentages + * + * src_line is allocated, percentages calculated and all sorted by percentage + * when the annotation is about to be presented, so the percentages are for + * one of the entries in the histogram array, i.e. for the event/counter being + * presented. It is deallocated right after symbol__{tui,tty,etc}_annotate + * returns. + */ struct annotation { - struct sym_hist *histogram; struct source_line *src_line; + struct sym_hist *histograms; + int sizeof_sym_hist; }; struct sannotation { @@ -38,28 +50,35 @@ struct sannotation { struct symbol symbol; }; +static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx) +{ + return ((void *)notes->histograms) + (notes->sizeof_sym_hist * idx); +} + static inline struct annotation *symbol__annotation(struct symbol *sym) { struct sannotation *a = container_of(sym, struct sannotation, symbol); return &a->annotation; } -int symbol__inc_addr_samples(struct symbol *sym, struct map *map, u64 addr); +int symbol__inc_addr_samples(struct symbol *sym, struct map *map, + int evidx, u64 addr); +int symbol__alloc_hist(struct symbol *sym, int nevents); int symbol__annotate(struct symbol *sym, struct map *map, struct list_head *head, size_t privsize); -int symbol__tty_annotate(struct symbol *sym, struct map *map, +int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, bool print_lines, bool full_paths); #ifdef NO_NEWT_SUPPORT static inline int symbol__tui_annotate(symbol *sym __used, - struct map *map __used) + struct map *map __used, int evidx __used) { return 0; } #else -int symbol__tui_annotate(struct symbol *sym, struct map *map); +int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx); #endif #endif /* __PERF_ANNOTATE_H */ -- cgit v1.2.2 From d040bd363824f9f0ad6610b91ee6c65f292c066c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 5 Feb 2011 15:37:31 -0200 Subject: perf annotate: Config options for symbol__tty_annotate Max line# that should be printed, minimum percentage filter, just like 'perf top', alas, due to it :-) Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/perf/util/annotate.h') diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 0a5069ca6dd7..6b707324e66f 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -69,7 +69,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, struct list_head *head, size_t privsize); int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, - bool print_lines, bool full_paths); + bool print_lines, bool full_paths, int min_pcnt, + int max_lines); #ifdef NO_NEWT_SUPPORT static inline int symbol__tui_annotate(symbol *sym __used, -- cgit v1.2.2 From f1e2701de02cff6d988b1dd49960620d5720cb89 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 5 Feb 2011 18:51:38 -0200 Subject: perf annotate: Separate objdump parsing from actual screen rendering Because in 'perf top' we'll need to parse just once and then, as samples come, render multiple times with evolving counter values. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools/perf/util/annotate.h') diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 6b707324e66f..53dd92de2615 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -67,6 +67,10 @@ int symbol__alloc_hist(struct symbol *sym, int nevents); int symbol__annotate(struct symbol *sym, struct map *map, struct list_head *head, size_t privsize); +void symbol__annotate_printf(struct symbol *sym, struct map *map, + struct list_head *head, int evidx, bool full_paths, + int min_pcnt, int max_lines); +void objdump_line_list__purge(struct list_head *head); int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, bool print_lines, bool full_paths, int min_pcnt, -- cgit v1.2.2 From 36532461a0f60bb36c5470a0326f7394f19db23c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 6 Feb 2011 14:54:44 -0200 Subject: perf top: Ditch private annotation code, share perf annotate's Next step: Live TUI annotation in perf top, just press enter on a symbol line. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'tools/perf/util/annotate.h') diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 53dd92de2615..b1253aadf340 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -42,6 +42,7 @@ struct source_line { struct annotation { struct source_line *src_line; struct sym_hist *histograms; + int nr_histograms; int sizeof_sym_hist; }; @@ -64,12 +65,16 @@ static inline struct annotation *symbol__annotation(struct symbol *sym) int symbol__inc_addr_samples(struct symbol *sym, struct map *map, int evidx, u64 addr); int symbol__alloc_hist(struct symbol *sym, int nevents); +void symbol__annotate_zero_histograms(struct symbol *sym); int symbol__annotate(struct symbol *sym, struct map *map, struct list_head *head, size_t privsize); -void symbol__annotate_printf(struct symbol *sym, struct map *map, - struct list_head *head, int evidx, bool full_paths, - int min_pcnt, int max_lines); +int symbol__annotate_printf(struct symbol *sym, struct map *map, + struct list_head *head, int evidx, bool full_paths, + int min_pcnt, int max_lines); +void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); +void symbol__annotate_decay_histogram(struct symbol *sym, + struct list_head *head, int evidx); void objdump_line_list__purge(struct list_head *head); int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, -- cgit v1.2.2 From a2221796256ea7b236cec6bf027c1c1de5b8ccd7 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 7 Feb 2011 15:32:18 +0100 Subject: perf annotate: Fix build error A small fix for when NO_NEWT_SUPPORT is defined. Add a missing "struct" to the function prototype. Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Tom Zanussi LKML-Reference: <20110207143218.GA31197@kryptos.osrc.amd.com> Signed-off-by: Borislav Petkov Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/util/annotate.h') diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index b1253aadf340..bc08b36a713a 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -82,7 +82,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, int max_lines); #ifdef NO_NEWT_SUPPORT -static inline int symbol__tui_annotate(symbol *sym __used, +static inline int symbol__tui_annotate(struct symbol *sym __used, struct map *map __used, int evidx __used) { return 0; -- cgit v1.2.2 From ce6f4fab4059cd72638a0cfa596a8ee2c79c1c8e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 8 Feb 2011 13:27:39 -0200 Subject: perf annotate: Move locking to struct annotation Since we'll need it when implementing the live annotate TUI browser. This also simplifies things a bit by having the list head for the source code to be in the dynamicly allocated part of struct annotation, that way we don't have to pass it around, it can be found from the struct symbol that is passed everywhere. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.h | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'tools/perf/util/annotate.h') diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index bc08b36a713a..b237c8678c22 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -28,22 +28,29 @@ struct source_line { char *path; }; -/** struct annotation - symbols with hits have this attached as in sannotation +/** struct annotated_source - symbols with hits have this attached as in sannotation * * @histogram: Array of addr hit histograms per event being monitored - * @src_line: If 'print_lines' is specified, per source code line percentages + * @lines: If 'print_lines' is specified, per source code line percentages + * @source: source parsed from objdump -dS * - * src_line is allocated, percentages calculated and all sorted by percentage + * lines is allocated, percentages calculated and all sorted by percentage * when the annotation is about to be presented, so the percentages are for * one of the entries in the histogram array, i.e. for the event/counter being * presented. It is deallocated right after symbol__{tui,tty,etc}_annotate * returns. */ -struct annotation { - struct source_line *src_line; - struct sym_hist *histograms; +struct annotated_source { + struct list_head source; + struct source_line *lines; int nr_histograms; int sizeof_sym_hist; + struct sym_hist histograms[0]; +}; + +struct annotation { + pthread_mutex_t lock; + struct annotated_source *src; }; struct sannotation { @@ -53,7 +60,8 @@ struct sannotation { static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx) { - return ((void *)notes->histograms) + (notes->sizeof_sym_hist * idx); + return (((void *)¬es->src->histograms) + + (notes->src->sizeof_sym_hist * idx)); } static inline struct annotation *symbol__annotation(struct symbol *sym) @@ -67,14 +75,12 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, int symbol__alloc_hist(struct symbol *sym, int nevents); void symbol__annotate_zero_histograms(struct symbol *sym); -int symbol__annotate(struct symbol *sym, struct map *map, - struct list_head *head, size_t privsize); -int symbol__annotate_printf(struct symbol *sym, struct map *map, - struct list_head *head, int evidx, bool full_paths, - int min_pcnt, int max_lines); +int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); +int symbol__annotate_init(struct map *map __used, struct symbol *sym); +int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, + bool full_paths, int min_pcnt, int max_lines); void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); -void symbol__annotate_decay_histogram(struct symbol *sym, - struct list_head *head, int evidx); +void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); void objdump_line_list__purge(struct list_head *head); int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, -- cgit v1.2.2 From d5e3d747007fdb541e57ed72e020ff0b94db3470 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 8 Feb 2011 15:29:25 -0200 Subject: 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 Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/perf/util/annotate.h') 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); int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); int symbol__annotate_init(struct map *map __used, struct symbol *sym); int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx, - bool full_paths, int min_pcnt, int max_lines); + bool full_paths, int min_pcnt, int max_lines, + int context); void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); void objdump_line_list__purge(struct list_head *head); -- cgit v1.2.2 From c97cf42219b7b6037d2f96c27a5f114f2383f828 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 22 Feb 2011 12:02:07 -0300 Subject: perf top: Live TUI Annotation Now one has just to press the right key, 'a' or Enter on the main 'perf top --tui' screen to live annotate the symbol under the cursor. The annotate window starts centered on the hottest line (the one with most samples so far) then TAB and shift+TAB can be used to go to the prev/next hot line. Pressing 'H' at any point will center again the screen on the hottest line. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools/perf/util/annotate.h') diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index e848803fcd48..c2c286896801 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -90,12 +90,14 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, #ifdef NO_NEWT_SUPPORT static inline int symbol__tui_annotate(struct symbol *sym __used, - struct map *map __used, int evidx __used) + struct map *map __used, + int evidx __used, int refresh __used) { return 0; } #else -int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx); +int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, + int refresh); #endif #endif /* __PERF_ANNOTATE_H */ -- cgit v1.2.2