* [PATCH 1/2] perf annotate: Fix perf data parsing
@ 2009-12-01 6:04 Li Zefan
2009-12-01 6:05 ` [PATCH 2/2] perf timechart: Remove open-coded event parsing code Li Zefan
2009-12-01 7:30 ` [tip:perf/core] perf annotate: Fix perf data parsing tip-bot for Li Zefan
0 siblings, 2 replies; 6+ messages in thread
From: Li Zefan @ 2009-12-01 6:04 UTC (permalink / raw)
To: Ingo Molnar
Cc: Frédéric Weisbecker, Arnaldo Carvalho de Melo,
Peter Zijlstra, Arjan van de Ven, LKML
perf-annotate doesn't parse perf.data correctly in that it doesn't
read perf header. Fix this by using mmap_dispatch_perf_file().
Before:
TOTAL events: 17565
MMAP events: 3221
LOST events: 10
COMM events: 235
EXIT events: 2
THROTTLE events: 1
UNTHROTTLE events: 2
FORK events: 10
READ events: 1
SAMPLE events: 14083
After:
TOTAL events: 17290
MMAP events: 3203
LOST events: 0
COMM events: 234
EXIT events: 1
THROTTLE events: 0
UNTHROTTLE events: 0
FORK events: 0
READ events: 0
SAMPLE events: 13852
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
---
tools/perf/builtin-annotate.c | 143 +++++-----------------------------------
tools/perf/util/event.c | 3 +-
2 files changed, 19 insertions(+), 127 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 7d39bd2..37b163f 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -25,19 +25,16 @@
#include "util/thread.h"
#include "util/sort.h"
#include "util/hist.h"
+#include "util/data_map.h"
static char const *input_name = "perf.data";
static int force;
-static int input;
static int full_paths;
static int print_line;
-static unsigned long page_size;
-static unsigned long mmap_window = 32;
-
struct sym_hist {
u64 sum;
u64 ip[0];
@@ -197,35 +194,6 @@ static int process_sample_event(event_t *event)
return 0;
}
-static int event__process(event_t *self)
-{
- switch (self->header.type) {
- case PERF_RECORD_SAMPLE:
- return process_sample_event(self);
-
- case PERF_RECORD_MMAP:
- return event__process_mmap(self);
-
- case PERF_RECORD_COMM:
- return event__process_comm(self);
-
- case PERF_RECORD_FORK:
- return event__process_task(self);
- /*
- * We dont process them right now but they are fine:
- */
-
- case PERF_RECORD_THROTTLE:
- case PERF_RECORD_UNTHROTTLE:
- return 0;
-
- default:
- return -1;
- }
-
- return 0;
-}
-
static int parse_line(FILE *file, struct hist_entry *he, u64 len)
{
struct symbol *sym = he->sym;
@@ -526,99 +494,26 @@ static void find_annotations(void)
}
}
+static struct perf_file_handler file_handler = {
+ .process_sample_event = process_sample_event,
+ .process_mmap_event = event__process_mmap,
+ .process_comm_event = event__process_comm,
+ .process_fork_event = event__process_task,
+};
+
static int __cmd_annotate(void)
{
- int ret, rc = EXIT_FAILURE;
- unsigned long offset = 0;
- unsigned long head = 0;
- struct stat input_stat;
- event_t *event;
- uint32_t size;
- char *buf;
-
- register_idle_thread();
-
- input = open(input_name, O_RDONLY);
- if (input < 0) {
- perror("failed to open file");
- exit(-1);
- }
-
- ret = fstat(input, &input_stat);
- if (ret < 0) {
- perror("failed to stat file");
- exit(-1);
- }
-
- if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
- fprintf(stderr, "file: %s not owned by current user or root\n", input_name);
- exit(-1);
- }
-
- if (!input_stat.st_size) {
- fprintf(stderr, "zero-sized file, nothing to do!\n");
- exit(0);
- }
-
-remap:
- buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
- MAP_SHARED, input, offset);
- if (buf == MAP_FAILED) {
- perror("failed to mmap file");
- exit(-1);
- }
-
-more:
- event = (event_t *)(buf + head);
-
- size = event->header.size;
- if (!size)
- size = 8;
-
- if (head + event->header.size >= page_size * mmap_window) {
- unsigned long shift = page_size * (head / page_size);
- int munmap_ret;
-
- munmap_ret = munmap(buf, page_size * mmap_window);
- assert(munmap_ret == 0);
-
- offset += shift;
- head -= shift;
- goto remap;
- }
-
- size = event->header.size;
-
- dump_printf("%p [%p]: event: %d\n",
- (void *)(offset + head),
- (void *)(long)event->header.size,
- event->header.type);
-
- if (!size || event__process(event) < 0) {
-
- dump_printf("%p [%p]: skipping unknown header type: %d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->header.type);
- /*
- * assume we lost track of the stream, check alignment, and
- * increment a single u64 in the hope to catch on again 'soon'.
- */
-
- if (unlikely(head & 7))
- head &= ~7ULL;
-
- size = 8;
- }
-
- head += size;
-
- if (offset + head < (unsigned long)input_stat.st_size)
- goto more;
+ struct perf_header *header;
+ struct thread *idle;
+ int ret;
- rc = EXIT_SUCCESS;
- close(input);
+ idle = register_idle_thread();
+ register_perf_file_handler(&file_handler);
+ ret = mmap_dispatch_perf_file(&header, input_name, 0, 0,
+ &event__cwdlen, &event__cwd);
+ if (ret)
+ return ret;
if (dump_trace) {
event__print_totals();
@@ -636,7 +531,7 @@ more:
find_annotations();
- return rc;
+ return ret;
}
static const char * const annotate_usage[] = {
@@ -685,8 +580,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
if (symbol__init(&symbol_conf) < 0)
return -1;
- page_size = getpagesize();
-
argc = parse_options(argc, argv, options, annotate_usage, 0);
setup_sorting();
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 70b4aa0..b5b333e 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -186,8 +186,7 @@ int event__process_comm(event_t *self)
{
struct thread *thread = threads__findnew(self->comm.pid);
- dump_printf("PERF_RECORD_COMM: %s:%d\n",
- self->comm.comm, self->comm.pid);
+ dump_printf(": %s:%d\n", self->comm.comm, self->comm.pid);
if (thread == NULL || thread__set_comm(thread, self->comm.comm)) {
dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
--
1.6.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/2] perf timechart: Remove open-coded event parsing code
2009-12-01 6:04 [PATCH 1/2] perf annotate: Fix perf data parsing Li Zefan
@ 2009-12-01 6:05 ` Li Zefan
2009-12-01 6:24 ` Arjan van de Ven
2009-12-01 7:31 ` [tip:perf/core] " tip-bot for Li Zefan
2009-12-01 7:30 ` [tip:perf/core] perf annotate: Fix perf data parsing tip-bot for Li Zefan
1 sibling, 2 replies; 6+ messages in thread
From: Li Zefan @ 2009-12-01 6:05 UTC (permalink / raw)
To: Ingo Molnar
Cc: Frédéric Weisbecker, Arnaldo Carvalho de Melo,
Peter Zijlstra, Arjan van de Ven, LKML
Convert builtin-timechart.c to mmap_dispatch_perf_file() +
perf_file_handler.
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
---
tools/perf/builtin-timechart.c | 165 +++++++---------------------------------
1 files changed, 28 insertions(+), 137 deletions(-)
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index dd4d82a..ce677bf 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -29,14 +29,14 @@
#include "util/header.h"
#include "util/parse-options.h"
#include "util/parse-events.h"
+#include "util/event.h"
+#include "util/data_map.h"
#include "util/svghelper.h"
static char const *input_name = "perf.data";
static char const *output_name = "output.svg";
-static unsigned long page_size;
-static unsigned long mmap_window = 32;
static u64 sample_type;
static unsigned int numcpus;
@@ -49,8 +49,6 @@ static u64 first_time, last_time;
static int power_only;
-static struct perf_header *header;
-
struct per_pid;
struct per_pidcomm;
@@ -1045,36 +1043,6 @@ static void write_svg_file(const char *filename)
svg_close();
}
-static int
-process_event(event_t *event)
-{
-
- switch (event->header.type) {
-
- case PERF_RECORD_COMM:
- return process_comm_event(event);
- case PERF_RECORD_FORK:
- return process_fork_event(event);
- case PERF_RECORD_EXIT:
- return process_exit_event(event);
- case PERF_RECORD_SAMPLE:
- return queue_sample_event(event);
-
- /*
- * We dont process them right now but they are fine:
- */
- case PERF_RECORD_MMAP:
- case PERF_RECORD_THROTTLE:
- case PERF_RECORD_UNTHROTTLE:
- return 0;
-
- default:
- return -1;
- }
-
- return 0;
-}
-
static void process_samples(void)
{
struct sample_wrapper *cursor;
@@ -1090,114 +1058,39 @@ static void process_samples(void)
}
}
-
-static int __cmd_timechart(void)
+static int sample_type_check(u64 type)
{
- int err, rc = EXIT_FAILURE;
- unsigned long offset = 0;
- unsigned long head, shift;
- struct stat statbuf;
- event_t *event;
- uint32_t size;
- char *buf;
- int input;
-
- input = open(input_name, O_RDONLY);
- if (input < 0) {
- fprintf(stderr, " failed to open file: %s", input_name);
- if (!strcmp(input_name, "perf.data"))
- fprintf(stderr, " (try 'perf record' first)");
- fprintf(stderr, "\n");
- exit(-1);
- }
-
- err = fstat(input, &statbuf);
- if (err < 0) {
- perror("failed to stat file");
- exit(-1);
- }
-
- if (!statbuf.st_size) {
- fprintf(stderr, "zero-sized file, nothing to do!\n");
- exit(0);
- }
-
- header = perf_header__new();
- if (header == NULL)
- return -ENOMEM;
+ sample_type = type;
- err = perf_header__read(header, input);
- if (err < 0) {
- perf_header__delete(header);
- return err;
- }
-
- head = header->data_offset;
-
- sample_type = perf_header__sample_type(header);
-
- shift = page_size * (head / page_size);
- offset += shift;
- head -= shift;
-
-remap:
- buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
- MAP_SHARED, input, offset);
- if (buf == MAP_FAILED) {
- perror("failed to mmap file");
- exit(-1);
- }
-
-more:
- event = (event_t *)(buf + head);
-
- size = event->header.size;
- if (!size)
- size = 8;
-
- if (head + event->header.size >= page_size * mmap_window) {
- int ret2;
-
- shift = page_size * (head / page_size);
-
- ret2 = munmap(buf, page_size * mmap_window);
- assert(ret2 == 0);
-
- offset += shift;
- head -= shift;
- goto remap;
- }
-
- size = event->header.size;
-
- if (!size || process_event(event) < 0) {
- pr_warning("%p [%p]: skipping unknown header type: %d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->header.type);
- /*
- * assume we lost track of the stream, check alignment, and
- * increment a single u64 in the hope to catch on again 'soon'.
- */
-
- if (unlikely(head & 7))
- head &= ~7ULL;
-
- size = 8;
+ if (!(sample_type & PERF_SAMPLE_RAW)) {
+ fprintf(stderr,
+ "No trace sample to read. Did you call perf record "
+ "without -R?");
+ return -1;
}
- head += size;
+ return 0;
+}
- if (offset + head >= header->data_offset + header->data_size)
- goto done;
+static struct perf_file_handler file_handler = {
+ .process_comm_event = process_comm_event,
+ .process_fork_event = process_fork_event,
+ .process_exit_event = process_exit_event,
+ .process_sample_event = queue_sample_event,
+ .sample_type_check = sample_type_check,
+};
- if (offset + head < (unsigned long)statbuf.st_size)
- goto more;
+static int __cmd_timechart(void)
+{
+ struct perf_header *header;
+ int ret;
-done:
- rc = EXIT_SUCCESS;
- close(input);
+ register_perf_file_handler(&file_handler);
+ ret = mmap_dispatch_perf_file(&header, input_name, 0, 0,
+ &event__cwdlen, &event__cwd);
+ if (ret)
+ return EXIT_FAILURE;
process_samples();
@@ -1210,7 +1103,7 @@ done:
pr_info("Written %2.1f seconds of trace to %s.\n",
(last_time - first_time) / 1000000000.0, output_name);
- return rc;
+ return EXIT_SUCCESS;
}
static const char * const timechart_usage[] = {
@@ -1277,8 +1170,6 @@ int cmd_timechart(int argc, const char **argv, const char *prefix __used)
{
symbol__init(0);
- page_size = getpagesize();
-
argc = parse_options(argc, argv, options, timechart_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
--
1.6.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 2/2] perf timechart: Remove open-coded event parsing code
2009-12-01 6:05 ` [PATCH 2/2] perf timechart: Remove open-coded event parsing code Li Zefan
@ 2009-12-01 6:24 ` Arjan van de Ven
2009-12-01 6:31 ` Li Zefan
2009-12-01 7:31 ` [tip:perf/core] " tip-bot for Li Zefan
1 sibling, 1 reply; 6+ messages in thread
From: Arjan van de Ven @ 2009-12-01 6:24 UTC (permalink / raw)
To: Li Zefan
Cc: Ingo Molnar, Frédéric Weisbecker,
Arnaldo Carvalho de Melo, Peter Zijlstra, LKML
On Tue, 01 Dec 2009 14:05:16 +0800
Li Zefan <lizf@cn.fujitsu.com> wrote:
> - size = 8;
> + if (!(sample_type & PERF_SAMPLE_RAW)) {
> + fprintf(stderr,
> + "No trace sample to read. Did you call perf
> record "
> + "without -R?");
> + return -1;
> }
while I like your cleanup... I am not so sure this printk makes sense
whatsoever.... the user did not use "perf record" to get here...
--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH 2/2] perf timechart: Remove open-coded event parsing code
2009-12-01 6:24 ` Arjan van de Ven
@ 2009-12-01 6:31 ` Li Zefan
0 siblings, 0 replies; 6+ messages in thread
From: Li Zefan @ 2009-12-01 6:31 UTC (permalink / raw)
To: Arjan van de Ven
Cc: Ingo Molnar, Frédéric Weisbecker,
Arnaldo Carvalho de Melo, Peter Zijlstra, LKML
Arjan van de Ven wrote:
> On Tue, 01 Dec 2009 14:05:16 +0800
> Li Zefan <lizf@cn.fujitsu.com> wrote:
>> - size = 8;
>> + if (!(sample_type & PERF_SAMPLE_RAW)) {
>> + fprintf(stderr,
>> + "No trace sample to read. Did you call perf
>> record "
>> + "without -R?");
>> + return -1;
>> }
>
> while I like your cleanup... I am not so sure this printk makes sense
> whatsoever.... the user did not use "perf record" to get here...
>
I followed builtin-trace.c and builtin-sched.c.
Well, if you run perf-record without -R, like:
# ./perf record -a -R -f -e power:* -e sched:sched_wakeup -e sched:sched_switch
And then run perf-timechart, you'll run into that warning.
But sure, if we always run "perf timechart rec" before "perf timechart",
we never get there.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [tip:perf/core] perf timechart: Remove open-coded event parsing code
2009-12-01 6:05 ` [PATCH 2/2] perf timechart: Remove open-coded event parsing code Li Zefan
2009-12-01 6:24 ` Arjan van de Ven
@ 2009-12-01 7:31 ` tip-bot for Li Zefan
1 sibling, 0 replies; 6+ messages in thread
From: tip-bot for Li Zefan @ 2009-12-01 7:31 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, lizf, peterz, arjan, fweisbec, acme,
tglx, mingo
Commit-ID: 5cbd08056142dcb2aea0dca7261afcb810a63c55
Gitweb: http://git.kernel.org/tip/5cbd08056142dcb2aea0dca7261afcb810a63c55
Author: Li Zefan <lizf@cn.fujitsu.com>
AuthorDate: Tue, 1 Dec 2009 14:05:16 +0800
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Tue, 1 Dec 2009 08:14:09 +0100
perf timechart: Remove open-coded event parsing code
Convert builtin-timechart.c to mmap_dispatch_perf_file() +
perf_file_handler.
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Acked-by: Arjan van de Ven <arjan@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Peter Zijlstra <peterz@infradead.org>
LKML-Reference: <4B14B21C.2040406@cn.fujitsu.com>
[ v2: cleaned up the printout, fixed a whitespace detail ]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
tools/perf/builtin-timechart.c | 170 +++++++---------------------------------
1 files changed, 30 insertions(+), 140 deletions(-)
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index dd4d82a..cb58b66 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -29,14 +29,14 @@
#include "util/header.h"
#include "util/parse-options.h"
#include "util/parse-events.h"
+#include "util/event.h"
+#include "util/data_map.h"
#include "util/svghelper.h"
static char const *input_name = "perf.data";
static char const *output_name = "output.svg";
-static unsigned long page_size;
-static unsigned long mmap_window = 32;
static u64 sample_type;
static unsigned int numcpus;
@@ -49,8 +49,6 @@ static u64 first_time, last_time;
static int power_only;
-static struct perf_header *header;
-
struct per_pid;
struct per_pidcomm;
@@ -156,9 +154,9 @@ struct sample_wrapper *all_samples;
struct process_filter;
struct process_filter {
- char *name;
- int pid;
- struct process_filter *next;
+ char *name;
+ int pid;
+ struct process_filter *next;
};
static struct process_filter *process_filter;
@@ -1045,36 +1043,6 @@ static void write_svg_file(const char *filename)
svg_close();
}
-static int
-process_event(event_t *event)
-{
-
- switch (event->header.type) {
-
- case PERF_RECORD_COMM:
- return process_comm_event(event);
- case PERF_RECORD_FORK:
- return process_fork_event(event);
- case PERF_RECORD_EXIT:
- return process_exit_event(event);
- case PERF_RECORD_SAMPLE:
- return queue_sample_event(event);
-
- /*
- * We dont process them right now but they are fine:
- */
- case PERF_RECORD_MMAP:
- case PERF_RECORD_THROTTLE:
- case PERF_RECORD_UNTHROTTLE:
- return 0;
-
- default:
- return -1;
- }
-
- return 0;
-}
-
static void process_samples(void)
{
struct sample_wrapper *cursor;
@@ -1090,114 +1058,38 @@ static void process_samples(void)
}
}
-
-static int __cmd_timechart(void)
+static int sample_type_check(u64 type)
{
- int err, rc = EXIT_FAILURE;
- unsigned long offset = 0;
- unsigned long head, shift;
- struct stat statbuf;
- event_t *event;
- uint32_t size;
- char *buf;
- int input;
-
- input = open(input_name, O_RDONLY);
- if (input < 0) {
- fprintf(stderr, " failed to open file: %s", input_name);
- if (!strcmp(input_name, "perf.data"))
- fprintf(stderr, " (try 'perf record' first)");
- fprintf(stderr, "\n");
- exit(-1);
- }
-
- err = fstat(input, &statbuf);
- if (err < 0) {
- perror("failed to stat file");
- exit(-1);
- }
-
- if (!statbuf.st_size) {
- fprintf(stderr, "zero-sized file, nothing to do!\n");
- exit(0);
- }
+ sample_type = type;
- header = perf_header__new();
- if (header == NULL)
- return -ENOMEM;
-
- err = perf_header__read(header, input);
- if (err < 0) {
- perf_header__delete(header);
- return err;
- }
-
- head = header->data_offset;
-
- sample_type = perf_header__sample_type(header);
-
- shift = page_size * (head / page_size);
- offset += shift;
- head -= shift;
-
-remap:
- buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
- MAP_SHARED, input, offset);
- if (buf == MAP_FAILED) {
- perror("failed to mmap file");
- exit(-1);
- }
-
-more:
- event = (event_t *)(buf + head);
-
- size = event->header.size;
- if (!size)
- size = 8;
-
- if (head + event->header.size >= page_size * mmap_window) {
- int ret2;
-
- shift = page_size * (head / page_size);
-
- ret2 = munmap(buf, page_size * mmap_window);
- assert(ret2 == 0);
-
- offset += shift;
- head -= shift;
- goto remap;
- }
-
- size = event->header.size;
-
- if (!size || process_event(event) < 0) {
- pr_warning("%p [%p]: skipping unknown header type: %d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->header.type);
- /*
- * assume we lost track of the stream, check alignment, and
- * increment a single u64 in the hope to catch on again 'soon'.
- */
-
- if (unlikely(head & 7))
- head &= ~7ULL;
-
- size = 8;
+ if (!(sample_type & PERF_SAMPLE_RAW)) {
+ fprintf(stderr, "No trace samples found in the file.\n"
+ "Have you used 'perf timechart record' to record it?\n");
+ return -1;
}
- head += size;
+ return 0;
+}
- if (offset + head >= header->data_offset + header->data_size)
- goto done;
+static struct perf_file_handler file_handler = {
+ .process_comm_event = process_comm_event,
+ .process_fork_event = process_fork_event,
+ .process_exit_event = process_exit_event,
+ .process_sample_event = queue_sample_event,
+ .sample_type_check = sample_type_check,
+};
- if (offset + head < (unsigned long)statbuf.st_size)
- goto more;
+static int __cmd_timechart(void)
+{
+ struct perf_header *header;
+ int ret;
-done:
- rc = EXIT_SUCCESS;
- close(input);
+ register_perf_file_handler(&file_handler);
+ ret = mmap_dispatch_perf_file(&header, input_name, 0, 0,
+ &event__cwdlen, &event__cwd);
+ if (ret)
+ return EXIT_FAILURE;
process_samples();
@@ -1210,7 +1102,7 @@ done:
pr_info("Written %2.1f seconds of trace to %s.\n",
(last_time - first_time) / 1000000000.0, output_name);
- return rc;
+ return EXIT_SUCCESS;
}
static const char * const timechart_usage[] = {
@@ -1277,8 +1169,6 @@ int cmd_timechart(int argc, const char **argv, const char *prefix __used)
{
symbol__init(0);
- page_size = getpagesize();
-
argc = parse_options(argc, argv, options, timechart_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [tip:perf/core] perf annotate: Fix perf data parsing
2009-12-01 6:04 [PATCH 1/2] perf annotate: Fix perf data parsing Li Zefan
2009-12-01 6:05 ` [PATCH 2/2] perf timechart: Remove open-coded event parsing code Li Zefan
@ 2009-12-01 7:30 ` tip-bot for Li Zefan
1 sibling, 0 replies; 6+ messages in thread
From: tip-bot for Li Zefan @ 2009-12-01 7:30 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, lizf, peterz, arjan, fweisbec, acme,
tglx, mingo
Commit-ID: bab81b624e970f1138535a465ad2b26b6bb0dd6c
Gitweb: http://git.kernel.org/tip/bab81b624e970f1138535a465ad2b26b6bb0dd6c
Author: Li Zefan <lizf@cn.fujitsu.com>
AuthorDate: Tue, 1 Dec 2009 14:04:49 +0800
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Tue, 1 Dec 2009 08:14:08 +0100
perf annotate: Fix perf data parsing
perf-annotate doesn't parse perf.data correctly in that it
doesn't read perf header. Fix this by using
mmap_dispatch_perf_file().
Before:
TOTAL events: 17565
MMAP events: 3221
LOST events: 10
COMM events: 235
EXIT events: 2
THROTTLE events: 1
UNTHROTTLE events: 2
FORK events: 10
READ events: 1
SAMPLE events: 14083
After:
TOTAL events: 17290
MMAP events: 3203
LOST events: 0
COMM events: 234
EXIT events: 1
THROTTLE events: 0
UNTHROTTLE events: 0
FORK events: 0
READ events: 0
SAMPLE events: 13852
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arjan van de Ven <arjan@infradead.org>
LKML-Reference: <4B14B201.9030708@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
tools/perf/builtin-annotate.c | 143 +++++-----------------------------------
tools/perf/util/event.c | 3 +-
2 files changed, 19 insertions(+), 127 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 7f85c6e..0bf2e8f 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -25,19 +25,16 @@
#include "util/thread.h"
#include "util/sort.h"
#include "util/hist.h"
+#include "util/data_map.h"
static char const *input_name = "perf.data";
static int force;
-static int input;
static int full_paths;
static int print_line;
-static unsigned long page_size;
-static unsigned long mmap_window = 32;
-
struct sym_hist {
u64 sum;
u64 ip[0];
@@ -156,35 +153,6 @@ static int process_sample_event(event_t *event)
return 0;
}
-static int event__process(event_t *self)
-{
- switch (self->header.type) {
- case PERF_RECORD_SAMPLE:
- return process_sample_event(self);
-
- case PERF_RECORD_MMAP:
- return event__process_mmap(self);
-
- case PERF_RECORD_COMM:
- return event__process_comm(self);
-
- case PERF_RECORD_FORK:
- return event__process_task(self);
- /*
- * We dont process them right now but they are fine:
- */
-
- case PERF_RECORD_THROTTLE:
- case PERF_RECORD_UNTHROTTLE:
- return 0;
-
- default:
- return -1;
- }
-
- return 0;
-}
-
static int parse_line(FILE *file, struct hist_entry *he, u64 len)
{
struct symbol *sym = he->sym;
@@ -485,99 +453,26 @@ static void find_annotations(void)
}
}
+static struct perf_file_handler file_handler = {
+ .process_sample_event = process_sample_event,
+ .process_mmap_event = event__process_mmap,
+ .process_comm_event = event__process_comm,
+ .process_fork_event = event__process_task,
+};
+
static int __cmd_annotate(void)
{
- int ret, rc = EXIT_FAILURE;
- unsigned long offset = 0;
- unsigned long head = 0;
- struct stat input_stat;
- event_t *event;
- uint32_t size;
- char *buf;
-
- register_idle_thread();
-
- input = open(input_name, O_RDONLY);
- if (input < 0) {
- perror("failed to open file");
- exit(-1);
- }
-
- ret = fstat(input, &input_stat);
- if (ret < 0) {
- perror("failed to stat file");
- exit(-1);
- }
-
- if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
- fprintf(stderr, "file: %s not owned by current user or root\n", input_name);
- exit(-1);
- }
-
- if (!input_stat.st_size) {
- fprintf(stderr, "zero-sized file, nothing to do!\n");
- exit(0);
- }
-
-remap:
- buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
- MAP_SHARED, input, offset);
- if (buf == MAP_FAILED) {
- perror("failed to mmap file");
- exit(-1);
- }
-
-more:
- event = (event_t *)(buf + head);
-
- size = event->header.size;
- if (!size)
- size = 8;
-
- if (head + event->header.size >= page_size * mmap_window) {
- unsigned long shift = page_size * (head / page_size);
- int munmap_ret;
-
- munmap_ret = munmap(buf, page_size * mmap_window);
- assert(munmap_ret == 0);
-
- offset += shift;
- head -= shift;
- goto remap;
- }
-
- size = event->header.size;
-
- dump_printf("%p [%p]: event: %d\n",
- (void *)(offset + head),
- (void *)(long)event->header.size,
- event->header.type);
-
- if (!size || event__process(event) < 0) {
-
- dump_printf("%p [%p]: skipping unknown header type: %d\n",
- (void *)(offset + head),
- (void *)(long)(event->header.size),
- event->header.type);
- /*
- * assume we lost track of the stream, check alignment, and
- * increment a single u64 in the hope to catch on again 'soon'.
- */
-
- if (unlikely(head & 7))
- head &= ~7ULL;
-
- size = 8;
- }
-
- head += size;
-
- if (offset + head < (unsigned long)input_stat.st_size)
- goto more;
+ struct perf_header *header;
+ struct thread *idle;
+ int ret;
- rc = EXIT_SUCCESS;
- close(input);
+ idle = register_idle_thread();
+ register_perf_file_handler(&file_handler);
+ ret = mmap_dispatch_perf_file(&header, input_name, 0, 0,
+ &event__cwdlen, &event__cwd);
+ if (ret)
+ return ret;
if (dump_trace) {
event__print_totals();
@@ -595,7 +490,7 @@ more:
find_annotations();
- return rc;
+ return ret;
}
static const char * const annotate_usage[] = {
@@ -644,8 +539,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
if (symbol__init(&symbol_conf) < 0)
return -1;
- page_size = getpagesize();
-
argc = parse_options(argc, argv, options, annotate_usage, 0);
setup_sorting();
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 233d7ad..414b89d 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -186,8 +186,7 @@ int event__process_comm(event_t *self)
{
struct thread *thread = threads__findnew(self->comm.pid);
- dump_printf("PERF_RECORD_COMM: %s:%d\n",
- self->comm.comm, self->comm.pid);
+ dump_printf(": %s:%d\n", self->comm.comm, self->comm.pid);
if (thread == NULL || thread__set_comm(thread, self->comm.comm)) {
dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-12-01 7:31 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-01 6:04 [PATCH 1/2] perf annotate: Fix perf data parsing Li Zefan
2009-12-01 6:05 ` [PATCH 2/2] perf timechart: Remove open-coded event parsing code Li Zefan
2009-12-01 6:24 ` Arjan van de Ven
2009-12-01 6:31 ` Li Zefan
2009-12-01 7:31 ` [tip:perf/core] " tip-bot for Li Zefan
2009-12-01 7:30 ` [tip:perf/core] perf annotate: Fix perf data parsing tip-bot for Li Zefan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.