From 46e3e055ce69a00d735e458445ab1d24718ff751 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 22 May 2010 11:25:40 -0300 Subject: perf annotate: Add TUI interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When annotating multiple entries, for instance, when running simply as: $ perf annotate the right and left keys, as well as TAB can be used to cycle thru the multiple symbols being annotated. If one doesn't like TUI annotate, disable it by editing ~/.perfconfig and adding: [tui] annotate = off Just like it is possible for report. Cc: Frédéric Weisbecker 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/builtin-annotate.c | 61 +++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 16 deletions(-) (limited to 'tools/perf/builtin-annotate.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 77bcc9b130f..08278eda31a 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -277,7 +277,7 @@ static void hist_entry__print_hits(struct hist_entry *self) printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum); } -static void annotate_sym(struct hist_entry *he) +static int hist_entry__tty_annotate(struct hist_entry *he) { struct map *map = he->ms.map; struct dso *dso = map->dso; @@ -288,7 +288,7 @@ static void annotate_sym(struct hist_entry *he) struct objdump_line *pos, *n; if (hist_entry__annotate(he, &head) < 0) - return; + return -1; if (full_paths) d_filename = filename; @@ -317,30 +317,59 @@ static void annotate_sym(struct hist_entry *he) if (print_line) free_source_line(he, len); + + return 0; } static void hists__find_annotations(struct hists *self) { - struct rb_node *nd; + struct rb_node *first = rb_first(&self->entries), *nd = first; + int key = KEY_RIGHT; - for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { + while (nd) { struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); struct sym_priv *priv; - if (he->ms.sym == NULL) - continue; + if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned) + goto find_next; priv = symbol__priv(he->ms.sym); - if (priv->hist == NULL) + if (priv->hist == NULL) { +find_next: + if (key == KEY_LEFT) + nd = rb_prev(nd); + else + nd = rb_next(nd); continue; + } - annotate_sym(he); - /* - * Since we have a hist_entry per IP for the same symbol, free - * he->ms.sym->hist to signal we already processed this symbol. - */ - free(priv->hist); - priv->hist = NULL; + if (use_browser) { + key = hist_entry__tui_annotate(he); + if (is_exit_key(key)) + break; + switch (key) { + case KEY_RIGHT: + case '\t': + nd = rb_next(nd); + break; + case KEY_LEFT: + if (nd == first) + continue; + nd = rb_prev(nd); + default: + break; + } + } else { + hist_entry__tty_annotate(he); + nd = rb_next(nd); + /* + * Since we have a hist_entry per IP for the same + * symbol, free he->ms.sym->hist to signal we already + * processed this symbol. + */ + free(priv->hist); + priv->hist = NULL; + } } } @@ -416,6 +445,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) { argc = parse_options(argc, argv, options, annotate_usage, 0); + setup_browser(); + symbol_conf.priv_size = sizeof(struct sym_priv); symbol_conf.try_vmlinux_path = true; @@ -435,8 +466,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) sym_hist_filter = argv[0]; } - setup_pager(); - if (field_sep && *field_sep == '.') { pr_err("'.' is the only non valid --field-separator argument\n"); return -1; -- cgit v1.2.3-70-g09d2 From 62e3436b5f3461662929eae102beefbd12127cb1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 26 May 2010 13:22:26 -0300 Subject: perf tui: Reset use_browser if stdout is not a tty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The newt initialization routines weren't being called because the output was a file (perf annotate > /tmp/bla) but use_browser was still 1, because ~/.perfconfig had it as 'on', so, later on newt routines segfaulted. Cc: Frédéric Weisbecker 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/builtin-annotate.c | 2 +- tools/perf/util/newt.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/perf/builtin-annotate.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 08278eda31a..96db5248e99 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -343,7 +343,7 @@ find_next: continue; } - if (use_browser) { + if (use_browser > 0) { key = hist_entry__tui_annotate(he); if (is_exit_key(key)) break; diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index d54c540f49d..cf182ca132f 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c @@ -1139,6 +1139,7 @@ void setup_browser(void) struct newtPercentTreeColors *c = &defaultPercentTreeColors; if (!isatty(1) || !use_browser || dump_trace) { + use_browser = 0; setup_pager(); return; } -- cgit v1.2.3-70-g09d2 From 41a37e20178b081193b08b228030d8f562bfee62 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 4 Jun 2010 08:02:07 -0300 Subject: perf tools: Make event__preprocess_sample parse the sample MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplifying the tools that were using both in sequence and allowing upcoming simplifications, such as Arun's patch to sort by cpus. Cc: David S. Miller Cc: Frédéric 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/builtin-annotate.c | 6 ++---- tools/perf/builtin-diff.c | 7 +------ tools/perf/builtin-report.c | 26 +------------------------- tools/perf/builtin-top.c | 4 +++- tools/perf/util/callchain.c | 2 +- tools/perf/util/callchain.h | 2 +- tools/perf/util/event.c | 33 +++++++++++++++++++++++++++++---- tools/perf/util/event.h | 5 +++-- 8 files changed, 41 insertions(+), 44 deletions(-) (limited to 'tools/perf/builtin-annotate.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 96db5248e99..fd20670ce98 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -61,11 +61,9 @@ static int hists__add_entry(struct hists *self, struct addr_location *al) static int process_sample_event(event_t *event, struct perf_session *session) { struct addr_location al; + struct sample_data data; - dump_printf("(IP, %d): %d: %#Lx\n", event->header.misc, - event->ip.pid, event->ip.ip); - - if (event__preprocess_sample(event, session, &al, NULL) < 0) { + if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index a6e2fdc7a04..39e6627ebb9 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -35,10 +35,7 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi struct addr_location al; struct sample_data data = { .period = 1, }; - dump_printf("(IP, %d): %d: %#Lx\n", event->header.misc, - event->ip.pid, event->ip.ip); - - if (event__preprocess_sample(event, session, &al, NULL) < 0) { + if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; @@ -47,8 +44,6 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi if (al.filtered || al.sym == NULL) return 0; - event__parse_sample(event, session->sample_type, &data); - if (hists__add_entry(&session->hists, &al, data.period)) { pr_warning("problem incrementing symbol period, skipping event\n"); return -1; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 207da184980..371a3c99580 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -155,31 +155,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) struct addr_location al; struct perf_event_attr *attr; - event__parse_sample(event, session->sample_type, &data); - - dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld cpu:%d\n", - event->header.misc, data.pid, data.tid, data.ip, - data.period, data.cpu); - - if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { - unsigned int i; - - dump_printf("... chain: nr:%Lu\n", data.callchain->nr); - - if (!ip_callchain__valid(data.callchain, event)) { - pr_debug("call-chain problem with event, " - "skipping it.\n"); - return 0; - } - - if (dump_trace) { - for (i = 0; i < data.callchain->nr; i++) - dump_printf("..... %2d: %016Lx\n", - i, data.callchain->ips[i]); - } - } - - if (event__preprocess_sample(event, session, &al, NULL) < 0) { + if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { fprintf(stderr, "problem processing %d event, skipping it.\n", event->header.type); return -1; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 45014ef1105..1e8e92e317b 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -983,6 +983,7 @@ static void event__process_sample(const event_t *self, u64 ip = self->ip.ip; struct sym_entry *syme; struct addr_location al; + struct sample_data data; struct machine *machine; u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; @@ -1025,7 +1026,8 @@ static void event__process_sample(const event_t *self, if (self->header.misc & PERF_RECORD_MISC_EXACT_IP) exact_samples++; - if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 || + if (event__preprocess_sample(self, session, &al, &data, + symbol_filter) < 0 || al.filtered) return; diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 62b69ad4aa7..e63c997d6c1 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -18,7 +18,7 @@ #include "util.h" #include "callchain.h" -bool ip_callchain__valid(struct ip_callchain *chain, event_t *event) +bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event) { unsigned int chain_size = event->header.size; chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event; diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 1ca73e4a272..809850fb75f 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -60,5 +60,5 @@ int register_callchain_param(struct callchain_param *param); int append_chain(struct callchain_node *root, struct ip_callchain *chain, struct map_symbol *syms); -bool ip_callchain__valid(struct ip_callchain *chain, event_t *event); +bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event); #endif /* __PERF_CALLCHAIN_H */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 891753255f5..ed3e14ff6df 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -655,11 +655,36 @@ static void dso__calc_col_width(struct dso *self) } int event__preprocess_sample(const event_t *self, struct perf_session *session, - struct addr_location *al, symbol_filter_t filter) + struct addr_location *al, struct sample_data *data, + symbol_filter_t filter) { u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - struct thread *thread = perf_session__findnew(session, self->ip.pid); + struct thread *thread; + + event__parse_sample(self, session->sample_type, data); + + dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld cpu:%d\n", + self->header.misc, data->pid, data->tid, data->ip, + data->period, data->cpu); + + if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { + unsigned int i; + + dump_printf("... chain: nr:%Lu\n", data->callchain->nr); + if (!ip_callchain__valid(data->callchain, self)) { + pr_debug("call-chain problem with event, " + "skipping it.\n"); + goto out_filtered; + } + + if (dump_trace) { + for (i = 0; i < data->callchain->nr; i++) + dump_printf("..... %2d: %016Lx\n", + i, data->callchain->ips[i]); + } + } + thread = perf_session__findnew(session, self->ip.pid); if (thread == NULL) return -1; @@ -724,9 +749,9 @@ out_filtered: return 0; } -int event__parse_sample(event_t *event, u64 type, struct sample_data *data) +int event__parse_sample(const event_t *event, u64 type, struct sample_data *data) { - u64 *array = event->sample.array; + const u64 *array = event->sample.array; if (type & PERF_SAMPLE_IP) { data->ip = event->ip.ip; diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 8577085db06..887ee63bbb6 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -157,8 +157,9 @@ int event__process_task(event_t *self, struct perf_session *session); struct addr_location; int event__preprocess_sample(const event_t *self, struct perf_session *session, - struct addr_location *al, symbol_filter_t filter); -int event__parse_sample(event_t *event, u64 type, struct sample_data *data); + struct addr_location *al, struct sample_data *data, + symbol_filter_t filter); +int event__parse_sample(const event_t *event, u64 type, struct sample_data *data); extern const char *event__name[]; -- cgit v1.2.3-70-g09d2 From 92221162875ec48913d3f9710046e48d599c9cf2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 9 Aug 2010 15:30:40 -0300 Subject: perf annotate: Sort by hottest lines in the TUI Right now it will just sort and position at the hottest line, i.e. the one where more samples were taken. It will be at the center of the screen and later TAB/shift-TAB will cycle thru the hottest lines. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 2 +- tools/perf/util/hist.c | 13 +-- tools/perf/util/hist.h | 3 +- tools/perf/util/ui/browsers/annotate.c | 153 +++++++++++++++++++++++++-------- 4 files changed, 125 insertions(+), 46 deletions(-) (limited to 'tools/perf/builtin-annotate.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index fd20670ce98..1478dc64bf1 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -285,7 +285,7 @@ static int hist_entry__tty_annotate(struct hist_entry *he) LIST_HEAD(head); struct objdump_line *pos, *n; - if (hist_entry__annotate(he, &head) < 0) + if (hist_entry__annotate(he, &head, 0) < 0) return -1; if (full_paths) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 62ec9b0e4b9..be22ae6ef05 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -983,9 +983,9 @@ int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip) return 0; } -static struct objdump_line *objdump_line__new(s64 offset, char *line) +static struct objdump_line *objdump_line__new(s64 offset, char *line, size_t privsize) { - struct objdump_line *self = malloc(sizeof(*self)); + struct objdump_line *self = malloc(sizeof(*self) + privsize); if (self != NULL) { self->offset = offset; @@ -1017,7 +1017,7 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head, } static int hist_entry__parse_objdump_line(struct hist_entry *self, FILE *file, - struct list_head *head) + struct list_head *head, size_t privsize) { struct symbol *sym = self->ms.sym; struct objdump_line *objdump_line; @@ -1068,7 +1068,7 @@ static int hist_entry__parse_objdump_line(struct hist_entry *self, FILE *file, offset = -1; } - objdump_line = objdump_line__new(offset, line); + objdump_line = objdump_line__new(offset, line, privsize); if (objdump_line == NULL) { free(line); return -1; @@ -1078,7 +1078,8 @@ static int hist_entry__parse_objdump_line(struct hist_entry *self, FILE *file, return 0; } -int hist_entry__annotate(struct hist_entry *self, struct list_head *head) +int hist_entry__annotate(struct hist_entry *self, struct list_head *head, + size_t privsize) { struct symbol *sym = self->ms.sym; struct map *map = self->ms.map; @@ -1143,7 +1144,7 @@ fallback: goto out_free_filename; while (!feof(file)) - if (hist_entry__parse_objdump_line(self, file, head) < 0) + if (hist_entry__parse_objdump_line(self, file, head, privsize) < 0) break; pclose(file); diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 65a48db46a2..587d375d343 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -101,7 +101,8 @@ size_t hists__fprintf(struct hists *self, struct hists *pair, bool show_displacement, FILE *fp); int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip); -int hist_entry__annotate(struct hist_entry *self, struct list_head *head); +int hist_entry__annotate(struct hist_entry *self, struct list_head *head, + size_t privsize); void hists__filter_by_dso(struct hists *self, const struct dso *dso); void hists__filter_by_thread(struct hists *self, const struct thread *thread); diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 5b01df633f9..763592b09d7 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -14,6 +14,23 @@ static void ui__error_window(const char *fmt, ...) va_end(ap); } +struct annotate_browser { + struct ui_browser b; + struct rb_root entries; +}; + +struct objdump_line_rb_node { + struct rb_node rb_node; + double percent; + u32 idx; +}; + +static inline +struct objdump_line_rb_node *objdump_line__rb(struct objdump_line *self) +{ + return (struct objdump_line_rb_node *)(self + 1); +} + static void annotate_browser__write(struct ui_browser *self, void *entry, int row) { struct objdump_line *ol = rb_entry(entry, struct objdump_line, node); @@ -21,17 +38,41 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro int width = self->width; if (ol->offset != -1) { - struct hist_entry *he = self->priv; - struct symbol *sym = he->ms.sym; - int len = he->ms.sym->end - he->ms.sym->start; + struct objdump_line_rb_node *olrb = objdump_line__rb(ol); + int color = ui_browser__percent_color(olrb->percent, current_entry); + SLsmg_set_color(color); + slsmg_printf(" %7.2f ", olrb->percent); + if (!current_entry) + SLsmg_set_color(HE_COLORSET_CODE); + } else { + int color = ui_browser__percent_color(0, current_entry); + SLsmg_set_color(color); + slsmg_write_nstring(" ", 9); + } + + SLsmg_write_char(':'); + slsmg_write_nstring(" ", 8); + if (!*ol->line) + slsmg_write_nstring(" ", width - 18); + else + slsmg_write_nstring(ol->line, width - 18); +} + +static double objdump_line__calc_percent(struct objdump_line *self, + struct list_head *head, + struct symbol *sym) +{ + double percent = 0.0; + + if (self->offset != -1) { + int len = sym->end - sym->start; unsigned int hits = 0; - double percent = 0.0; - int color; struct sym_priv *priv = symbol__priv(sym); struct sym_ext *sym_ext = priv->ext; struct sym_hist *h = priv->hist; - s64 offset = ol->offset; - struct objdump_line *next = objdump__get_next_ip_line(self->entries, ol); + s64 offset = self->offset; + struct objdump_line *next = objdump__get_next_ip_line(head, self); + while (offset < (s64)len && (next == NULL || offset < next->offset)) { @@ -45,37 +86,45 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro if (sym_ext == NULL && h->sum) percent = 100.0 * hits / h->sum; - - color = ui_browser__percent_color(percent, current_entry); - SLsmg_set_color(color); - slsmg_printf(" %7.2f ", percent); - if (!current_entry) - SLsmg_set_color(HE_COLORSET_CODE); - } else { - int color = ui_browser__percent_color(0, current_entry); - SLsmg_set_color(color); - slsmg_write_nstring(" ", 9); } - SLsmg_write_char(':'); - slsmg_write_nstring(" ", 8); - if (!*ol->line) - slsmg_write_nstring(" ", width - 18); - else - slsmg_write_nstring(ol->line, width - 18); + return percent; +} + +static void objdump__insert_line(struct rb_root *self, + struct objdump_line_rb_node *line) +{ + struct rb_node **p = &self->rb_node; + struct rb_node *parent = NULL; + struct objdump_line_rb_node *l; + + while (*p != NULL) { + parent = *p; + l = rb_entry(parent, struct objdump_line_rb_node, rb_node); + if (line->percent < l->percent) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + rb_link_node(&line->rb_node, parent, p); + rb_insert_color(&line->rb_node, self); } int hist_entry__tui_annotate(struct hist_entry *self) { struct newtExitStruct es; struct objdump_line *pos, *n; + struct objdump_line_rb_node *rbpos; + struct rb_node *nd; LIST_HEAD(head); - struct ui_browser browser = { - .entries = &head, - .refresh = ui_browser__list_head_refresh, - .seek = ui_browser__list_head_seek, - .write = annotate_browser__write, - .priv = self, + struct annotate_browser browser = { + .b = { + .entries = &head, + .refresh = ui_browser__list_head_refresh, + .seek = ui_browser__list_head_seek, + .write = annotate_browser__write, + .priv = self, + }, }; int ret; @@ -85,7 +134,7 @@ int hist_entry__tui_annotate(struct hist_entry *self) if (self->ms.map->dso->annotate_warned) return -1; - if (hist_entry__annotate(self, &head) < 0) { + if (hist_entry__annotate(self, &head, sizeof(*rbpos)) < 0) { ui__error_window(ui_helpline__last_msg); return -1; } @@ -94,16 +143,44 @@ int hist_entry__tui_annotate(struct hist_entry *self) list_for_each_entry(pos, &head, node) { size_t line_len = strlen(pos->line); - if (browser.width < line_len) - browser.width = line_len; - ++browser.nr_entries; + if (browser.b.width < line_len) + browser.b.width = line_len; + rbpos = objdump_line__rb(pos); + rbpos->idx = browser.b.nr_entries++; + rbpos->percent = objdump_line__calc_percent(pos, &head, self->ms.sym); + if (rbpos->percent < 0.01) + continue; + objdump__insert_line(&browser.entries, rbpos); + } + + /* + * Position the browser at the hottest line. + */ + nd = rb_last(&browser.entries); + if (nd != NULL) { + unsigned back; + + ui_browser__refresh_dimensions(&browser.b); + back = browser.b.height / 2; + rbpos = rb_entry(nd, struct objdump_line_rb_node, rb_node); + pos = ((struct objdump_line *)rbpos) - 1; + browser.b.top_idx = browser.b.index = rbpos->idx; + + while (browser.b.top_idx != 0 && back != 0) { + pos = list_entry(pos->node.prev, struct objdump_line, node); + + --browser.b.top_idx; + --back; + } + + browser.b.top = pos; } - browser.width += 18; /* Percentage */ - ui_browser__show(&browser, self->ms.sym->name); - newtFormAddHotKey(browser.form, ' '); - ret = ui_browser__run(&browser, &es); - newtFormDestroy(browser.form); + browser.b.width += 18; /* Percentage */ + ui_browser__show(&browser.b, self->ms.sym->name); + newtFormAddHotKey(browser.b.form, ' '); + ret = ui_browser__run(&browser.b, &es); + newtFormDestroy(browser.b.form); newtPopWindow(); list_for_each_entry_safe(pos, n, &head, node) { list_del(&pos->node); -- cgit v1.2.3-70-g09d2 From b50e003db13848dd74572ffd221047683313981d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Aug 2010 10:07:43 -0300 Subject: perf ui browser: Return the exit key in all browsers Make all browsers return the exit key uniformly and remove the newtExitStruct parameter, removing one more newt specific thing from the ui API. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 17 ++--- tools/perf/util/ui/browser.c | 16 ++-- tools/perf/util/ui/browser.h | 2 +- tools/perf/util/ui/browsers/annotate.c | 18 ++--- tools/perf/util/ui/browsers/hists.c | 132 +++++++++++++++------------------ tools/perf/util/ui/browsers/map.c | 20 ++--- tools/perf/util/util.h | 13 ---- 7 files changed, 93 insertions(+), 125 deletions(-) (limited to 'tools/perf/builtin-annotate.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 1478dc64bf1..20ee21d5297 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -321,7 +321,7 @@ static int hist_entry__tty_annotate(struct hist_entry *he) static void hists__find_annotations(struct hists *self) { - struct rb_node *first = rb_first(&self->entries), *nd = first; + struct rb_node *nd = rb_first(&self->entries), *next; int key = KEY_RIGHT; while (nd) { @@ -343,20 +343,19 @@ find_next: if (use_browser > 0) { key = hist_entry__tui_annotate(he); - if (is_exit_key(key)) - break; switch (key) { case KEY_RIGHT: - case '\t': - nd = rb_next(nd); + next = rb_next(nd); break; case KEY_LEFT: - if (nd == first) - continue; - nd = rb_prev(nd); - default: + next = rb_prev(nd); break; + default: + return; } + + if (next != NULL) + nd = next; } else { hist_entry__tty_annotate(he); nd = rb_next(nd); diff --git a/tools/perf/util/ui/browser.c b/tools/perf/util/ui/browser.c index d237410c973..669a9806755 100644 --- a/tools/perf/util/ui/browser.c +++ b/tools/perf/util/ui/browser.c @@ -204,21 +204,21 @@ int ui_browser__refresh(struct ui_browser *self) return 0; } -int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es) +int ui_browser__run(struct ui_browser *self) { + struct newtExitStruct es; + if (ui_browser__refresh(self) < 0) return -1; while (1) { off_t offset; - newtFormRun(self->form, es); + newtFormRun(self->form, &es); - if (es->reason != NEWT_EXIT_HOTKEY) + if (es.reason != NEWT_EXIT_HOTKEY) break; - if (is_exit_key(es->u.key)) - return es->u.key; - switch (es->u.key) { + switch (es.u.key) { case NEWT_KEY_DOWN: if (self->index == self->nr_entries - 1) break; @@ -275,12 +275,12 @@ int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es) self->seek(self, -offset, SEEK_END); break; default: - return es->u.key; + return es.u.key; } if (ui_browser__refresh(self) < 0) return -1; } - return 0; + return -1; } unsigned int ui_browser__list_head_refresh(struct ui_browser *self) diff --git a/tools/perf/util/ui/browser.h b/tools/perf/util/ui/browser.h index 27c23c277ab..332a675e55c 100644 --- a/tools/perf/util/ui/browser.h +++ b/tools/perf/util/ui/browser.h @@ -37,7 +37,7 @@ int ui_browser__show(struct ui_browser *self, const char *title, const char *helpline, ...); void ui_browser__hide(struct ui_browser *self); int ui_browser__refresh(struct ui_browser *self); -int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es); +int ui_browser__run(struct ui_browser *self); void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence); unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self); diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index a00d529caaf..a8bc2c01594 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -133,14 +133,14 @@ static void annotate_browser__set_top(struct annotate_browser *self, self->curr_hot = nd; } -static int annotate_browser__run(struct annotate_browser *self, - struct newtExitStruct *es) +static int annotate_browser__run(struct annotate_browser *self) { struct rb_node *nd; struct hist_entry *he = self->b.priv; + int key; if (ui_browser__show(&self->b, he->ms.sym->name, - "<- or ESC: exit, TAB/shift+TAB: cycle thru samples") < 0) + "<-, -> or ESC: exit, TAB/shift+TAB: cycle thru samples") < 0) return -1; newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT); @@ -153,12 +153,9 @@ static int annotate_browser__run(struct annotate_browser *self, } while (1) { - ui_browser__run(&self->b, es); + key = ui_browser__run(&self->b); - if (es->reason != NEWT_EXIT_HOTKEY) - break; - - switch (es->u.key) { + switch (key) { case NEWT_KEY_TAB: nd = rb_prev(nd); if (nd == NULL) @@ -177,12 +174,11 @@ static int annotate_browser__run(struct annotate_browser *self, } out: ui_browser__hide(&self->b); - return es->u.key; + return key; } int hist_entry__tui_annotate(struct hist_entry *self) { - struct newtExitStruct es; struct objdump_line *pos, *n; struct objdump_line_rb_node *rbpos; LIST_HEAD(head); @@ -230,7 +226,7 @@ int hist_entry__tui_annotate(struct hist_entry *self) annotate_browser__set_top(&browser, browser.curr_hot); browser.b.width += 18; /* Percentage */ - ret = annotate_browser__run(&browser, &es); + ret = annotate_browser__run(&browser); list_for_each_entry_safe(pos, n, &head, node) { list_del(&pos->node); objdump_line__free(pos); diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index 5723091134e..1735c48691a 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c @@ -195,9 +195,9 @@ static bool hist_browser__toggle_fold(struct hist_browser *self) return false; } -static int hist_browser__run(struct hist_browser *self, const char *title, - struct newtExitStruct *es) +static int hist_browser__run(struct hist_browser *self, const char *title) { + int key; char str[256], unit; unsigned long nr_events = self->hists->stats.nr_events[PERF_RECORD_SAMPLE]; @@ -227,11 +227,9 @@ static int hist_browser__run(struct hist_browser *self, const char *title, newtFormAddHotKey(self->b.form, NEWT_KEY_ENTER); while (1) { - ui_browser__run(&self->b, es); + key = ui_browser__run(&self->b); - if (es->reason != NEWT_EXIT_HOTKEY) - break; - switch (es->u.key) { + switch (key) { case 'D': { /* Debug */ static int seq; struct hist_entry *h = rb_entry(self->b.top, @@ -251,12 +249,12 @@ static int hist_browser__run(struct hist_browser *self, const char *title, break; /* fall thru */ default: - return 0; + goto out; } } - +out: ui_browser__hide(&self->b); - return 0; + return key; } static char *callchain_list__sym_name(struct callchain_list *self, @@ -687,8 +685,6 @@ static struct hist_browser *hist_browser__new(struct hists *hists) static void hist_browser__delete(struct hist_browser *self) { - newtFormDestroy(self->b.form); - newtPopWindow(); free(self); } @@ -725,7 +721,6 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name) struct pstack *fstack; const struct thread *thread_filter = NULL; const struct dso *dso_filter = NULL; - struct newtExitStruct es; char msg[160]; int key = -1; @@ -749,70 +744,63 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name) annotate = -2, zoom_dso = -2, zoom_thread = -2, browse_map = -2; - if (hist_browser__run(browser, msg, &es)) - break; + key = hist_browser__run(browser, msg); thread = hist_browser__selected_thread(browser); dso = browser->selection->map ? browser->selection->map->dso : NULL; - if (es.reason == NEWT_EXIT_HOTKEY) { - key = es.u.key; - - switch (key) { - case NEWT_KEY_F1: - goto do_help; - case NEWT_KEY_TAB: - case NEWT_KEY_UNTAB: - /* - * Exit the browser, let hists__browser_tree - * go to the next or previous - */ - goto out_free_stack; - default:; - } - - switch (key) { - case 'a': - if (browser->selection->map == NULL && - browser->selection->map->dso->annotate_warned) - continue; - goto do_annotate; - case 'd': - goto zoom_dso; - case 't': - goto zoom_thread; - case 'h': - case '?': -do_help: - ui__help_window("-> Zoom into DSO/Threads & Annotate current symbol\n" - "<- Zoom out\n" - "a Annotate current symbol\n" - "h/?/F1 Show this window\n" - "d Zoom into current DSO\n" - "t Zoom into current Thread\n" - "q/CTRL+C Exit browser"); + switch (key) { + case NEWT_KEY_F1: + goto do_help; + case NEWT_KEY_TAB: + case NEWT_KEY_UNTAB: + /* + * Exit the browser, let hists__browser_tree + * go to the next or previous + */ + goto out_free_stack; + case 'a': + if (browser->selection->map == NULL && + browser->selection->map->dso->annotate_warned) continue; - default:; - } - if (is_exit_key(key)) { - if (key == NEWT_KEY_ESCAPE && - !ui__dialog_yesno("Do you really want to exit?")) - continue; - break; - } - - if (es.u.key == NEWT_KEY_LEFT) { - const void *top; + goto do_annotate; + case 'd': + goto zoom_dso; + case 't': + goto zoom_thread; + case 'h': + case '?': +do_help: + ui__help_window("-> Zoom into DSO/Threads & Annotate current symbol\n" + "<- Zoom out\n" + "a Annotate current symbol\n" + "h/?/F1 Show this window\n" + "d Zoom into current DSO\n" + "t Zoom into current Thread\n" + "q/CTRL+C Exit browser"); + continue; + case NEWT_KEY_ENTER: + case NEWT_KEY_RIGHT: + /* menu */ + break; + case NEWT_KEY_LEFT: { + const void *top; - if (pstack__empty(fstack)) - continue; - top = pstack__pop(fstack); - if (top == &dso_filter) - goto zoom_out_dso; - if (top == &thread_filter) - goto zoom_out_thread; + if (pstack__empty(fstack)) continue; - } + top = pstack__pop(fstack); + if (top == &dso_filter) + goto zoom_out_dso; + if (top == &thread_filter) + goto zoom_out_thread; + continue; + } + case NEWT_KEY_ESCAPE: + if (!ui__dialog_yesno("Do you really want to exit?")) + continue; + /* Fall thru */ + default: + goto out_free_stack; } if (browser->selection->sym != NULL && @@ -925,10 +913,6 @@ int hists__tui_browse_tree(struct rb_root *self, const char *help) const char *ev_name = __event_name(hists->type, hists->config); key = hists__browse(hists, help, ev_name); - - if (is_exit_key(key)) - break; - switch (key) { case NEWT_KEY_TAB: next = rb_next(nd); @@ -940,7 +924,7 @@ int hists__tui_browse_tree(struct rb_root *self, const char *help) continue; nd = rb_prev(nd); default: - break; + return key; } } diff --git a/tools/perf/util/ui/browsers/map.c b/tools/perf/util/ui/browsers/map.c index 733daba60cd..16b7d70f2c5 100644 --- a/tools/perf/util/ui/browsers/map.c +++ b/tools/perf/util/ui/browsers/map.c @@ -97,31 +97,34 @@ static int map_browser__search(struct map_browser *self) return 0; } -static int map_browser__run(struct map_browser *self, struct newtExitStruct *es) +static int map_browser__run(struct map_browser *self) { + int key; + if (ui_browser__show(&self->b, self->map->dso->long_name, "Press <- or ESC to exit, %s / to search", verbose ? "" : "restart with -v to use") < 0) return -1; newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT); - newtFormAddHotKey(self->b.form, NEWT_KEY_ENTER); + newtFormAddHotKey(self->b.form, NEWT_KEY_ESCAPE); + newtFormAddHotKey(self->b.form, 'Q'); + newtFormAddHotKey(self->b.form, 'q'); + newtFormAddHotKey(self->b.form, CTRL('c')); if (verbose) newtFormAddHotKey(self->b.form, '/'); while (1) { - ui_browser__run(&self->b, es); + key = ui_browser__run(&self->b); - if (es->reason != NEWT_EXIT_HOTKEY) - break; - if (verbose && es->u.key == '/') + if (verbose && key == '/') map_browser__search(self); else break; } ui_browser__hide(&self->b); - return 0; + return key; } int map__browse(struct map *self) @@ -135,7 +138,6 @@ int map__browse(struct map *self) }, .map = self, }; - struct newtExitStruct es; struct rb_node *nd; char tmp[BITS_PER_LONG / 4]; u64 maxaddr = 0; @@ -156,5 +158,5 @@ int map__browse(struct map *self) mb.addrlen = snprintf(tmp, sizeof(tmp), "%llx", maxaddr); mb.b.width += mb.addrlen * 2 + 4 + mb.namelen; - return map_browser__run(&mb, &es); + return map_browser__run(&mb); } diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index f380fed7435..7562707ddd1 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -266,19 +266,6 @@ bool strglobmatch(const char *str, const char *pat); bool strlazymatch(const char *str, const char *pat); unsigned long convert_unit(unsigned long value, char *unit); -#ifndef ESC -#define ESC 27 -#endif - -static inline bool is_exit_key(int key) -{ - char up; - if (key == CTRL('c') || key == ESC) - return true; - up = toupper(key); - return up == 'Q'; -} - #define _STR(x) #x #define STR(x) _STR(x) -- cgit v1.2.3-70-g09d2 From 8b9e74eb8af808807192d16b76565c27154ae7ed Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 21 Aug 2010 10:38:16 -0300 Subject: perf tools: Add --tui and --stdio to choose the UI Relying just on ~/.perfconfig or rebuilding the tool disabling support for the TUI is too cumbersome, so allow specifying which UI to use and make the command line switch override whatever is in ~/.perfconfig. Suggested-by: Christoph Hellwig Cc: Christoph Hellwig Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-annotate.txt | 11 +++++++++-- tools/perf/Documentation/perf-report.txt | 7 +++++++ tools/perf/builtin-annotate.c | 9 ++++++++- tools/perf/builtin-report.c | 11 ++++++++++- 4 files changed, 34 insertions(+), 4 deletions(-) (limited to 'tools/perf/builtin-annotate.c') diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index 5164a655c39..b2c63309a65 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt @@ -8,7 +8,7 @@ perf-annotate - Read perf.data (created by perf record) and display annotated co SYNOPSIS -------- [verse] -'perf annotate' [-i | --input=file] symbol_name +'perf annotate' [-i | --input=file] [symbol_name] DESCRIPTION ----------- @@ -24,6 +24,13 @@ OPTIONS --input=:: Input file name. (default: perf.data) +--stdio:: Use the stdio interface. + +--tui:: Use the TUI interface Use of --tui requires a tty, if one is not + present, as when piping to other commands, the stdio interface is + used. This interfaces starts by centering on the line with more + samples, TAB/UNTAB cycles thru the lines with more samples. + SEE ALSO -------- -linkperf:perf-record[1] +linkperf:perf-record[1], linkperf:perf-report[1] diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index abfabe9147a..12052c9ed0b 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -65,6 +65,13 @@ OPTIONS the tree is considered as a new profiled object. + Default: fractal,0.5. +--stdio:: Use the stdio interface. + +--tui:: Use the TUI interface, that is integrated with annotate and allows + zooming into DSOs or threads, among other features. Use of --tui + requires a tty, if one is not present, as when piping to other + commands, the stdio interface is used. + SEE ALSO -------- linkperf:perf-stat[1] diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 20ee21d5297..6d5604d8df9 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -28,7 +28,7 @@ static char const *input_name = "perf.data"; -static bool force; +static bool force, use_tui, use_stdio; static bool full_paths; @@ -427,6 +427,8 @@ static const struct option options[] = { "be more verbose (show symbol address, etc)"), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), + OPT_BOOLEAN(0, "tui", &use_tui, "Use the TUI interface"), + OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"), OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, "file", "vmlinux pathname"), OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, @@ -442,6 +444,11 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) { argc = parse_options(argc, argv, options, annotate_usage, 0); + if (use_stdio) + use_browser = 0; + else if (use_tui) + use_browser = 1; + setup_browser(); symbol_conf.priv_size = sizeof(struct sym_priv); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 55fc1f46892..7d35a719c95 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -32,7 +32,7 @@ static char const *input_name = "perf.data"; -static bool force; +static bool force, use_tui, use_stdio; static bool hide_unresolved; static bool dont_use_callchains; @@ -450,6 +450,8 @@ static const struct option options[] = { "Show per-thread event counters"), OPT_STRING(0, "pretty", &pretty_printing_style, "key", "pretty printing style key: normal raw"), + OPT_BOOLEAN(0, "tui", &use_tui, "Use the TUI interface"), + OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"), OPT_STRING('s', "sort", &sort_order, "key[,key2...]", "sort by key(s): pid, comm, dso, symbol, parent"), OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization, @@ -482,8 +484,15 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) { argc = parse_options(argc, argv, options, report_usage, 0); + if (use_stdio) + use_browser = 0; + else if (use_tui) + use_browser = 1; + if (strcmp(input_name, "-") != 0) setup_browser(); + else + use_browser = 0; /* * Only in the newt browser we are doing integrated annotation, * so don't allocate extra space that won't be used in the stdio -- cgit v1.2.3-70-g09d2 From 640c03ce837fe8d4b56342aba376ea0da3960459 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 2 Dec 2010 14:10:21 -0200 Subject: perf session: Parse sample earlier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At perf_session__process_event, so that we reduce the number of lines in eache tool sample processing routine that now receives a sample_data pointer already parsed. This will also be useful in the next patch, where we'll allow sample the identity fields in MMAP, FORK, EXIT, etc, when it will be possible to see (cpu, timestamp) just after before every event. Also validate callchains in perf_session__process_event, i.e. as early as possible, and keep a counter of the number of events discarded due to invalid callchains, warning the user about it if it happens. There is an assumption that was kept that all events have the same sample_type, that will be dealt with in the future, when this preexisting limitation will be removed. Tested-by: Thomas Gleixner Reviewed-by: Thomas Gleixner Acked-by: Ian Munsie Acked-by: Thomas Gleixner Cc: Frédéric Weisbecker Cc: Ian Munsie Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Stephane Eranian LKML-Reference: <1291318772-30880-4-git-send-email-acme@infradead.org> Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 6 +-- tools/perf/builtin-diff.c | 11 +++-- tools/perf/builtin-inject.c | 39 ++++++++++------ tools/perf/builtin-kmem.c | 21 ++------- tools/perf/builtin-lock.c | 12 ++--- tools/perf/builtin-record.c | 7 +++ tools/perf/builtin-report.c | 15 +++--- tools/perf/builtin-sched.c | 21 +++------ tools/perf/builtin-script.c | 34 +++++--------- tools/perf/builtin-timechart.c | 40 ++++++++-------- tools/perf/builtin-top.c | 4 +- tools/perf/util/build-id.c | 7 ++- tools/perf/util/event.c | 66 +++++++++++--------------- tools/perf/util/event.h | 20 +++++--- tools/perf/util/header.c | 11 ++--- tools/perf/util/hist.h | 2 + tools/perf/util/session.c | 103 +++++++++++++++++++++++++++++++---------- tools/perf/util/session.h | 9 ++-- 18 files changed, 236 insertions(+), 192 deletions(-) (limited to 'tools/perf/builtin-annotate.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 6d5604d8df9..569a2761b90 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -58,12 +58,12 @@ static int hists__add_entry(struct hists *self, struct addr_location *al) return hist_entry__inc_addr_samples(he, al->addr); } -static int process_sample_event(event_t *event, struct perf_session *session) +static int process_sample_event(event_t *event, struct sample_data *sample, + struct perf_session *session) { struct addr_location al; - struct sample_data data; - if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { + if (event__preprocess_sample(event, session, &al, sample, NULL) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 221b823bc26..5e1a043aae0 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -30,12 +30,13 @@ static int hists__add_entry(struct hists *self, return -ENOMEM; } -static int diff__process_sample_event(event_t *event, struct perf_session *session) +static int diff__process_sample_event(event_t *event, + struct sample_data *sample, + struct perf_session *session) { struct addr_location al; - struct sample_data data = { .period = 1, }; - if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { + if (event__preprocess_sample(event, session, &al, sample, NULL) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; @@ -44,12 +45,12 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi if (al.filtered || al.sym == NULL) return 0; - if (hists__add_entry(&session->hists, &al, data.period)) { + if (hists__add_entry(&session->hists, &al, sample->period)) { pr_warning("problem incrementing symbol period, skipping event\n"); return -1; } - session->hists.stats.total_period += data.period; + session->hists.stats.total_period += sample->period; return 0; } diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 8e3e47b064c..4b66b857941 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -16,8 +16,8 @@ static char const *input_name = "-"; static bool inject_build_ids; -static int event__repipe(event_t *event __used, - struct perf_session *session __used) +static int event__repipe_synth(event_t *event, + struct perf_session *session __used) { uint32_t size; void *buf = event; @@ -36,22 +36,30 @@ static int event__repipe(event_t *event __used, return 0; } -static int event__repipe_mmap(event_t *self, struct perf_session *session) +static int event__repipe(event_t *event, struct sample_data *sample __used, + struct perf_session *session) +{ + return event__repipe_synth(event, session); +} + +static int event__repipe_mmap(event_t *self, struct sample_data *sample, + struct perf_session *session) { int err; - err = event__process_mmap(self, session); - event__repipe(self, session); + err = event__process_mmap(self, sample, session); + event__repipe(self, sample, session); return err; } -static int event__repipe_task(event_t *self, struct perf_session *session) +static int event__repipe_task(event_t *self, struct sample_data *sample, + struct perf_session *session) { int err; - err = event__process_task(self, session); - event__repipe(self, session); + err = event__process_task(self, sample, session); + event__repipe(self, sample, session); return err; } @@ -61,7 +69,7 @@ static int event__repipe_tracing_data(event_t *self, { int err; - event__repipe(self, session); + event__repipe_synth(self, session); err = event__process_tracing_data(self, session); return err; @@ -111,7 +119,8 @@ static int dso__inject_build_id(struct dso *self, struct perf_session *session) return 0; } -static int event__inject_buildid(event_t *event, struct perf_session *session) +static int event__inject_buildid(event_t *event, struct sample_data *sample, + struct perf_session *session) { struct addr_location al; struct thread *thread; @@ -146,7 +155,7 @@ static int event__inject_buildid(event_t *event, struct perf_session *session) } repipe: - event__repipe(event, session); + event__repipe(event, sample, session); return 0; } @@ -160,10 +169,10 @@ struct perf_event_ops inject_ops = { .read = event__repipe, .throttle = event__repipe, .unthrottle = event__repipe, - .attr = event__repipe, - .event_type = event__repipe, - .tracing_data = event__repipe, - .build_id = event__repipe, + .attr = event__repipe_synth, + .event_type = event__repipe_synth, + .tracing_data = event__repipe_synth, + .build_id = event__repipe_synth, }; extern volatile int session_done; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 31f60a2535e..d0a652e9c70 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -304,22 +304,11 @@ process_raw_event(event_t *raw_event __used, void *data, } } -static int process_sample_event(event_t *event, struct perf_session *session) +static int process_sample_event(event_t *event, struct sample_data *sample, + struct perf_session *session) { - struct sample_data data; - struct thread *thread; + struct thread *thread = perf_session__findnew(session, event->ip.pid); - memset(&data, 0, sizeof(data)); - data.time = -1; - data.cpu = -1; - data.period = 1; - - event__parse_sample(event, session->sample_type, &data); - - dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, - data.pid, data.tid, data.ip, data.period); - - thread = perf_session__findnew(session, event->ip.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); @@ -328,8 +317,8 @@ static int process_sample_event(event_t *event, struct perf_session *session) dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - process_raw_event(event, data.raw_data, data.cpu, - data.time, thread); + process_raw_event(event, sample->raw_data, sample->cpu, + sample->time, thread); return 0; } diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 8452a2ae219..92d3da52a5c 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -834,22 +834,18 @@ static void dump_info(void) die("Unknown type of information\n"); } -static int process_sample_event(event_t *self, struct perf_session *s) +static int process_sample_event(event_t *self, struct sample_data *sample, + struct perf_session *s) { - struct sample_data data; - struct thread *thread; + struct thread *thread = perf_session__findnew(s, sample->tid); - bzero(&data, sizeof(data)); - event__parse_sample(self, s->sample_type, &data); - - thread = perf_session__findnew(s, data.tid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", self->header.type); return -1; } - process_raw_event(data.raw_data, data.cpu, data.time, thread); + process_raw_event(sample->raw_data, sample->cpu, sample->time, thread); return 0; } diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 024e1441d76..b34de9291c2 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -36,6 +36,7 @@ static int *fd[MAX_NR_CPUS][MAX_COUNTERS]; static u64 user_interval = ULLONG_MAX; static u64 default_interval = 0; +static u64 sample_type; static int nr_cpus = 0; static unsigned int page_size; @@ -129,6 +130,7 @@ static void write_output(void *buf, size_t size) } static int process_synthesized_event(event_t *event, + struct sample_data *sample __used, struct perf_session *self __used) { write_output(event, event->header.size); @@ -287,6 +289,9 @@ static void create_counter(int counter, int cpu) attr->sample_type |= PERF_SAMPLE_CPU; } + if (!sample_type) + sample_type = attr->sample_type; + attr->mmap = track; attr->comm = track; attr->inherit = !no_inherit; @@ -642,6 +647,8 @@ static int __cmd_record(int argc, const char **argv) open_counters(cpumap[i]); } + perf_session__set_sample_type(session, sample_type); + if (pipe_output) { err = perf_header__write_pipe(output); if (err < 0) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 5de405d4523..904519fba43 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -150,13 +150,13 @@ static int add_event_total(struct perf_session *session, return 0; } -static int process_sample_event(event_t *event, struct perf_session *session) +static int process_sample_event(event_t *event, struct sample_data *sample, + struct perf_session *session) { - struct sample_data data = { .period = 1, }; struct addr_location al; struct perf_event_attr *attr; - if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { + if (event__preprocess_sample(event, session, &al, sample, NULL) < 0) { fprintf(stderr, "problem processing %d event, skipping it.\n", event->header.type); return -1; @@ -165,14 +165,14 @@ static int process_sample_event(event_t *event, struct perf_session *session) if (al.filtered || (hide_unresolved && al.sym == NULL)) return 0; - if (perf_session__add_hist_entry(session, &al, &data)) { + if (perf_session__add_hist_entry(session, &al, sample)) { pr_debug("problem incrementing symbol period, skipping event\n"); return -1; } - attr = perf_header__find_attr(data.id, &session->header); + attr = perf_header__find_attr(sample->id, &session->header); - if (add_event_total(session, &data, attr)) { + if (add_event_total(session, sample, attr)) { pr_debug("problem adding event period\n"); return -1; } @@ -180,7 +180,8 @@ static int process_sample_event(event_t *event, struct perf_session *session) return 0; } -static int process_read_event(event_t *event, struct perf_session *session __used) +static int process_read_event(event_t *event, struct sample_data *sample __used, + struct perf_session *session __used) { struct perf_event_attr *attr; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 26523c93979..73d1e30b0fe 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1606,25 +1606,15 @@ process_raw_event(event_t *raw_event __used, struct perf_session *session, process_sched_migrate_task_event(data, session, event, cpu, timestamp, thread); } -static int process_sample_event(event_t *event, struct perf_session *session) +static int process_sample_event(event_t *event, struct sample_data *sample, + struct perf_session *session) { - struct sample_data data; struct thread *thread; if (!(session->sample_type & PERF_SAMPLE_RAW)) return 0; - memset(&data, 0, sizeof(data)); - data.time = -1; - data.cpu = -1; - data.period = -1; - - event__parse_sample(event, session->sample_type, &data); - - dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, - data.pid, data.tid, data.ip, data.period); - - thread = perf_session__findnew(session, data.pid); + thread = perf_session__findnew(session, sample->pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); @@ -1633,10 +1623,11 @@ static int process_sample_event(event_t *event, struct perf_session *session) dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - if (profile_cpu != -1 && profile_cpu != (int)data.cpu) + if (profile_cpu != -1 && profile_cpu != (int)sample->cpu) return 0; - process_raw_event(event, session, data.raw_data, data.cpu, data.time, thread); + process_raw_event(event, session, sample->raw_data, sample->cpu, + sample->time, thread); return 0; } diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 4539551ab40..683a30572cc 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -63,22 +63,11 @@ static int cleanup_scripting(void) static char const *input_name = "perf.data"; -static int process_sample_event(event_t *event, struct perf_session *session) +static int process_sample_event(event_t *event, struct sample_data *sample, + struct perf_session *session) { - struct sample_data data; - struct thread *thread; + struct thread *thread = perf_session__findnew(session, event->ip.pid); - memset(&data, 0, sizeof(data)); - data.time = -1; - data.cpu = -1; - data.period = 1; - - event__parse_sample(event, session->sample_type, &data); - - dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, - data.pid, data.tid, data.ip, data.period); - - thread = perf_session__findnew(session, event->ip.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); @@ -87,13 +76,13 @@ static int process_sample_event(event_t *event, struct perf_session *session) if (session->sample_type & PERF_SAMPLE_RAW) { if (debug_mode) { - if (data.time < last_timestamp) { + if (sample->time < last_timestamp) { pr_err("Samples misordered, previous: %llu " "this: %llu\n", last_timestamp, - data.time); + sample->time); nr_unordered++; } - last_timestamp = data.time; + last_timestamp = sample->time; return 0; } /* @@ -101,18 +90,19 @@ static int process_sample_event(event_t *event, struct perf_session *session) * field, although it should be the same than this perf * event pid */ - scripting_ops->process_event(data.cpu, data.raw_data, - data.raw_size, - data.time, thread->comm); + scripting_ops->process_event(sample->cpu, sample->raw_data, + sample->raw_size, + sample->time, thread->comm); } - session->hists.stats.total_period += data.period; + session->hists.stats.total_period += sample->period; return 0; } static u64 nr_lost; -static int process_lost_event(event_t *event, struct perf_session *session __used) +static int process_lost_event(event_t *event, struct sample_data *sample __used, + struct perf_session *session __used) { nr_lost += event->lost.lost; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 9bcc38f0b70..1f158dc0334 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -272,19 +272,22 @@ static int cpus_cstate_state[MAX_CPUS]; static u64 cpus_pstate_start_times[MAX_CPUS]; static u64 cpus_pstate_state[MAX_CPUS]; -static int process_comm_event(event_t *event, struct perf_session *session __used) +static int process_comm_event(event_t *event, struct sample_data *sample __used, + struct perf_session *session __used) { pid_set_comm(event->comm.tid, event->comm.comm); return 0; } -static int process_fork_event(event_t *event, struct perf_session *session __used) +static int process_fork_event(event_t *event, struct sample_data *sample __used, + struct perf_session *session __used) { pid_fork(event->fork.pid, event->fork.ppid, event->fork.time); return 0; } -static int process_exit_event(event_t *event, struct perf_session *session __used) +static int process_exit_event(event_t *event, struct sample_data *sample __used, + struct perf_session *session __used) { pid_exit(event->fork.pid, event->fork.time); return 0; @@ -470,24 +473,21 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te) } -static int process_sample_event(event_t *event, struct perf_session *session) +static int process_sample_event(event_t *event __used, + struct sample_data *sample, + struct perf_session *session) { - struct sample_data data; struct trace_entry *te; - memset(&data, 0, sizeof(data)); - - event__parse_sample(event, session->sample_type, &data); - if (session->sample_type & PERF_SAMPLE_TIME) { - if (!first_time || first_time > data.time) - first_time = data.time; - if (last_time < data.time) - last_time = data.time; + if (!first_time || first_time > sample->time) + first_time = sample->time; + if (last_time < sample->time) + last_time = sample->time; } - te = (void *)data.raw_data; - if (session->sample_type & PERF_SAMPLE_RAW && data.raw_size > 0) { + te = (void *)sample->raw_data; + if (session->sample_type & PERF_SAMPLE_RAW && sample->raw_size > 0) { char *event_str; struct power_entry *pe; @@ -499,19 +499,19 @@ static int process_sample_event(event_t *event, struct perf_session *session) return 0; if (strcmp(event_str, "power:power_start") == 0) - c_state_start(pe->cpu_id, data.time, pe->value); + c_state_start(pe->cpu_id, sample->time, pe->value); if (strcmp(event_str, "power:power_end") == 0) - c_state_end(pe->cpu_id, data.time); + c_state_end(pe->cpu_id, sample->time); if (strcmp(event_str, "power:power_frequency") == 0) - p_state_change(pe->cpu_id, data.time, pe->value); + p_state_change(pe->cpu_id, sample->time, pe->value); if (strcmp(event_str, "sched:sched_wakeup") == 0) - sched_wakeup(data.cpu, data.time, data.pid, te); + sched_wakeup(sample->cpu, sample->time, sample->pid, te); if (strcmp(event_str, "sched:sched_switch") == 0) - sched_switch(data.cpu, data.time, te); + sched_switch(sample->cpu, sample->time, te); } return 0; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 3d2b47d5121..5aa29e1e855 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1025,6 +1025,8 @@ static void event__process_sample(const event_t *self, if (self->header.misc & PERF_RECORD_MISC_EXACT_IP) exact_samples++; + event__parse_sample(self, session->sample_type, &data); + if (event__preprocess_sample(self, session, &al, &data, symbol_filter) < 0 || al.filtered) @@ -1155,7 +1157,7 @@ static void perf_session__mmap_read_counter(struct perf_session *self, if (event->header.type == PERF_RECORD_SAMPLE) event__process_sample(event, self, md->counter); else - event__process(event, self); + event__process(event, NULL, self); old += size; } diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index e437edb7241..deffb8c9607 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -14,7 +14,9 @@ #include #include "debug.h" -static int build_id__mark_dso_hit(event_t *event, struct perf_session *session) +static int build_id__mark_dso_hit(event_t *event, + struct sample_data *sample __used, + struct perf_session *session) { struct addr_location al; u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; @@ -35,7 +37,8 @@ static int build_id__mark_dso_hit(event_t *event, struct perf_session *session) return 0; } -static int event__exit_del_thread(event_t *self, struct perf_session *session) +static int event__exit_del_thread(event_t *self, struct sample_data *sample __used, + struct perf_session *session) { struct thread *thread = perf_session__findnew(session, self->fork.tid); diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 7260db75b93..34510f44197 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -24,6 +24,15 @@ const char *event__name[] = { [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", }; +static struct sample_data synth_sample = { + .pid = -1, + .tid = -1, + .time = -1, + .stream_id = -1, + .cpu = -1, + .period = 1, +}; + static pid_t event__synthesize_comm(pid_t pid, int full, event__handler_t process, struct perf_session *session) @@ -75,7 +84,7 @@ out_race: if (!full) { ev.comm.tid = pid; - process(&ev, session); + process(&ev, &synth_sample, session); goto out_fclose; } @@ -93,7 +102,7 @@ out_race: ev.comm.tid = pid; - process(&ev, session); + process(&ev, &synth_sample, session); } closedir(tasks); @@ -173,7 +182,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, ev.mmap.pid = tgid; ev.mmap.tid = pid; - process(&ev, session); + process(&ev, &synth_sample, session); } } @@ -219,7 +228,7 @@ int event__synthesize_modules(event__handler_t process, memcpy(ev.mmap.filename, pos->dso->long_name, pos->dso->long_name_len + 1); - process(&ev, session); + process(&ev, &synth_sample, session); } return 0; @@ -331,7 +340,7 @@ int event__synthesize_kernel_mmap(event__handler_t process, ev.mmap.len = map->end - ev.mmap.start; ev.mmap.pid = machine->pid; - return process(&ev, session); + return process(&ev, &synth_sample, session); } static void thread__comm_adjust(struct thread *self, struct hists *hists) @@ -361,7 +370,8 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm, return 0; } -int event__process_comm(event_t *self, struct perf_session *session) +int event__process_comm(event_t *self, struct sample_data *sample __used, + struct perf_session *session) { struct thread *thread = perf_session__findnew(session, self->comm.tid); @@ -376,7 +386,8 @@ int event__process_comm(event_t *self, struct perf_session *session) return 0; } -int event__process_lost(event_t *self, struct perf_session *session) +int event__process_lost(event_t *self, struct sample_data *sample __used, + struct perf_session *session) { dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost); session->hists.stats.total_lost += self->lost.lost; @@ -485,7 +496,8 @@ out_problem: return -1; } -int event__process_mmap(event_t *self, struct perf_session *session) +int event__process_mmap(event_t *self, struct sample_data *sample __used, + struct perf_session *session) { struct machine *machine; struct thread *thread; @@ -526,7 +538,8 @@ out_problem: return 0; } -int event__process_task(event_t *self, struct perf_session *session) +int event__process_task(event_t *self, struct sample_data *sample __used, + struct perf_session *session) { struct thread *thread = perf_session__findnew(session, self->fork.tid); struct thread *parent = perf_session__findnew(session, self->fork.ptid); @@ -548,18 +561,19 @@ int event__process_task(event_t *self, struct perf_session *session) return 0; } -int event__process(event_t *event, struct perf_session *session) +int event__process(event_t *event, struct sample_data *sample, + struct perf_session *session) { switch (event->header.type) { case PERF_RECORD_COMM: - event__process_comm(event, session); + event__process_comm(event, sample, session); break; case PERF_RECORD_MMAP: - event__process_mmap(event, session); + event__process_mmap(event, sample, session); break; case PERF_RECORD_FORK: case PERF_RECORD_EXIT: - event__process_task(event, session); + event__process_task(event, sample, session); break; default: break; @@ -674,32 +688,8 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, symbol_filter_t filter) { u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - struct thread *thread; - - event__parse_sample(self, session->sample_type, data); + struct thread *thread = perf_session__findnew(session, self->ip.pid); - dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld cpu:%d\n", - self->header.misc, data->pid, data->tid, data->ip, - data->period, data->cpu); - - if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { - unsigned int i; - - dump_printf("... chain: nr:%Lu\n", data->callchain->nr); - - if (!ip_callchain__valid(data->callchain, self)) { - pr_debug("call-chain problem with event, " - "skipping it.\n"); - goto out_filtered; - } - - if (dump_trace) { - for (i = 0; i < data->callchain->nr; i++) - dump_printf("..... %2d: %016Lx\n", - i, data->callchain->ips[i]); - } - } - thread = perf_session__findnew(session, self->ip.pid); if (thread == NULL) return -1; diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 8e790dae702..08c400b83d5 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -135,7 +135,10 @@ void event__print_totals(void); struct perf_session; -typedef int (*event__handler_t)(event_t *event, struct perf_session *session); +typedef int (*event__handler_synth_t)(event_t *event, + struct perf_session *session); +typedef int (*event__handler_t)(event_t *event, struct sample_data *sample, + struct perf_session *session); int event__synthesize_thread(pid_t pid, event__handler_t process, struct perf_session *session); @@ -150,11 +153,16 @@ int event__synthesize_modules(event__handler_t process, struct perf_session *session, struct machine *machine); -int event__process_comm(event_t *self, struct perf_session *session); -int event__process_lost(event_t *self, struct perf_session *session); -int event__process_mmap(event_t *self, struct perf_session *session); -int event__process_task(event_t *self, struct perf_session *session); -int event__process(event_t *event, struct perf_session *session); +int event__process_comm(event_t *self, struct sample_data *sample, + struct perf_session *session); +int event__process_lost(event_t *self, struct sample_data *sample, + struct perf_session *session); +int event__process_mmap(event_t *self, struct sample_data *sample, + struct perf_session *session); +int event__process_task(event_t *self, struct sample_data *sample, + struct perf_session *session); +int event__process(event_t *event, struct sample_data *sample, + struct perf_session *session); struct addr_location; int event__preprocess_sample(const event_t *self, struct perf_session *session, diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index f65d7dc127b..fe652f3b0aa 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -993,15 +993,14 @@ int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id, ev->attr.header.type = PERF_RECORD_HEADER_ATTR; ev->attr.header.size = size; - err = process(ev, session); + err = process(ev, NULL, session); free(ev); return err; } -int event__synthesize_attrs(struct perf_header *self, - event__handler_t process, +int event__synthesize_attrs(struct perf_header *self, event__handler_t process, struct perf_session *session) { struct perf_header_attr *attr; @@ -1071,7 +1070,7 @@ int event__synthesize_event_type(u64 event_id, char *name, ev.event_type.header.size = sizeof(ev.event_type) - (sizeof(ev.event_type.event_type.name) - size); - err = process(&ev, session); + err = process(&ev, NULL, session); return err; } @@ -1126,7 +1125,7 @@ int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs, ev.tracing_data.header.size = sizeof(ev.tracing_data); ev.tracing_data.size = aligned_size; - process(&ev, session); + process(&ev, NULL, session); err = read_tracing_data(fd, pattrs, nb_events); write_padded(fd, NULL, 0, padding); @@ -1186,7 +1185,7 @@ int event__synthesize_build_id(struct dso *pos, u16 misc, ev.build_id.header.size = sizeof(ev.build_id) + len; memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); - err = process(&ev, session); + err = process(&ev, NULL, session); return err; } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 587d375d343..ee789856a8c 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -52,8 +52,10 @@ struct sym_priv { struct events_stats { u64 total_period; u64 total_lost; + u64 total_invalid_chains; u32 nr_events[PERF_RECORD_HEADER_MAX]; u32 nr_unknown_events; + u32 nr_invalid_chains; }; enum hist_column { diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 52672dad1fe..08ec018966a 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -70,6 +70,11 @@ void perf_session__update_sample_type(struct perf_session *self) self->sample_type = perf_header__sample_type(&self->header); } +void perf_session__set_sample_type(struct perf_session *session, u64 type) +{ + session->sample_type = type; +} + int perf_session__create_kernel_maps(struct perf_session *self) { int ret = machine__create_kernel_maps(&self->host_machine); @@ -240,7 +245,15 @@ struct map_symbol *perf_session__resolve_callchain(struct perf_session *self, return syms; } +static int process_event_synth_stub(event_t *event __used, + struct perf_session *session __used) +{ + dump_printf(": unhandled!\n"); + return 0; +} + static int process_event_stub(event_t *event __used, + struct sample_data *sample __used, struct perf_session *session __used) { dump_printf(": unhandled!\n"); @@ -280,13 +293,13 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) if (handler->unthrottle == NULL) handler->unthrottle = process_event_stub; if (handler->attr == NULL) - handler->attr = process_event_stub; + handler->attr = process_event_synth_stub; if (handler->event_type == NULL) - handler->event_type = process_event_stub; + handler->event_type = process_event_synth_stub; if (handler->tracing_data == NULL) - handler->tracing_data = process_event_stub; + handler->tracing_data = process_event_synth_stub; if (handler->build_id == NULL) - handler->build_id = process_event_stub; + handler->build_id = process_event_synth_stub; if (handler->finished_round == NULL) { if (handler->ordered_samples) handler->finished_round = process_finished_round; @@ -419,6 +432,7 @@ static void flush_sample_queue(struct perf_session *s, struct ordered_samples *os = &s->ordered_samples; struct list_head *head = &os->samples; struct sample_queue *tmp, *iter; + struct sample_data sample; u64 limit = os->next_flush; u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; @@ -429,7 +443,8 @@ static void flush_sample_queue(struct perf_session *s, if (iter->timestamp > limit) break; - ops->sample(iter->event, s); + event__parse_sample(iter->event, s->sample_type, &sample); + ops->sample(iter->event, &sample, s); os->last_flush = iter->timestamp; list_del(&iter->list); @@ -578,20 +593,29 @@ static int queue_sample_event(event_t *event, struct sample_data *data, return 0; } -static int perf_session__process_sample(event_t *event, struct perf_session *s, +static int perf_session__process_sample(event_t *event, + struct sample_data *sample, + struct perf_session *s, struct perf_event_ops *ops) { - struct sample_data data; - if (!ops->ordered_samples) - return ops->sample(event, s); + return ops->sample(event, sample, s); + + queue_sample_event(event, sample, s); + return 0; +} - bzero(&data, sizeof(struct sample_data)); - event__parse_sample(event, s->sample_type, &data); +static void callchain__dump(struct sample_data *sample) +{ + unsigned int i; - queue_sample_event(event, &data, s); + if (!dump_trace) + return; - return 0; + printf("... chain: nr:%Lu\n", sample->callchain->nr); + + for (i = 0; i < sample->callchain->nr; i++) + printf("..... %2d: %016Lx\n", i, sample->callchain->ips[i]); } static int perf_session__process_event(struct perf_session *self, @@ -599,8 +623,16 @@ static int perf_session__process_event(struct perf_session *self, struct perf_event_ops *ops, u64 file_offset) { + struct sample_data sample; + trace_event(event); + if (self->header.needs_swap && event__swap_ops[event->header.type]) + event__swap_ops[event->header.type](event); + + if (event->header.type == PERF_RECORD_SAMPLE) + event__parse_sample(event, self->sample_type, &sample); + if (event->header.type < PERF_RECORD_HEADER_MAX) { dump_printf("%#Lx [%#x]: PERF_RECORD_%s", file_offset, event->header.size, @@ -608,28 +640,41 @@ static int perf_session__process_event(struct perf_session *self, hists__inc_nr_events(&self->hists, event->header.type); } - if (self->header.needs_swap && event__swap_ops[event->header.type]) - event__swap_ops[event->header.type](event); - switch (event->header.type) { case PERF_RECORD_SAMPLE: - return perf_session__process_sample(event, self, ops); + dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, + sample.pid, sample.tid, sample.ip, sample.period); + + if (self->sample_type & PERF_SAMPLE_CALLCHAIN) { + if (!ip_callchain__valid(sample.callchain, event)) { + pr_debug("call-chain problem with event, " + "skipping it.\n"); + ++self->hists.stats.nr_invalid_chains; + self->hists.stats.total_invalid_chains += sample.period; + return 0; + } + + callchain__dump(&sample); + } + + return perf_session__process_sample(event, &sample, self, ops); + case PERF_RECORD_MMAP: - return ops->mmap(event, self); + return ops->mmap(event, &sample, self); case PERF_RECORD_COMM: - return ops->comm(event, self); + return ops->comm(event, &sample, self); case PERF_RECORD_FORK: - return ops->fork(event, self); + return ops->fork(event, &sample, self); case PERF_RECORD_EXIT: - return ops->exit(event, self); + return ops->exit(event, &sample, self); case PERF_RECORD_LOST: - return ops->lost(event, self); + return ops->lost(event, &sample, self); case PERF_RECORD_READ: - return ops->read(event, self); + return ops->read(event, &sample, self); case PERF_RECORD_THROTTLE: - return ops->throttle(event, self); + return ops->throttle(event, &sample, self); case PERF_RECORD_UNTHROTTLE: - return ops->unthrottle(event, self); + return ops->unthrottle(event, &sample, self); case PERF_RECORD_HEADER_ATTR: return ops->attr(event, self); case PERF_RECORD_HEADER_EVENT_TYPE: @@ -894,6 +939,14 @@ out_err: session->hists.stats.nr_unknown_events); } + if (session->hists.stats.nr_invalid_chains != 0) { + ui__warning("Found invalid callchains!\n\n" + "%u out of %u events were discarded for this reason.\n\n" + "Consider reporting to linux-kernel@vger.kernel.org.\n\n", + session->hists.stats.nr_invalid_chains, + session->hists.stats.nr_events[PERF_RECORD_SAMPLE]); + } + perf_session_free_sample_buffers(session); return err; } diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 5bf6efa3788..4578f86a620 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -54,7 +54,9 @@ struct perf_session { struct perf_event_ops; -typedef int (*event_op)(event_t *self, struct perf_session *session); +typedef int (*event_op)(event_t *self, struct sample_data *sample, + struct perf_session *session); +typedef int (*event_synth_op)(event_t *self, struct perf_session *session); typedef int (*event_op2)(event_t *self, struct perf_session *session, struct perf_event_ops *ops); @@ -67,8 +69,8 @@ struct perf_event_ops { lost, read, throttle, - unthrottle, - attr, + unthrottle; + event_synth_op attr, event_type, tracing_data, build_id; @@ -104,6 +106,7 @@ int perf_session__create_kernel_maps(struct perf_session *self); int do_read(int fd, void *buf, size_t size); void perf_session__update_sample_type(struct perf_session *self); +void perf_session__set_sample_type(struct perf_session *session, u64 type); void perf_session__remove_thread(struct perf_session *self, struct thread *th); static inline -- cgit v1.2.3-70-g09d2 From 21ef97f05a7da5bc23b26cb34d6746f83ca9bf20 Mon Sep 17 00:00:00 2001 From: Ian Munsie Date: Fri, 10 Dec 2010 14:09:16 +1100 Subject: perf session: Fallback to unordered processing if no sample_id_all If we are running the new perf on an old kernel without support for sample_id_all, we should fall back to the old unordered processing of events. If we didn't than we would *always* process events without timestamps out of order, whether or not we hit a reordering race. In other words, instead of there being a chance of not attributing samples correctly, we would guarantee that samples would not be attributed. While processing all events without timestamps before events with timestamps may seem like an intuitive solution, it falls down as PERF_RECORD_EXIT events would also be processed before any samples. Even with a workaround for that case, samples before/after an exec would not be attributed correctly. This patch allows commands to indicate whether they need to fall back to unordered processing, so that commands that do not care about timestamps on every event will not be affected. If we do fallback, this will print out a warning if report -D was invoked. This patch adds the test in perf_session__new so that we only need to test once per session. Commands that do not use an event_ops (such as record and top) can simply pass NULL in it's place. Acked-by: Thomas Gleixner Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Thomas Gleixner LKML-Reference: <1291951882-sup-6069@au1.ibm.com> Signed-off-by: Ian Munsie Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-buildid-list.c | 3 ++- tools/perf/builtin-diff.c | 4 ++-- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-kmem.c | 3 ++- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-sched.c | 3 ++- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-timechart.c | 3 ++- tools/perf/builtin-top.c | 2 +- tools/perf/util/session.c | 11 ++++++++++- tools/perf/util/session.h | 5 ++++- 14 files changed, 31 insertions(+), 15 deletions(-) (limited to 'tools/perf/builtin-annotate.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 569a2761b90..48dbab4b482 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -382,7 +382,7 @@ static int __cmd_annotate(void) int ret; struct perf_session *session; - session = perf_session__new(input_name, O_RDONLY, force, false); + session = perf_session__new(input_name, O_RDONLY, force, false, &event_ops); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 44a47e13bd6..3b06f9ca263 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -39,7 +39,8 @@ static int __cmd_buildid_list(void) int err = -1; struct perf_session *session; - session = perf_session__new(input_name, O_RDONLY, force, false); + session = perf_session__new(input_name, O_RDONLY, force, false, + &build_id__mark_dso_hit_ops); if (session == NULL) return -1; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 5e1a043aae0..af84e1c0519 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -142,8 +142,8 @@ static int __cmd_diff(void) int ret, i; struct perf_session *session[2]; - session[0] = perf_session__new(input_old, O_RDONLY, force, false); - session[1] = perf_session__new(input_new, O_RDONLY, force, false); + session[0] = perf_session__new(input_old, O_RDONLY, force, false, &event_ops); + session[1] = perf_session__new(input_new, O_RDONLY, force, false, &event_ops); if (session[0] == NULL || session[1] == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 4b66b857941..0c78ffa7bf6 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -196,7 +196,7 @@ static int __cmd_inject(void) inject_ops.tracing_data = event__repipe_tracing_data; } - session = perf_session__new(input_name, O_RDONLY, false, true); + session = perf_session__new(input_name, O_RDONLY, false, true, &inject_ops); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index c9620ff6496..def7ddc2fd4 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -481,7 +481,8 @@ static void sort_result(void) static int __cmd_kmem(void) { int err = -EINVAL; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, false, &event_ops); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index b41b4492b1c..b9c6e543297 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -858,7 +858,7 @@ static struct perf_event_ops eops = { static int read_events(void) { - session = perf_session__new(input_name, O_RDONLY, 0, false); + session = perf_session__new(input_name, O_RDONLY, 0, false, &eops); if (!session) die("Initializing perf session failed\n"); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e9be6ae87a2..efd1b3c3d4a 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -572,7 +572,7 @@ static int __cmd_record(int argc, const char **argv) } session = perf_session__new(output_name, O_WRONLY, - write_mode == WRITE_FORCE, false); + write_mode == WRITE_FORCE, false, NULL); if (session == NULL) { pr_err("Not enough memory for reading perf file header\n"); return -1; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index b6a2a899aa8..fd4c4500cd1 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -308,7 +308,7 @@ static int __cmd_report(void) signal(SIGINT, sig_handler); - session = perf_session__new(input_name, O_RDONLY, force, false); + session = perf_session__new(input_name, O_RDONLY, force, false, &event_ops); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index c7753940aea..7a4ebeb8b01 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1643,7 +1643,8 @@ static struct perf_event_ops event_ops = { static int read_events(void) { int err = -EINVAL; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, false, &event_ops); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 54f1ea808db..6ef65c04ab9 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -779,7 +779,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) if (!script_name) setup_pager(); - session = perf_session__new(input_name, O_RDONLY, 0, false); + session = perf_session__new(input_name, O_RDONLY, 0, false, &event_ops); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index d2fc46103f8..459b5e3db26 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -937,7 +937,8 @@ static struct perf_event_ops event_ops = { static int __cmd_timechart(void) { - struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, false, &event_ops); int ret = -EINVAL; if (session == NULL) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0515ce9d3d3..ae15f046c40 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1272,7 +1272,7 @@ static int __cmd_top(void) * FIXME: perf_session__new should allow passing a O_MMAP, so that all this * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. */ - struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false); + struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false, NULL); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index b59abf5aba3..0f7e544544f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -125,7 +125,9 @@ static void perf_session__destroy_kernel_maps(struct perf_session *self) machines__destroy_guest_kernel_maps(&self->machines); } -struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) +struct perf_session *perf_session__new(const char *filename, int mode, + bool force, bool repipe, + struct perf_event_ops *ops) { size_t len = filename ? strlen(filename) + 1 : 0; struct perf_session *self = zalloc(sizeof(*self) + len); @@ -170,6 +172,13 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc } perf_session__update_sample_type(self); + + if (ops && ops->ordering_requires_timestamps && + ops->ordered_samples && !self->sample_id_all) { + dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); + ops->ordered_samples = false; + } + out: return self; out_free: diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index ac36f99f14a..ffe4b98db8f 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -78,9 +78,12 @@ struct perf_event_ops { build_id; event_op2 finished_round; bool ordered_samples; + bool ordering_requires_timestamps; }; -struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe); +struct perf_session *perf_session__new(const char *filename, int mode, + bool force, bool repipe, + struct perf_event_ops *ops); void perf_session__delete(struct perf_session *self); void perf_event_header__bswap(struct perf_event_header *self); -- cgit v1.2.3-70-g09d2 From eac23d1c384b55e4bbb89ea9e5a6bb77fb4d1140 Mon Sep 17 00:00:00 2001 From: Ian Munsie Date: Thu, 9 Dec 2010 16:33:53 +1100 Subject: perf record,report,annotate,diff: Process events in order This patch changes perf report to ask for the ID info on all events be default if recording from multiple CPUs. Perf report, annotate and diff will now process the events in order if the kernel is able to provide timestamps on all events. This ensures that events such as COMM and MMAP which are necessary to correctly interpret samples are processed prior to those samples so that they are attributed correctly. Before: # perf record ./cachetest # perf report # Events: 6K cycles # # Overhead Command Shared Object Symbol # ........ ....... ................. ............................... # 74.11% :3259 [unknown] [k] 0x4a6c 1.50% cachetest ld-2.11.2.so [.] 0x1777c 1.46% :3259 [kernel.kallsyms] [k] .perf_event_mmap_ctx 1.25% :3259 [kernel.kallsyms] [k] restore 0.74% :3259 [kernel.kallsyms] [k] ._raw_spin_lock 0.71% :3259 [kernel.kallsyms] [k] .filemap_fault 0.66% :3259 [kernel.kallsyms] [k] .memset 0.54% cachetest [kernel.kallsyms] [k] .sha_transform 0.54% :3259 [kernel.kallsyms] [k] .copy_4K_page 0.54% :3259 [kernel.kallsyms] [k] .find_get_page 0.52% :3259 [kernel.kallsyms] [k] .trace_hardirqs_off 0.50% :3259 [kernel.kallsyms] [k] .__do_fault After: # perf report # Events: 6K cycles # # Overhead Command Shared Object Symbol # ........ ....... ................. ............................... # 44.28% cachetest cachetest [.] sumArrayNaive 22.53% cachetest cachetest [.] sumArrayOptimal 6.59% cachetest ld-2.11.2.so [.] 0x1777c 2.13% cachetest [unknown] [k] 0x340 1.46% cachetest [kernel.kallsyms] [k] .perf_event_mmap_ctx 1.25% cachetest [kernel.kallsyms] [k] restore 0.74% cachetest [kernel.kallsyms] [k] ._raw_spin_lock 0.71% cachetest [kernel.kallsyms] [k] .filemap_fault 0.66% cachetest [kernel.kallsyms] [k] .memset 0.54% cachetest [kernel.kallsyms] [k] .copy_4K_page 0.54% cachetest [kernel.kallsyms] [k] .find_get_page 0.54% cachetest [kernel.kallsyms] [k] .sha_transform 0.52% cachetest [kernel.kallsyms] [k] .trace_hardirqs_off 0.50% cachetest [kernel.kallsyms] [k] .__do_fault Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Thomas Gleixner LKML-Reference: <1291872833-839-1-git-send-email-imunsie@au1.ibm.com> Signed-off-by: Ian Munsie Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 2 ++ tools/perf/builtin-diff.c | 2 ++ tools/perf/builtin-record.c | 5 ++++- tools/perf/builtin-report.c | 2 ++ 4 files changed, 10 insertions(+), 1 deletion(-) (limited to 'tools/perf/builtin-annotate.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 48dbab4b482..c056cdc0691 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -375,6 +375,8 @@ static struct perf_event_ops event_ops = { .mmap = event__process_mmap, .comm = event__process_comm, .fork = event__process_task, + .ordered_samples = true, + .ordering_requires_timestamps = true, }; static int __cmd_annotate(void) diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index af84e1c0519..97846dcafc6 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -61,6 +61,8 @@ static struct perf_event_ops event_ops = { .exit = event__process_task, .fork = event__process_task, .lost = event__process_lost, + .ordered_samples = true, + .ordering_requires_timestamps = true, }; static void perf_session__insert_hist_entry_by_name(struct rb_root *root, diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index efd1b3c3d4a..5149e3deb7b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -285,7 +285,7 @@ static void create_counter(int counter, int cpu) if (system_wide) attr->sample_type |= PERF_SAMPLE_CPU; - if (sample_time) + if (sample_time || system_wide || !no_inherit || cpu_list) attr->sample_type |= PERF_SAMPLE_TIME; if (raw_samples) { @@ -327,6 +327,9 @@ try_again: * Old kernel, no attr->sample_id_type_all field */ sample_id_all_avail = false; + if (!sample_time && !raw_samples) + attr->sample_type &= ~PERF_SAMPLE_TIME; + goto retry_sample_id; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index fd4c4500cd1..4af7ce6e155 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -244,6 +244,8 @@ static struct perf_event_ops event_ops = { .event_type = event__process_event_type, .tracing_data = event__process_tracing_data, .build_id = event__process_build_id, + .ordered_samples = true, + .ordering_requires_timestamps = true, }; extern volatile int session_done; -- cgit v1.2.3-70-g09d2 From 9486aa38771661e96fbb51c549b9901b5df609d8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 22 Jan 2011 20:37:02 -0200 Subject: perf tools: Fix 64 bit integer format strings Using %L[uxd] has issues in some architectures, like on ppc64. Fix it by making our 64 bit integers typedefs of stdint.h types and using PRI[ux]64 like, for instance, git does. Reported by Denis Kirjanov that provided a patch for one case, I went and changed all cases. Reported-by: Denis Kirjanov Tested-by: Denis Kirjanov LKML-Reference: <20110120093246.GA8031@hera.kernel.org> Cc: Denis Kirjanov Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Pingtian Han Cc: Stephane Eranian Cc: Tom Zanussi Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 6 +++--- tools/perf/builtin-kmem.c | 4 ++-- tools/perf/builtin-lock.c | 6 +++--- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-sched.c | 20 ++++++++++---------- tools/perf/builtin-script.c | 6 +++--- tools/perf/builtin-stat.c | 4 ++-- tools/perf/builtin-test.c | 14 +++++++------- tools/perf/builtin-top.c | 9 +++++---- tools/perf/util/event.c | 5 +++-- tools/perf/util/header.c | 4 ++-- tools/perf/util/hist.c | 17 +++++++++-------- tools/perf/util/map.c | 3 ++- tools/perf/util/parse-events.c | 2 +- tools/perf/util/probe-event.c | 2 +- tools/perf/util/session.c | 28 +++++++++++++++------------- tools/perf/util/svghelper.c | 5 +++-- tools/perf/util/symbol.c | 9 +++++---- tools/perf/util/types.h | 10 ++++++---- tools/perf/util/ui/browsers/hists.c | 2 +- tools/perf/util/ui/browsers/map.c | 5 +++-- tools/perf/util/values.c | 10 +++++----- 23 files changed, 93 insertions(+), 82 deletions(-) (limited to 'tools/perf/builtin-annotate.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index c056cdc0691..8879463807e 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -212,7 +212,7 @@ get_source_line(struct hist_entry *he, int len, const char *filename) continue; offset = start + i; - sprintf(cmd, "addr2line -e %s %016llx", filename, offset); + sprintf(cmd, "addr2line -e %s %016" PRIx64, filename, offset); fp = popen(cmd, "r"); if (!fp) continue; @@ -270,9 +270,9 @@ static void hist_entry__print_hits(struct hist_entry *self) for (offset = 0; offset < len; ++offset) if (h->ip[offset] != 0) - printf("%*Lx: %Lu\n", BITS_PER_LONG / 2, + printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, sym->start + offset, h->ip[offset]); - printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum); + printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); } static int hist_entry__tty_annotate(struct hist_entry *he) diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index def7ddc2fd4..d97256d6598 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -371,10 +371,10 @@ static void __print_result(struct rb_root *root, struct perf_session *session, addr = data->ptr; if (sym != NULL) - snprintf(buf, sizeof(buf), "%s+%Lx", sym->name, + snprintf(buf, sizeof(buf), "%s+%" PRIx64 "", sym->name, addr - map->unmap_ip(map, sym->start)); else - snprintf(buf, sizeof(buf), "%#Lx", addr); + snprintf(buf, sizeof(buf), "%#" PRIx64 "", addr); printf(" %-34s |", buf); printf(" %9llu/%-5lu | %9llu/%-5lu | %8lu | %8lu | %6.3f%%\n", diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index b9c6e543297..2b36defc5d7 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -782,9 +782,9 @@ static void print_result(void) pr_info("%10u ", st->nr_acquired); pr_info("%10u ", st->nr_contended); - pr_info("%15llu ", st->wait_time_total); - pr_info("%15llu ", st->wait_time_max); - pr_info("%15llu ", st->wait_time_min == ULLONG_MAX ? + pr_info("%15" PRIu64 " ", st->wait_time_total); + pr_info("%15" PRIu64 " ", st->wait_time_max); + pr_info("%15" PRIu64 " ", st->wait_time_min == ULLONG_MAX ? 0 : st->wait_time_min); pr_info("\n"); } diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index fcd29e8af29..b2f729fdb31 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -817,7 +817,7 @@ static int __cmd_record(int argc, const char **argv) * Approximate RIP event size: 24 bytes. */ fprintf(stderr, - "[ perf record: Captured and wrote %.3f MB %s (~%lld samples) ]\n", + "[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64 " samples) ]\n", (double)bytes_written / 1024.0 / 1024.0, output_name, bytes_written / 24); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 75183a4518e..c27e31f289e 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -197,7 +197,7 @@ static int process_read_event(event_t *event, struct sample_data *sample __used, event->read.value); } - dump_printf(": %d %d %s %Lu\n", event->read.pid, event->read.tid, + dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, attr ? __event_name(attr->type, attr->config) : "FAIL", event->read.value); diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 29e7ffd8569..29acb894e03 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -193,7 +193,7 @@ static void calibrate_run_measurement_overhead(void) } run_measurement_overhead = min_delta; - printf("run measurement overhead: %Ld nsecs\n", min_delta); + printf("run measurement overhead: %" PRIu64 " nsecs\n", min_delta); } static void calibrate_sleep_measurement_overhead(void) @@ -211,7 +211,7 @@ static void calibrate_sleep_measurement_overhead(void) min_delta -= 10000; sleep_measurement_overhead = min_delta; - printf("sleep measurement overhead: %Ld nsecs\n", min_delta); + printf("sleep measurement overhead: %" PRIu64 " nsecs\n", min_delta); } static struct sched_atom * @@ -617,13 +617,13 @@ static void test_calibrations(void) burn_nsecs(1e6); T1 = get_nsecs(); - printf("the run test took %Ld nsecs\n", T1-T0); + printf("the run test took %" PRIu64 " nsecs\n", T1 - T0); T0 = get_nsecs(); sleep_nsecs(1e6); T1 = get_nsecs(); - printf("the sleep test took %Ld nsecs\n", T1-T0); + printf("the sleep test took %" PRIu64 " nsecs\n", T1 - T0); } #define FILL_FIELD(ptr, field, event, data) \ @@ -816,10 +816,10 @@ replay_switch_event(struct trace_switch_event *switch_event, delta = 0; if (delta < 0) - die("hm, delta: %Ld < 0 ?\n", delta); + die("hm, delta: %" PRIu64 " < 0 ?\n", delta); if (verbose) { - printf(" ... switch from %s/%d to %s/%d [ran %Ld nsecs]\n", + printf(" ... switch from %s/%d to %s/%d [ran %" PRIu64 " nsecs]\n", switch_event->prev_comm, switch_event->prev_pid, switch_event->next_comm, switch_event->next_pid, delta); @@ -1048,7 +1048,7 @@ latency_switch_event(struct trace_switch_event *switch_event, delta = 0; if (delta < 0) - die("hm, delta: %Ld < 0 ?\n", delta); + die("hm, delta: %" PRIu64 " < 0 ?\n", delta); sched_out = perf_session__findnew(session, switch_event->prev_pid); @@ -1221,7 +1221,7 @@ static void output_lat_thread(struct work_atoms *work_list) avg = work_list->total_lat / work_list->nb_atoms; - printf("|%11.3f ms |%9llu | avg:%9.3f ms | max:%9.3f ms | max at: %9.6f s\n", + printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: %9.6f s\n", (double)work_list->total_runtime / 1e6, work_list->nb_atoms, (double)avg / 1e6, (double)work_list->max_lat / 1e6, @@ -1423,7 +1423,7 @@ map_switch_event(struct trace_switch_event *switch_event, delta = 0; if (delta < 0) - die("hm, delta: %Ld < 0 ?\n", delta); + die("hm, delta: %" PRIu64 " < 0 ?\n", delta); sched_out = perf_session__findnew(session, switch_event->prev_pid); @@ -1713,7 +1713,7 @@ static void __cmd_lat(void) } printf(" -----------------------------------------------------------------------------------------\n"); - printf(" TOTAL: |%11.3f ms |%9Ld |\n", + printf(" TOTAL: |%11.3f ms |%9" PRIu64 " |\n", (double)all_runtime/1e6, all_count); printf(" ---------------------------------------------------\n"); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 150a606002e..b766c2a9ac9 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -77,8 +77,8 @@ static int process_sample_event(event_t *event, struct sample_data *sample, if (session->sample_type & PERF_SAMPLE_RAW) { if (debug_mode) { if (sample->time < last_timestamp) { - pr_err("Samples misordered, previous: %llu " - "this: %llu\n", last_timestamp, + pr_err("Samples misordered, previous: %" PRIu64 + " this: %" PRIu64 "\n", last_timestamp, sample->time); nr_unordered++; } @@ -126,7 +126,7 @@ static int __cmd_script(struct perf_session *session) ret = perf_session__process_events(session, &event_ops); if (debug_mode) - pr_err("Misordered timestamps: %llu\n", nr_unordered); + pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); return ret; } diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 0ff11d9b13b..a482a191a0c 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -206,8 +206,8 @@ static int read_counter_aggr(struct perf_evsel *counter) update_stats(&ps->res_stats[i], count[i]); if (verbose) { - fprintf(stderr, "%s: %Ld %Ld %Ld\n", event_name(counter), - count[0], count[1], count[2]); + fprintf(stderr, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", + event_name(counter), count[0], count[1], count[2]); } /* diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 0e01834a48d..5dcdba653d7 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -146,7 +146,7 @@ next_pair: if (llabs(skew) < page_size) continue; - pr_debug("%#Lx: diff end addr for %s v: %#Lx k: %#Lx\n", + pr_debug("%#" PRIx64 ": diff end addr for %s v: %#" PRIx64 " k: %#" PRIx64 "\n", sym->start, sym->name, sym->end, pair->end); } else { struct rb_node *nnd; @@ -168,11 +168,11 @@ detour: goto detour; } - pr_debug("%#Lx: diff name v: %s k: %s\n", + pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n", sym->start, sym->name, pair->name); } } else - pr_debug("%#Lx: %s not on kallsyms\n", sym->start, sym->name); + pr_debug("%#" PRIx64 ": %s not on kallsyms\n", sym->start, sym->name); err = -1; } @@ -211,10 +211,10 @@ detour: if (pair->start == pos->start) { pair->priv = 1; - pr_info(" %Lx-%Lx %Lx %s in kallsyms as", + pr_info(" %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", pos->start, pos->end, pos->pgoff, pos->dso->name); if (pos->pgoff != pair->pgoff || pos->end != pair->end) - pr_info(": \n*%Lx-%Lx %Lx", + pr_info(": \n*%" PRIx64 "-%" PRIx64 " %" PRIx64 "", pair->start, pair->end, pair->pgoff); pr_info(" %s\n", pair->dso->name); pair->priv = 1; @@ -307,7 +307,7 @@ static int test__open_syscall_event(void) } if (evsel->counts->cpu[0].val != nr_open_calls) { - pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %Ld\n", + pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n", nr_open_calls, evsel->counts->cpu[0].val); goto out_close_fd; } @@ -421,7 +421,7 @@ static int test__open_syscall_event_on_all_cpus(void) expected = nr_open_calls + cpu; if (evsel->counts->cpu[cpu].val != expected) { - pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %Ld\n", + pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n", expected, cpus->map[cpu], evsel->counts->cpu[cpu].val); goto out_close_fd; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 05344c6210a..b6998e05576 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -214,7 +215,7 @@ static int parse_source(struct sym_entry *syme) len = sym->end - sym->start; sprintf(command, - "objdump --start-address=%#0*Lx --stop-address=%#0*Lx -dS %s", + "objdump --start-address=%#0*" PRIx64 " --stop-address=%#0*" PRIx64 " -dS %s", BITS_PER_LONG / 4, map__rip_2objdump(map, sym->start), BITS_PER_LONG / 4, map__rip_2objdump(map, sym->end), path); @@ -308,7 +309,7 @@ static void lookup_sym_source(struct sym_entry *syme) struct source_line *line; char pattern[PATTERN_LEN + 1]; - sprintf(pattern, "%0*Lx <", BITS_PER_LONG / 4, + sprintf(pattern, "%0*" PRIx64 " <", BITS_PER_LONG / 4, map__rip_2objdump(syme->map, symbol->start)); pthread_mutex_lock(&syme->src->lock); @@ -537,7 +538,7 @@ static void print_sym_table(void) if (nr_counters == 1 || !display_weighted) { struct perf_evsel *first; first = list_entry(evsel_list.next, struct perf_evsel, node); - printf("%Ld", first->attr.sample_period); + printf("%" PRIu64, (uint64_t)first->attr.sample_period); if (freq) printf("Hz "); else @@ -640,7 +641,7 @@ static void print_sym_table(void) percent_color_fprintf(stdout, "%4.1f%%", pcnt); if (verbose) - printf(" %016llx", sym->start); + printf(" %016" PRIx64, sym->start); printf(" %-*.*s", sym_width, sym_width, sym->name); printf(" %-*.*s\n", dso_width, dso_width, dso_width >= syme->map->dso->long_name_len ? diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2302ec051bb..1478ab4ee22 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -459,7 +459,8 @@ int event__process_comm(event_t *self, struct sample_data *sample __used, int event__process_lost(event_t *self, struct sample_data *sample __used, struct perf_session *session) { - dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost); + dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", + self->lost.id, self->lost.lost); session->hists.stats.total_lost += self->lost.lost; return 0; } @@ -575,7 +576,7 @@ int event__process_mmap(event_t *self, struct sample_data *sample __used, u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; int ret = 0; - dump_printf(" %d/%d: [%#Lx(%#Lx) @ %#Lx]: %s\n", + dump_printf(" %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n", self->mmap.pid, self->mmap.tid, self->mmap.start, self->mmap.len, self->mmap.pgoff, self->mmap.filename); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 989fa2dee2f..f6a929e7498 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -798,8 +798,8 @@ static int perf_file_section__process(struct perf_file_section *self, int feat, int fd) { if (lseek(fd, self->offset, SEEK_SET) == (off_t)-1) { - pr_debug("Failed to lseek to %Ld offset for feature %d, " - "continuing...\n", self->offset, feat); + pr_debug("Failed to lseek to %" PRIu64 " offset for feature " + "%d, continuing...\n", self->offset, feat); return 0; } diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index c749ba6136a..32f4f1f2f6e 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -636,13 +636,13 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, } } } else - ret = snprintf(s, size, sep ? "%lld" : "%12lld ", period); + ret = snprintf(s, size, sep ? "%" PRIu64 : "%12" PRIu64 " ", period); if (symbol_conf.show_nr_samples) { if (sep) - ret += snprintf(s + ret, size - ret, "%c%lld", *sep, period); + ret += snprintf(s + ret, size - ret, "%c%" PRIu64, *sep, period); else - ret += snprintf(s + ret, size - ret, "%11lld", period); + ret += snprintf(s + ret, size - ret, "%11" PRIu64, period); } if (pair_hists) { @@ -971,7 +971,7 @@ int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip) sym_size = sym->end - sym->start; offset = ip - sym->start; - pr_debug3("%s: ip=%#Lx\n", __func__, self->ms.map->unmap_ip(self->ms.map, ip)); + pr_debug3("%s: ip=%#" PRIx64 "\n", __func__, self->ms.map->unmap_ip(self->ms.map, ip)); if (offset >= sym_size) return 0; @@ -980,8 +980,9 @@ int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip) h->sum++; h->ip[offset]++; - pr_debug3("%#Lx %s: period++ [ip: %#Lx, %#Lx] => %Ld\n", self->ms.sym->start, - self->ms.sym->name, ip, ip - self->ms.sym->start, h->ip[offset]); + pr_debug3("%#" PRIx64 " %s: period++ [ip: %#" PRIx64 ", %#" PRIx64 + "] => %" PRIu64 "\n", self->ms.sym->start, self->ms.sym->name, + ip, ip - self->ms.sym->start, h->ip[offset]); return 0; } @@ -1132,7 +1133,7 @@ fallback: goto out_free_filename; } - pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__, + pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, filename, sym->name, map->unmap_ip(map, sym->start), map->unmap_ip(map, sym->end)); @@ -1142,7 +1143,7 @@ fallback: dso, dso->long_name, sym, sym->name); snprintf(command, sizeof(command), - "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS -C %s|grep -v %s|expand", + "objdump --start-address=0x%016" PRIx64 " --stop-address=0x%016" PRIx64 " -dS -C %s|grep -v %s|expand", map__rip_2objdump(map, sym->start), map__rip_2objdump(map, sym->end), symfs_filename, filename); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 3a7eb6ec0ee..a16ecab5229 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -1,5 +1,6 @@ #include "symbol.h" #include +#include #include #include #include @@ -195,7 +196,7 @@ int map__overlap(struct map *l, struct map *r) size_t map__fprintf(struct map *self, FILE *fp) { - return fprintf(fp, " %Lx-%Lx %Lx %s\n", + return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", self->start, self->end, self->pgoff, self->dso->name); } diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index bc2732ee23e..135f69baf96 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -279,7 +279,7 @@ const char *__event_name(int type, u64 config) static char buf[32]; if (type == PERF_TYPE_RAW) { - sprintf(buf, "raw 0x%llx", config); + sprintf(buf, "raw 0x%" PRIx64, config); return buf; } diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 128aaab0aed..6e29d9c9dcc 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -172,7 +172,7 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, sym = __find_kernel_function_by_name(tp->symbol, &map); if (sym) { addr = map->unmap_ip(map, sym->start + tp->offset); - pr_debug("try to find %s+%ld@%llx\n", tp->symbol, + pr_debug("try to find %s+%ld@%" PRIx64 "\n", tp->symbol, tp->offset, addr); ret = find_perf_probe_point((unsigned long)addr, pp); } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 313dac2d94c..105f00bfd55 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -652,10 +652,11 @@ static void callchain__printf(struct sample_data *sample) { unsigned int i; - printf("... chain: nr:%Lu\n", sample->callchain->nr); + printf("... chain: nr:%" PRIu64 "\n", sample->callchain->nr); for (i = 0; i < sample->callchain->nr; i++) - printf("..... %2d: %016Lx\n", i, sample->callchain->ips[i]); + printf("..... %2d: %016" PRIx64 "\n", + i, sample->callchain->ips[i]); } static void perf_session__print_tstamp(struct perf_session *session, @@ -672,7 +673,7 @@ static void perf_session__print_tstamp(struct perf_session *session, printf("%u ", sample->cpu); if (session->sample_type & PERF_SAMPLE_TIME) - printf("%Lu ", sample->time); + printf("%" PRIu64 " ", sample->time); } static void dump_event(struct perf_session *session, event_t *event, @@ -681,16 +682,16 @@ static void dump_event(struct perf_session *session, event_t *event, if (!dump_trace) return; - printf("\n%#Lx [%#x]: event: %d\n", file_offset, event->header.size, - event->header.type); + printf("\n%#" PRIx64 " [%#x]: event: %d\n", + file_offset, event->header.size, event->header.type); trace_event(event); if (sample) perf_session__print_tstamp(session, event, sample); - printf("%#Lx [%#x]: PERF_RECORD_%s", file_offset, event->header.size, - event__get_event_name(event->header.type)); + printf("%#" PRIx64 " [%#x]: PERF_RECORD_%s", file_offset, + event->header.size, event__get_event_name(event->header.type)); } static void dump_sample(struct perf_session *session, event_t *event, @@ -699,8 +700,9 @@ static void dump_sample(struct perf_session *session, event_t *event, if (!dump_trace) return; - printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, - sample->pid, sample->tid, sample->ip, sample->period); + printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 "\n", + event->header.misc, sample->pid, sample->tid, sample->ip, + sample->period); if (session->sample_type & PERF_SAMPLE_CALLCHAIN) callchain__printf(sample); @@ -843,8 +845,8 @@ static void perf_session__warn_about_errors(const struct perf_session *session, { if (ops->lost == event__process_lost && session->hists.stats.total_lost != 0) { - ui__warning("Processed %Lu events and LOST %Lu!\n\n" - "Check IO/CPU overload!\n\n", + ui__warning("Processed %" PRIu64 " events and LOST %" PRIu64 + "!\n\nCheck IO/CPU overload!\n\n", session->hists.stats.total_period, session->hists.stats.total_lost); } @@ -918,7 +920,7 @@ more: if (size == 0 || (skip = perf_session__process_event(self, &event, ops, head)) < 0) { - dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n", + dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n", head, event.header.size, event.header.type); /* * assume we lost track of the stream, check alignment, and @@ -1023,7 +1025,7 @@ more: if (size == 0 || perf_session__process_event(session, event, ops, file_pos) < 0) { - dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n", + dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n", file_offset + head, event->header.size, event->header.type); /* diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index b3637db025a..805220afc08 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -12,6 +12,7 @@ * of the License. */ +#include #include #include #include @@ -94,7 +95,7 @@ void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end) total_height = (1 + rows + cpu2slot(cpus)) * SLOT_MULT; fprintf(svgfile, " \n"); - fprintf(svgfile, "\n", svg_page_width, total_height); + fprintf(svgfile, "\n", svg_page_width, total_height); fprintf(svgfile, "\n