From b226a5a72901bc9c73d639ea2e53e6c304bf3b74 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Tue, 7 Dec 2010 19:39:46 -0700 Subject: [PATCH 01/10] perf report: Allow user to specify path to kallsyms file This is useful for analyzing a perf data file on a different system than the one data was collected on and still include symbols from loaded kernel modules in the output. Commiter note: Updated the man page accordingly. LKML-Reference: <1291775986-16475-1-git-send-email-daahern@cisco.com> Signed-off-by: David Ahern Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-report.txt | 3 +++ tools/perf/builtin-report.c | 2 ++ tools/perf/util/symbol.c | 9 +++++++-- tools/perf/util/symbol.h | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 59a1f57f2bb72..fefea77ec6e9c 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -104,6 +104,9 @@ OPTIONS --vmlinux=:: vmlinux pathname +--kallsyms=:: + kallsyms pathname + -m:: --modules:: Load module symbols. WARNING: This should only be used with -k and diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 904519fba4347..b6a2a899aa8fb 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -443,6 +443,8 @@ static const struct option options[] = { "dump raw trace in ASCII"), OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, "file", "vmlinux pathname"), + OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, + "file", "kallsyms pathname"), OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, "load module symbols - WARNING: use only with -k and LIVE kernel"), diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a348906b587d7..f40c076aeb7b0 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1830,8 +1830,8 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, const char *kallsyms_filename = NULL; char *kallsyms_allocated_filename = NULL; /* - * Step 1: if the user specified a vmlinux filename, use it and only - * it, reporting errors to the user if it cannot be used. + * Step 1: if the user specified a kallsyms or vmlinux filename, use + * it and only it, reporting errors to the user if it cannot be used. * * For instance, try to analyse an ARM perf.data file _without_ a * build-id, or if the user specifies the wrong path to the right @@ -1844,6 +1844,11 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, * validation in dso__load_vmlinux and will bail out if they don't * match. */ + if (symbol_conf.kallsyms_name != NULL) { + kallsyms_filename = symbol_conf.kallsyms_name; + goto do_kallsyms; + } + if (symbol_conf.vmlinux_name != NULL) { err = dso__load_vmlinux(self, map, symbol_conf.vmlinux_name, filter); diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 038f2201ee095..12defbe18c13f 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -72,6 +72,7 @@ struct symbol_conf { show_cpu_utilization, initialized; const char *vmlinux_name, + *kallsyms_name, *source_prefix, *field_sep; const char *default_guest_vmlinux_name, From 3835bc00c5b2d8e337a6e9d7b44f47e02760dba3 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 7 Dec 2010 12:48:42 +0000 Subject: [PATCH 02/10] perf event: Prevent unbound event__name array access event__name[] is missing an entry for PERF_RECORD_FINISHED_ROUND, but we happily access the array from the dump code. Make event__name[] static and provide an accessor function, fix up all callers and add the missing string. Cc: Frederic Weisbecker Cc: Ian Munsie Cc: Ingo Molnar Cc: Peter Zijlstra LKML-Reference: <20101207124550.432593943@linutronix.de> Signed-off-by: Thomas Gleixner Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.c | 12 +++++++++++- tools/perf/util/event.h | 2 +- tools/perf/util/hist.c | 9 ++++++--- tools/perf/util/session.c | 2 +- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index e4cdc1ebe0fbb..183aedd4db838 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -7,7 +7,7 @@ #include "strlist.h" #include "thread.h" -const char *event__name[] = { +static const char *event__name[] = { [0] = "TOTAL", [PERF_RECORD_MMAP] = "MMAP", [PERF_RECORD_LOST] = "LOST", @@ -22,8 +22,18 @@ const char *event__name[] = { [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", + [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND", }; +const char *event__get_event_name(unsigned int id) +{ + if (id >= ARRAY_SIZE(event__name)) + return "INVALID"; + if (!event__name[id]) + return "UNKNOWN"; + return event__name[id]; +} + static struct sample_data synth_sample = { .pid = -1, .tid = -1, diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index a95ab18575cea..4716a8f6d3eb8 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -171,6 +171,6 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, int event__parse_sample(const event_t *event, struct perf_session *session, struct sample_data *sample); -extern const char *event__name[]; +const char *event__get_event_name(unsigned int id); #endif /* __PERF_RECORD_H */ diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 2022e87409942..a3b84160c42eb 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1168,10 +1168,13 @@ size_t hists__fprintf_nr_events(struct hists *self, FILE *fp) size_t ret = 0; for (i = 0; i < PERF_RECORD_HEADER_MAX; ++i) { - if (!event__name[i]) + const char *name = event__get_event_name(i); + + if (!strcmp(name, "UNKNOWN")) continue; - ret += fprintf(fp, "%10s events: %10d\n", - event__name[i], self->stats.nr_events[i]); + + ret += fprintf(fp, "%16s events: %10d\n", name, + self->stats.nr_events[i]); } return ret; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 3074d38897e6a..b3b145a8ff7c4 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -718,7 +718,7 @@ static int perf_session__process_event(struct perf_session *session, if (event->header.type < PERF_RECORD_HEADER_MAX) { dump_printf("%#Lx [%#x]: PERF_RECORD_%s", file_offset, event->header.size, - event__name[event->header.type]); + event__get_event_name(event->header.type)); hists__inc_nr_events(&session->hists, event->header.type); } From 79a14c1f458d598642bf11f09512c83d33a114e6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 7 Dec 2010 12:48:44 +0000 Subject: [PATCH 03/10] perf session: Dont queue events w/o timestamps If the event has no timestamp assigned then the parse code sets it to ~0ULL which causes the ordering code to enqueue it at the end. Process it right away. Reported-by: Ian Munsie Cc: Frederic Weisbecker Cc: Ian Munsie Cc: Ingo Molnar Cc: Peter Zijlstra LKML-Reference: <20101207124550.528788441@linutronix.de> Signed-off-by: Thomas Gleixner Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index b3b145a8ff7c4..e5d0ed9603eeb 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -603,7 +603,7 @@ static int perf_session_queue_event(struct perf_session *s, event_t *event, u64 timestamp = data->time; struct sample_queue *new; - if (!timestamp) + if (!timestamp || timestamp == ~0ULL) return -ETIME; if (timestamp < s->ordered_samples.last_flush) { From 9aefcab0de472ee2b3ab195a6827ddd4b170e3a7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 7 Dec 2010 12:48:47 +0000 Subject: [PATCH 04/10] perf session: Consolidate the dump code The dump code used by perf report -D is scattered all over the place. Move it to separate functions. Acked-by: Ian Munsie Cc: Frederic Weisbecker Cc: Ian Munsie Cc: Ingo Molnar Cc: Peter Zijlstra LKML-Reference: <20101207124550.625434869@linutronix.de> Signed-off-by: Thomas Gleixner Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.h | 1 + tools/perf/util/session.c | 64 ++++++++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 4716a8f6d3eb8..2b7e91902f105 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -85,6 +85,7 @@ struct build_id_event { }; enum perf_user_event_type { /* above any possible kernel type */ + PERF_RECORD_USER_TYPE_START = 64, PERF_RECORD_HEADER_ATTR = 64, PERF_RECORD_HEADER_EVENT_TYPE = 65, PERF_RECORD_HEADER_TRACING_DATA = 66, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index e5d0ed9603eeb..12761d5bc92a2 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -665,6 +665,35 @@ static void perf_session__print_tstamp(struct perf_session *session, printf("%Lu ", sample->time); } +static void dump_event(struct perf_session *session, event_t *event, + u64 file_offset, struct sample_data *sample) +{ + if (!dump_trace) + return; + + dump_printf("\n%#Lx [%#x]: event: %d\n", file_offset, + event->header.size, event->header.type); + + trace_event(event); + + if (sample) + perf_session__print_tstamp(session, event, sample); + + dump_printf("%#Lx [%#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, + struct sample_data *sample) +{ + dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, + sample->pid, sample->tid, sample->ip, sample->period); + + if (session->sample_type & PERF_SAMPLE_CALLCHAIN) + callchain__dump(sample); +} + static int perf_session_deliver_event(struct perf_session *session, event_t *event, struct sample_data *sample, @@ -703,32 +732,24 @@ static int perf_session__process_event(struct perf_session *session, struct sample_data sample; int ret; - trace_event(event); - if (session->header.needs_swap && event__swap_ops[event->header.type]) event__swap_ops[event->header.type](event); - if (event->header.type >= PERF_RECORD_MMAP && - event->header.type <= PERF_RECORD_SAMPLE) { - event__parse_sample(event, session, &sample); - if (dump_trace) - perf_session__print_tstamp(session, event, &sample); - } + if (event->header.type >= PERF_RECORD_HEADER_MAX) + return -EINVAL; - if (event->header.type < PERF_RECORD_HEADER_MAX) { - dump_printf("%#Lx [%#x]: PERF_RECORD_%s", - file_offset, event->header.size, - event__get_event_name(event->header.type)); - hists__inc_nr_events(&session->hists, event->header.type); + hists__inc_nr_events(&session->hists, event->header.type); + + if (event->header.type >= PERF_RECORD_USER_TYPE_START) + dump_event(session, event, file_offset, NULL); + else { + event__parse_sample(event, session, &sample); + dump_event(session, event, file_offset, &sample); } /* These events are processed right away */ switch (event->header.type) { case PERF_RECORD_SAMPLE: - dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", - event->header.misc, - sample.pid, sample.tid, sample.ip, sample.period); - if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { if (!ip_callchain__valid(sample.callchain, event)) { pr_debug("call-chain problem with event, " @@ -738,9 +759,8 @@ static int perf_session__process_event(struct perf_session *session, sample.period; return 0; } - - callchain__dump(&sample); } + dump_sample(session, event, &sample); break; case PERF_RECORD_HEADER_ATTR: @@ -870,9 +890,6 @@ static int __perf_session__process_pipe_events(struct perf_session *self, head += size; - dump_printf("\n%#Lx [%#x]: event: %d\n", - head, event.header.size, event.header.type); - if (skip > 0) head += skip; @@ -961,9 +978,6 @@ int __perf_session__process_events(struct perf_session *session, size = event->header.size; - dump_printf("\n%#Lx [%#x]: event: %d\n", - file_pos, event->header.size, event->header.type); - if (size == 0 || perf_session__process_event(session, event, ops, file_pos) < 0) { dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n", From e4c2df132fef60a28b851abc1859a531e64f350c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 7 Dec 2010 12:48:50 +0000 Subject: [PATCH 05/10] perf session: Store file offset in sample_queue Preparatory patch for ordered output of perf report -D. Acked-by: Ian Munsie Cc: Frederic Weisbecker Cc: Ian Munsie Cc: Ingo Molnar Cc: Peter Zijlstra LKML-Reference: <20101207124550.725128545@linutronix.de> Signed-off-by: Thomas Gleixner Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 12761d5bc92a2..a4339548de672 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -444,6 +444,7 @@ static event__swap_op event__swap_ops[] = { struct sample_queue { u64 timestamp; + u64 file_offset; event_t *event; struct list_head list; }; @@ -596,7 +597,7 @@ static void __queue_event(struct sample_queue *new, struct perf_session *s) #define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct sample_queue)) static int perf_session_queue_event(struct perf_session *s, event_t *event, - struct sample_data *data) + struct sample_data *data, u64 file_offset) { struct ordered_samples *os = &s->ordered_samples; struct list_head *sc = &os->sample_cache; @@ -628,6 +629,7 @@ static int perf_session_queue_event(struct perf_session *s, event_t *event, } new->timestamp = timestamp; + new->file_offset = file_offset; new->event = event; __queue_event(new, s); @@ -780,7 +782,8 @@ static int perf_session__process_event(struct perf_session *session, } if (ops->ordered_samples) { - ret = perf_session_queue_event(session, event, &sample); + ret = perf_session_queue_event(session, event, &sample, + file_offset); if (ret != -ETIME) return ret; } From f74725dcf2f6931c26bc65e77e34e693eeb8441c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 7 Dec 2010 12:48:53 +0000 Subject: [PATCH 06/10] perf session: Add file_offset to event delivery function Preparatory patch for ordered output of perf report -D Acked-by: Ian Munsie Cc: Frederic Weisbecker Cc: Ian Munsie Cc: Ingo Molnar Cc: Peter Zijlstra LKML-Reference: <20101207124550.818568607@linutronix.de> Signed-off-by: Thomas Gleixner Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index a4339548de672..d43e56cd6f28e 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -465,7 +465,8 @@ static void perf_session_free_sample_buffers(struct perf_session *session) static int perf_session_deliver_event(struct perf_session *session, event_t *event, struct sample_data *sample, - struct perf_event_ops *ops); + struct perf_event_ops *ops, + u64 file_offset); static void flush_sample_queue(struct perf_session *s, struct perf_event_ops *ops) @@ -485,7 +486,8 @@ static void flush_sample_queue(struct perf_session *s, break; event__parse_sample(iter->event, s, &sample); - perf_session_deliver_event(s, iter->event, &sample, ops); + perf_session_deliver_event(s, iter->event, &sample, ops, + iter->file_offset); os->last_flush = iter->timestamp; list_del(&iter->list); @@ -699,7 +701,8 @@ static void dump_sample(struct perf_session *session, event_t *event, static int perf_session_deliver_event(struct perf_session *session, event_t *event, struct sample_data *sample, - struct perf_event_ops *ops) + struct perf_event_ops *ops, + u64 file_offset __used) { switch (event->header.type) { case PERF_RECORD_SAMPLE: @@ -788,7 +791,8 @@ static int perf_session__process_event(struct perf_session *session, return ret; } - return perf_session_deliver_event(session, event, &sample, ops); + return perf_session_deliver_event(session, event, &sample, ops, + file_offset); } void perf_event_header__bswap(struct perf_event_header *self) From 532e7269c01098f0be6e08113c6947ec6ed11bfa Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 7 Dec 2010 12:48:55 +0000 Subject: [PATCH 07/10] perf session: Move dump code to event delivery path Preparatory patch for ordered perf report -D Acked-by: Ian Munsie Cc: Frederic Weisbecker Cc: Ian Munsie Cc: Ingo Molnar Cc: Peter Zijlstra LKML-Reference: <20101207124550.918655066@linutronix.de> Signed-off-by: Thomas Gleixner Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index d43e56cd6f28e..7c5cc129207ab 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -702,10 +702,13 @@ static int perf_session_deliver_event(struct perf_session *session, event_t *event, struct sample_data *sample, struct perf_event_ops *ops, - u64 file_offset __used) + u64 file_offset) { + dump_event(session, event, file_offset, sample); + switch (event->header.type) { case PERF_RECORD_SAMPLE: + dump_sample(session, event, sample); return ops->sample(event, sample, session); case PERF_RECORD_MMAP: return ops->mmap(event, sample, session); @@ -747,10 +750,8 @@ static int perf_session__process_event(struct perf_session *session, if (event->header.type >= PERF_RECORD_USER_TYPE_START) dump_event(session, event, file_offset, NULL); - else { + else event__parse_sample(event, session, &sample); - dump_event(session, event, file_offset, &sample); - } /* These events are processed right away */ switch (event->header.type) { @@ -765,7 +766,6 @@ static int perf_session__process_event(struct perf_session *session, return 0; } } - dump_sample(session, event, &sample); break; case PERF_RECORD_HEADER_ATTR: From 3dfc2c0aee789843d18f6e4675658e6879465a56 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 7 Dec 2010 12:48:58 +0000 Subject: [PATCH 08/10] perf session: Split out sample preprocessing Simplify the code a bit. Cc: Frederic Weisbecker Cc: Ian Munsie Cc: Ingo Molnar Cc: Peter Zijlstra LKML-Reference: <20101207124551.014649793@linutronix.de> Signed-off-by: Thomas Gleixner Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 40 ++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 7c5cc129207ab..a765b274390eb 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -732,6 +732,22 @@ static int perf_session_deliver_event(struct perf_session *session, } } +static int perf_session__preprocess_sample(struct perf_session *session, + event_t *event, struct sample_data *sample) +{ + if (event->header.type != PERF_RECORD_SAMPLE || + !(session->sample_type & PERF_SAMPLE_CALLCHAIN)) + return 0; + + if (!ip_callchain__valid(sample->callchain, event)) { + pr_debug("call-chain problem with event, skipping it.\n"); + ++session->hists.stats.nr_invalid_chains; + session->hists.stats.total_invalid_chains += sample->period; + return -EINVAL; + } + return 0; +} + static int perf_session__process_event(struct perf_session *session, event_t *event, struct perf_event_ops *ops, @@ -750,24 +766,9 @@ static int perf_session__process_event(struct perf_session *session, if (event->header.type >= PERF_RECORD_USER_TYPE_START) dump_event(session, event, file_offset, NULL); - else - event__parse_sample(event, session, &sample); /* These events are processed right away */ switch (event->header.type) { - case PERF_RECORD_SAMPLE: - if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { - if (!ip_callchain__valid(sample.callchain, event)) { - pr_debug("call-chain problem with event, " - "skipping it.\n"); - ++session->hists.stats.nr_invalid_chains; - session->hists.stats.total_invalid_chains += - sample.period; - return 0; - } - } - break; - case PERF_RECORD_HEADER_ATTR: return ops->attr(event, session); case PERF_RECORD_HEADER_EVENT_TYPE: @@ -784,6 +785,15 @@ static int perf_session__process_event(struct perf_session *session, break; } + /* + * For all kernel events we get the sample data + */ + event__parse_sample(event, session, &sample); + + /* Preprocess sample records - precheck callchains */ + if (perf_session__preprocess_sample(session, event, &sample)) + return 0; + if (ops->ordered_samples) { ret = perf_session_queue_event(session, event, &sample, file_offset); From ba74f0640d963ccc914ac533cb0ba133ee07bcf2 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 7 Dec 2010 12:49:01 +0000 Subject: [PATCH 09/10] perf session: Split out user event processing Simplify further. Cc: Frederic Weisbecker Cc: Ian Munsie Cc: Ingo Molnar Cc: Peter Zijlstra LKML-Reference: <20101207124551.110956235@linutronix.de> Signed-off-by: Thomas Gleixner Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 42 ++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index a765b274390eb..69760cd4cc44c 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -748,24 +748,10 @@ static int perf_session__preprocess_sample(struct perf_session *session, return 0; } -static int perf_session__process_event(struct perf_session *session, - event_t *event, - struct perf_event_ops *ops, - u64 file_offset) +static int perf_session__process_user_event(struct perf_session *session, event_t *event, + struct perf_event_ops *ops, u64 file_offset) { - struct sample_data sample; - int ret; - - if (session->header.needs_swap && event__swap_ops[event->header.type]) - event__swap_ops[event->header.type](event); - - if (event->header.type >= PERF_RECORD_HEADER_MAX) - return -EINVAL; - - hists__inc_nr_events(&session->hists, event->header.type); - - if (event->header.type >= PERF_RECORD_USER_TYPE_START) - dump_event(session, event, file_offset, NULL); + dump_event(session, event, file_offset, NULL); /* These events are processed right away */ switch (event->header.type) { @@ -782,8 +768,28 @@ static int perf_session__process_event(struct perf_session *session, case PERF_RECORD_FINISHED_ROUND: return ops->finished_round(event, session, ops); default: - break; + return -EINVAL; } +} + +static int perf_session__process_event(struct perf_session *session, + event_t *event, + struct perf_event_ops *ops, + u64 file_offset) +{ + struct sample_data sample; + int ret; + + if (session->header.needs_swap && event__swap_ops[event->header.type]) + event__swap_ops[event->header.type](event); + + if (event->header.type >= PERF_RECORD_HEADER_MAX) + return -EINVAL; + + hists__inc_nr_events(&session->hists, event->header.type); + + if (event->header.type >= PERF_RECORD_USER_TYPE_START) + return perf_session__process_user_event(session, event, ops, file_offset); /* * For all kernel events we get the sample data From ddbc24b72c2c3f3f0182bbc2cb70b31c52a6f45b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 9 Dec 2010 12:20:20 -0200 Subject: [PATCH 10/10] perf session: Remove unneeded dump_printf calls Since we check at the beginning of the callers, no need to ask if dump_trace is set multiple times. Cc: Frederic Weisbecker Cc: Ian Munsie Cc: Ingo Molnar Cc: Thomas Gleixner LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 69760cd4cc44c..b59abf5aba36e 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -639,13 +639,10 @@ static int perf_session_queue_event(struct perf_session *s, event_t *event, return 0; } -static void callchain__dump(struct sample_data *sample) +static void callchain__printf(struct sample_data *sample) { unsigned int i; - if (!dump_trace) - return; - printf("... chain: nr:%Lu\n", sample->callchain->nr); for (i = 0; i < sample->callchain->nr; i++) @@ -675,27 +672,29 @@ static void dump_event(struct perf_session *session, event_t *event, if (!dump_trace) return; - dump_printf("\n%#Lx [%#x]: event: %d\n", file_offset, - event->header.size, event->header.type); + printf("\n%#Lx [%#x]: event: %d\n", file_offset, event->header.size, + event->header.type); trace_event(event); if (sample) perf_session__print_tstamp(session, event, sample); - dump_printf("%#Lx [%#x]: PERF_RECORD_%s", - file_offset, event->header.size, - event__get_event_name(event->header.type)); + printf("%#Lx [%#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, struct sample_data *sample) { - dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, - sample->pid, sample->tid, sample->ip, sample->period); + if (!dump_trace) + return; + + printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, + sample->pid, sample->tid, sample->ip, sample->period); if (session->sample_type & PERF_SAMPLE_CALLCHAIN) - callchain__dump(sample); + callchain__printf(sample); } static int perf_session_deliver_event(struct perf_session *session,