2010-12-09 18:13:17

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [GIT PULL 00/10] perf/core improvements

Hi Ingo,

Please pull from:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 perf/core

Regards,

- Arnaldo

Arnaldo Carvalho de Melo (1):
perf session: Remove unneeded dump_printf calls

David Ahern (1):
perf report: Allow user to specify path to kallsyms file

Thomas Gleixner (8):
perf event: Prevent unbound event__name array access
perf session: Dont queue events w/o timestamps
perf session: Consolidate the dump code
perf session: Store file offset in sample_queue
perf session: Add file_offset to event delivery function
perf session: Move dump code to event delivery path
perf session: Split out sample preprocessing
perf session: Split out user event processing

tools/perf/Documentation/perf-report.txt | 3 +
tools/perf/builtin-report.c | 2 +
tools/perf/util/event.c | 12 ++-
tools/perf/util/event.h | 3 +-
tools/perf/util/hist.c | 9 +-
tools/perf/util/session.c | 154 ++++++++++++++++++-----------
tools/perf/util/symbol.c | 9 ++-
tools/perf/util/symbol.h | 1 +
8 files changed, 127 insertions(+), 66 deletions(-)


2010-12-09 18:13:07

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 01/10] perf report: Allow user to specify path to kallsyms file

From: David Ahern <[email protected]>

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: <[email protected]>
Signed-off-by: David Ahern <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
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 59a1f57..fefea77 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -104,6 +104,9 @@ OPTIONS
--vmlinux=<file>::
vmlinux pathname

+--kallsyms=<file>::
+ 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 904519f..b6a2a89 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 a348906..f40c076 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 038f220..12defbe 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,
--
1.6.2.5

2010-12-09 18:13:13

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 08/10] perf session: Split out sample preprocessing

From: Thomas Gleixner <[email protected]>

Simplify the code a bit.

Cc: Frederic Weisbecker <[email protected]>
Cc: Ian Munsie <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Peter Zijlstra <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/session.c | 40 +++++++++++++++++++++++++---------------
1 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 7c5cc12..a765b27 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);
--
1.6.2.5

2010-12-09 18:13:28

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 06/10] perf session: Add file_offset to event delivery function

From: Thomas Gleixner <[email protected]>

Preparatory patch for ordered output of perf report -D

Acked-by: Ian Munsie <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ian Munsie <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Peter Zijlstra <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/session.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index a433954..d43e56c 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)
--
1.6.2.5

2010-12-09 18:13:34

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 07/10] perf session: Move dump code to event delivery path

From: Thomas Gleixner <[email protected]>

Preparatory patch for ordered perf report -D

Acked-by: Ian Munsie <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ian Munsie <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Peter Zijlstra <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/session.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index d43e56c..7c5cc12 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:
--
1.6.2.5

2010-12-09 18:14:09

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 02/10] perf event: Prevent unbound event__name array access

From: Thomas Gleixner <[email protected]>

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 <[email protected]>
Cc: Ian Munsie <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Peter Zijlstra <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
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 e4cdc1e..183aedd 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 a95ab18..4716a8f 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 2022e87..a3b8416 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 3074d38..b3b145a 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);
}

--
1.6.2.5

2010-12-09 18:14:07

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 03/10] perf session: Dont queue events w/o timestamps

From: Thomas Gleixner <[email protected]>

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 <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ian Munsie <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Peter Zijlstra <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/session.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index b3b145a..e5d0ed9 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) {
--
1.6.2.5

2010-12-09 18:14:03

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 05/10] perf session: Store file offset in sample_queue

From: Thomas Gleixner <[email protected]>

Preparatory patch for ordered output of perf report -D.

Acked-by: Ian Munsie <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ian Munsie <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Peter Zijlstra <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/session.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 12761d5..a433954 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;
}
--
1.6.2.5

2010-12-09 18:14:05

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 09/10] perf session: Split out user event processing

From: Thomas Gleixner <[email protected]>

Simplify further.

Cc: Frederic Weisbecker <[email protected]>
Cc: Ian Munsie <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Peter Zijlstra <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/session.c | 42 ++++++++++++++++++++++++------------------
1 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index a765b27..69760cd 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
--
1.6.2.5

2010-12-09 18:14:50

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 04/10] perf session: Consolidate the dump code

From: Thomas Gleixner <[email protected]>

The dump code used by perf report -D is scattered all over the place.
Move it to separate functions.

Acked-by: Ian Munsie <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ian Munsie <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Peter Zijlstra <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
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 4716a8f..2b7e919 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 e5d0ed9..12761d5 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 @@ more:

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 @@ more:

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",
--
1.6.2.5