From 028c515253761084c6594bf9ac9b194b51d87065 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Sun, 6 Dec 2009 20:07:29 +0900 Subject: perf timechart: Fix header handling Update "struct trace_entry" to match with current one. And remove "size" field from it. If it has "size", it become cause of alignment mismatch of structure with kernel. Signed-off-by: OGAWA Hirofumi Acked-by: Arjan van de Ven Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <87ljhg8ioe.fsf@devron.myhome.or.jp> Signed-off-by: Ingo Molnar --- tools/perf/builtin-timechart.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index cb58b6605fcc..c0f29ed09966 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -302,12 +302,11 @@ process_exit_event(event_t *event) } struct trace_entry { - u32 size; unsigned short type; unsigned char flags; unsigned char preempt_count; int pid; - int tgid; + int lock_depth; }; struct power_entry { @@ -489,6 +488,7 @@ process_sample_event(event_t *event) u64 stamp = 0; u32 cpu = 0; u32 pid = 0; + u32 size, *size_ptr; struct trace_entry *te; if (sample_type & PERF_SAMPLE_IP) @@ -518,9 +518,13 @@ process_sample_event(event_t *event) if (sample_type & PERF_SAMPLE_PERIOD) cursor++; - te = (void *)&event->sample.array[cursor]; + size_ptr = (void *)&event->sample.array[cursor]; - if (sample_type & PERF_SAMPLE_RAW && te->size > 0) { + size = *size_ptr; + size_ptr++; + + te = (void *)size_ptr; + if (sample_type & PERF_SAMPLE_RAW && size > 0) { char *event_str; struct power_entry *pe; -- cgit v1.2.3 From 180f95e29aa8782c019caa64ede2a28d8ab62564 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Sun, 6 Dec 2009 20:08:24 +0900 Subject: perf: Make common SAMPLE_EVENT parser Currently, sample event data is parsed for each commands, and it is assuming that the data is not including other data. (E.g. timechart, trace, etc. can't parse the event if it has PERF_SAMPLE_CALLCHAIN) So, even if we record the superset data for multiple commands at a time, commands can't parse. etc. To fix it, this makes common sample event parser, and use it to parse sample event correctly. (PERF_SAMPLE_READ is unsupported for now though, it seems to be not using.) Signed-off-by: OGAWA Hirofumi Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker LKML-Reference: <87hbs48imv.fsf@devron.myhome.or.jp> Signed-off-by: Ingo Molnar --- tools/perf/builtin-kmem.c | 36 ++++++++--------------- tools/perf/builtin-report.c | 39 ++++++++++++------------ tools/perf/builtin-sched.c | 38 ++++++++---------------- tools/perf/builtin-timechart.c | 56 ++++++++++------------------------- tools/perf/builtin-trace.c | 48 ++++++++++-------------------- tools/perf/util/event.c | 67 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/event.h | 17 ++++++++++- 7 files changed, 155 insertions(+), 146 deletions(-) (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 047fef74bd52..f218990de0cd 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -320,35 +320,23 @@ process_raw_event(event_t *raw_event __used, void *more_data, static int process_sample_event(event_t *event) { - u64 ip = event->ip.ip; - u64 timestamp = -1; - u32 cpu = -1; - u64 period = 1; - void *more_data = event->ip.__more_data; - struct thread *thread = threads__findnew(event->ip.pid); - - if (sample_type & PERF_SAMPLE_TIME) { - timestamp = *(u64 *)more_data; - more_data += sizeof(u64); - } + struct sample_data data; + struct thread *thread; - if (sample_type & PERF_SAMPLE_CPU) { - cpu = *(u32 *)more_data; - more_data += sizeof(u32); - more_data += sizeof(u32); /* reserved */ - } + memset(&data, 0, sizeof(data)); + data.time = -1; + data.cpu = -1; + data.period = 1; - if (sample_type & PERF_SAMPLE_PERIOD) { - period = *(u64 *)more_data; - more_data += sizeof(u64); - } + event__parse_sample(event, sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, - event->ip.pid, event->ip.tid, - (void *)(long)ip, - (long long)period); + data.pid, data.tid, + (void *)(long)data.ip, + (long long)data.period); + thread = threads__findnew(event->ip.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); @@ -357,7 +345,7 @@ static int process_sample_event(event_t *event) dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - process_raw_event(event, more_data, cpu, timestamp, thread); + process_raw_event(event, data.raw_data, data.cpu, data.time, thread); return 0; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 383c4ab4f9af..2b9eb3a553ed 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -605,44 +605,41 @@ static int validate_chain(struct ip_callchain *chain, event_t *event) static int process_sample_event(event_t *event) { - u64 ip = event->ip.ip; - u64 period = 1; - void *more_data = event->ip.__more_data; - struct ip_callchain *chain = NULL; + struct sample_data data; int cpumode; struct addr_location al; - struct thread *thread = threads__findnew(event->ip.pid); + struct thread *thread; - if (sample_type & PERF_SAMPLE_PERIOD) { - period = *(u64 *)more_data; - more_data += sizeof(u64); - } + memset(&data, 0, sizeof(data)); + data.period = 1; + + event__parse_sample(event, sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, - event->ip.pid, event->ip.tid, - (void *)(long)ip, - (long long)period); + data.pid, data.tid, + (void *)(long)data.ip, + (long long)data.period); if (sample_type & PERF_SAMPLE_CALLCHAIN) { unsigned int i; - chain = (void *)more_data; - - dump_printf("... chain: nr:%Lu\n", chain->nr); + dump_printf("... chain: nr:%Lu\n", data.callchain->nr); - if (validate_chain(chain, event) < 0) { + if (validate_chain(data.callchain, event) < 0) { pr_debug("call-chain problem with event, " "skipping it.\n"); return 0; } if (dump_trace) { - for (i = 0; i < chain->nr; i++) - dump_printf("..... %2d: %016Lx\n", i, chain->ips[i]); + for (i = 0; i < data.callchain->nr; i++) + dump_printf("..... %2d: %016Lx\n", + i, data.callchain->ips[i]); } } + thread = threads__findnew(data.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); @@ -657,7 +654,7 @@ static int process_sample_event(event_t *event) cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; thread__find_addr_location(thread, cpumode, - MAP__FUNCTION, ip, &al, NULL); + MAP__FUNCTION, data.ip, &al, NULL); /* * We have to do this here as we may have a dso with no symbol hit that * has a name longer than the ones with symbols sampled. @@ -675,12 +672,12 @@ static int process_sample_event(event_t *event) if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name)) return 0; - if (hist_entry__add(&al, chain, period)) { + if (hist_entry__add(&al, data.callchain, data.period)) { pr_debug("problem incrementing symbol count, skipping event\n"); return -1; } - event__stats.total += period; + event__stats.total += data.period; return 0; } diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 26b782f26ee1..45c46c790493 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1598,40 +1598,26 @@ process_raw_event(event_t *raw_event __used, void *more_data, static int process_sample_event(event_t *event) { + struct sample_data data; struct thread *thread; - u64 ip = event->ip.ip; - u64 timestamp = -1; - u32 cpu = -1; - u64 period = 1; - void *more_data = event->ip.__more_data; if (!(sample_type & PERF_SAMPLE_RAW)) return 0; - thread = threads__findnew(event->ip.pid); + memset(&data, 0, sizeof(data)); + data.time = -1; + data.cpu = -1; + data.period = -1; - if (sample_type & PERF_SAMPLE_TIME) { - timestamp = *(u64 *)more_data; - more_data += sizeof(u64); - } - - if (sample_type & PERF_SAMPLE_CPU) { - cpu = *(u32 *)more_data; - more_data += sizeof(u32); - more_data += sizeof(u32); /* reserved */ - } - - if (sample_type & PERF_SAMPLE_PERIOD) { - period = *(u64 *)more_data; - more_data += sizeof(u64); - } + event__parse_sample(event, sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, - event->ip.pid, event->ip.tid, - (void *)(long)ip, - (long long)period); + data.pid, data.tid, + (void *)(long)data.ip, + (long long)data.period); + thread = threads__findnew(data.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); @@ -1640,10 +1626,10 @@ static int process_sample_event(event_t *event) dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - if (profile_cpu != -1 && profile_cpu != (int) cpu) + if (profile_cpu != -1 && profile_cpu != (int)data.cpu) return 0; - process_raw_event(event, more_data, cpu, timestamp, thread); + process_raw_event(event, data.raw_data, data.cpu, data.time, thread); return 0; } diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index c0f29ed09966..f472df9561ee 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -483,48 +483,22 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te) static int process_sample_event(event_t *event) { - int cursor = 0; - u64 addr = 0; - u64 stamp = 0; - u32 cpu = 0; - u32 pid = 0; - u32 size, *size_ptr; + struct sample_data data; struct trace_entry *te; - if (sample_type & PERF_SAMPLE_IP) - cursor++; - - if (sample_type & PERF_SAMPLE_TID) { - pid = event->sample.array[cursor]>>32; - cursor++; - } - if (sample_type & PERF_SAMPLE_TIME) { - stamp = event->sample.array[cursor++]; + memset(&data, 0, sizeof(data)); - if (!first_time || first_time > stamp) - first_time = stamp; - if (last_time < stamp) - last_time = stamp; + event__parse_sample(event, sample_type, &data); + if (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 (sample_type & PERF_SAMPLE_ADDR) - addr = event->sample.array[cursor++]; - if (sample_type & PERF_SAMPLE_ID) - cursor++; - if (sample_type & PERF_SAMPLE_STREAM_ID) - cursor++; - if (sample_type & PERF_SAMPLE_CPU) - cpu = event->sample.array[cursor++] & 0xFFFFFFFF; - if (sample_type & PERF_SAMPLE_PERIOD) - cursor++; - - size_ptr = (void *)&event->sample.array[cursor]; - - size = *size_ptr; - size_ptr++; - te = (void *)size_ptr; - if (sample_type & PERF_SAMPLE_RAW && size > 0) { + te = (void *)data.raw_data; + if (sample_type & PERF_SAMPLE_RAW && data.raw_size > 0) { char *event_str; struct power_entry *pe; @@ -536,19 +510,19 @@ process_sample_event(event_t *event) return 0; if (strcmp(event_str, "power:power_start") == 0) - c_state_start(cpu, stamp, pe->value); + c_state_start(data.cpu, data.time, pe->value); if (strcmp(event_str, "power:power_end") == 0) - c_state_end(cpu, stamp); + c_state_end(data.cpu, data.time); if (strcmp(event_str, "power:power_frequency") == 0) - p_state_change(cpu, stamp, pe->value); + p_state_change(data.cpu, data.time, pe->value); if (strcmp(event_str, "sched:sched_wakeup") == 0) - sched_wakeup(cpu, stamp, pid, te); + sched_wakeup(data.cpu, data.time, data.pid, te); if (strcmp(event_str, "sched:sched_switch") == 0) - sched_switch(cpu, stamp, te); + sched_switch(data.cpu, data.time, te); } return 0; } diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index abb914aa7be6..c2fcc34486f5 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -66,58 +66,40 @@ static u64 sample_type; static int process_sample_event(event_t *event) { - u64 ip = event->ip.ip; - u64 timestamp = -1; - u32 cpu = -1; - u64 period = 1; - void *more_data = event->ip.__more_data; - struct thread *thread = threads__findnew(event->ip.pid); - - if (sample_type & PERF_SAMPLE_TIME) { - timestamp = *(u64 *)more_data; - more_data += sizeof(u64); - } + struct sample_data data; + struct thread *thread; - if (sample_type & PERF_SAMPLE_CPU) { - cpu = *(u32 *)more_data; - more_data += sizeof(u32); - more_data += sizeof(u32); /* reserved */ - } + memset(&data, 0, sizeof(data)); + data.time = -1; + data.cpu = -1; + data.period = 1; - if (sample_type & PERF_SAMPLE_PERIOD) { - period = *(u64 *)more_data; - more_data += sizeof(u64); - } + event__parse_sample(event, sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, - event->ip.pid, event->ip.tid, - (void *)(long)ip, - (long long)period); + data.pid, data.tid, + (void *)(long)data.ip, + (long long)data.period); + thread = threads__findnew(event->ip.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); return -1; } - dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - if (sample_type & PERF_SAMPLE_RAW) { - struct { - u32 size; - char data[0]; - } *raw = more_data; - /* * FIXME: better resolve from pid from the struct trace_entry * field, although it should be the same than this perf * event pid */ - scripting_ops->process_event(cpu, raw->data, raw->size, - timestamp, thread->comm); + scripting_ops->process_event(data.cpu, data.raw_data, + data.raw_size, + data.time, thread->comm); } - event__stats.total += period; + event__stats.total += data.period; return 0; } diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 414b89d1bde9..4dcecafa85dc 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -310,3 +310,70 @@ int event__preprocess_sample(const event_t *self, struct addr_location *al, al->level == 'H' ? "[hypervisor]" : ""); return 0; } + +int event__parse_sample(event_t *event, u64 type, struct sample_data *data) +{ + u64 *array = event->sample.array; + + if (type & PERF_SAMPLE_IP) { + data->ip = event->ip.ip; + array++; + } + + if (type & PERF_SAMPLE_TID) { + u32 *p = (u32 *)array; + data->pid = p[0]; + data->tid = p[1]; + array++; + } + + if (type & PERF_SAMPLE_TIME) { + data->time = *array; + array++; + } + + if (type & PERF_SAMPLE_ADDR) { + data->addr = *array; + array++; + } + + if (type & PERF_SAMPLE_ID) { + data->id = *array; + array++; + } + + if (type & PERF_SAMPLE_STREAM_ID) { + data->stream_id = *array; + array++; + } + + if (type & PERF_SAMPLE_CPU) { + u32 *p = (u32 *)array; + data->cpu = *p; + array++; + } + + if (type & PERF_SAMPLE_PERIOD) { + data->period = *array; + array++; + } + + if (type & PERF_SAMPLE_READ) { + pr_debug("PERF_SAMPLE_READ is unsuported for now\n"); + return -1; + } + + if (type & PERF_SAMPLE_CALLCHAIN) { + data->callchain = (struct ip_callchain *)array; + array += 1 + data->callchain->nr; + } + + if (type & PERF_SAMPLE_RAW) { + u32 *p = (u32 *)array; + data->raw_size = *p; + p++; + data->raw_data = p; + } + + return 0; +} diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index a4cc8105cf67..c7a78eef8e52 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -56,11 +56,25 @@ struct read_event { u64 id; }; -struct sample_event{ +struct sample_event { struct perf_event_header header; u64 array[]; }; +struct sample_data { + u64 ip; + u32 pid, tid; + u64 time; + u64 addr; + u64 id; + u64 stream_id; + u32 cpu; + u64 period; + struct ip_callchain *callchain; + u32 raw_size; + void *raw_data; +}; + #define BUILD_ID_SIZE 20 struct build_id_event { @@ -155,5 +169,6 @@ int event__process_task(event_t *self); struct addr_location; int event__preprocess_sample(const event_t *self, struct addr_location *al, symbol_filter_t filter); +int event__parse_sample(event_t *event, u64 type, struct sample_data *data); #endif /* __PERF_RECORD_H */ -- cgit v1.2.3 From 94c744b6c0c6c5802a85ebfebbec429ac5851f2b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 11 Dec 2009 21:24:02 -0200 Subject: perf tools: Introduce perf_session class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That does all the initialization boilerplate, opening the file, reading the header, checking if it is valid, etc. And that will as well have the threads list, kmap (now) global variable, etc, so that we can handle two (or more) perf.data files describing sessions to compare. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260573842-19720-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar --- tools/perf/Makefile | 3 ++ tools/perf/builtin-annotate.c | 15 +++++--- tools/perf/builtin-buildid-list.c | 55 ++++----------------------- tools/perf/builtin-kmem.c | 13 +++++-- tools/perf/builtin-record.c | 25 ++++++------ tools/perf/builtin-report.c | 20 ++++++---- tools/perf/builtin-sched.c | 13 +++++-- tools/perf/builtin-timechart.c | 15 +++++--- tools/perf/builtin-trace.c | 20 ++++++---- tools/perf/util/data_map.c | 71 ++++++---------------------------- tools/perf/util/data_map.h | 9 ++--- tools/perf/util/header.c | 28 +++----------- tools/perf/util/header.h | 4 +- tools/perf/util/session.c | 80 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/session.h | 16 ++++++++ 15 files changed, 206 insertions(+), 181 deletions(-) create mode 100644 tools/perf/util/session.c create mode 100644 tools/perf/util/session.h (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/Makefile b/tools/perf/Makefile index e2ee3b589af7..406999668cab 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -356,7 +356,9 @@ LIB_H += util/parse-options.h LIB_H += util/parse-events.h LIB_H += util/quote.h LIB_H += util/util.h +LIB_H += util/header.h LIB_H += util/help.h +LIB_H += util/session.h LIB_H += util/strbuf.h LIB_H += util/string.h LIB_H += util/strlist.h @@ -405,6 +407,7 @@ LIB_OBJS += util/callchain.o LIB_OBJS += util/values.o LIB_OBJS += util/debug.o LIB_OBJS += util/map.o +LIB_OBJS += util/session.o LIB_OBJS += util/thread.o LIB_OBJS += util/trace-event-parse.o LIB_OBJS += util/trace-event-read.o diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 0bf2e8f9af57..21a78d30d53d 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -25,6 +25,7 @@ #include "util/thread.h" #include "util/sort.h" #include "util/hist.h" +#include "util/session.h" #include "util/data_map.h" static char const *input_name = "perf.data"; @@ -462,21 +463,23 @@ static struct perf_file_handler file_handler = { static int __cmd_annotate(void) { - struct perf_header *header; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, force); struct thread *idle; int ret; + if (session == NULL) + return -ENOMEM; + idle = register_idle_thread(); register_perf_file_handler(&file_handler); - ret = mmap_dispatch_perf_file(&header, input_name, 0, 0, - &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); if (ret) - return ret; + goto out_delete; if (dump_trace) { event__print_totals(); - return 0; + goto out_delete; } if (verbose > 3) @@ -489,6 +492,8 @@ static int __cmd_annotate(void) output__resort(event__total[0]); find_annotations(); +out_delete: + perf_session__delete(session); return ret; } diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index dcb6143a0002..bfd16a1594e4 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -11,8 +11,8 @@ #include "util/cache.h" #include "util/data_map.h" #include "util/debug.h" -#include "util/header.h" #include "util/parse-options.h" +#include "util/session.h" #include "util/symbol.h" static char const *input_name = "perf.data"; @@ -55,56 +55,17 @@ static int perf_file_section__process_buildids(struct perf_file_section *self, static int __cmd_buildid_list(void) { int err = -1; - struct perf_header *header; - struct perf_file_header f_header; - struct stat input_stat; - int input = open(input_name, O_RDONLY); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, force); - if (input < 0) { - pr_err("failed to open file: %s", input_name); - if (!strcmp(input_name, "perf.data")) - pr_err(" (try 'perf record' first)"); - pr_err("\n"); - goto out; - } - - err = fstat(input, &input_stat); - if (err < 0) { - perror("failed to stat file"); - goto out_close; - } - - if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) { - pr_err("file %s not owned by current user or root\n", - input_name); - goto out_close; - } - - if (!input_stat.st_size) { - pr_info("zero-sized file, nothing to do!\n"); - goto out_close; - } - - err = -1; - header = perf_header__new(); - if (header == NULL) - goto out_close; - - if (perf_file_header__read(&f_header, header, input) < 0) { - pr_warning("incompatible file format"); - goto out_close; - } + if (session == NULL) + return -1; - err = perf_header__process_sections(header, input, + err = perf_header__process_sections(&session->header, session->fd, perf_file_section__process_buildids); + if (err >= 0) + dsos__fprintf_buildid(stdout); - if (err < 0) - goto out_close; - - dsos__fprintf_buildid(stdout); -out_close: - close(input); -out: + perf_session__delete(session); return err; } diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index fe73435192b3..2071d2485913 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -6,6 +6,7 @@ #include "util/symbol.h" #include "util/thread.h" #include "util/header.h" +#include "util/session.h" #include "util/parse-options.h" #include "util/trace-event.h" @@ -20,7 +21,6 @@ typedef int (*sort_fn_t)(struct alloc_stat *, struct alloc_stat *); static char const *input_name = "perf.data"; -static struct perf_header *header; static u64 sample_type; static int alloc_flag; @@ -367,11 +367,18 @@ static struct perf_file_handler file_handler = { static int read_events(void) { + int err; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); + + if (session == NULL) + return -ENOMEM; + register_idle_thread(); register_perf_file_handler(&file_handler); - return mmap_dispatch_perf_file(&header, input_name, 0, 0, - &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + perf_session__delete(session); + return err; } static double fragmentation(unsigned long n_req, unsigned long n_alloc) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 0e519c667e3a..4decbd14eaed 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -17,6 +17,7 @@ #include "util/header.h" #include "util/event.h" #include "util/debug.h" +#include "util/session.h" #include "util/symbol.h" #include @@ -62,7 +63,7 @@ static int nr_cpu = 0; static int file_new = 1; -struct perf_header *header = NULL; +static struct perf_session *session; struct mmap_data { int counter; @@ -216,12 +217,12 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n { struct perf_header_attr *h_attr; - if (nr < header->attrs) { - h_attr = header->attr[nr]; + if (nr < session->header.attrs) { + h_attr = session->header.attr[nr]; } else { h_attr = perf_header_attr__new(a); if (h_attr != NULL) - if (perf_header__add_attr(header, h_attr) < 0) { + if (perf_header__add_attr(&session->header, h_attr) < 0) { perf_header_attr__delete(h_attr); h_attr = NULL; } @@ -395,9 +396,9 @@ static void open_counters(int cpu, pid_t pid) static void atexit_header(void) { - header->data_size += bytes_written; + session->header.data_size += bytes_written; - perf_header__write(header, output, true); + perf_header__write(&session->header, output, true); } static int __cmd_record(int argc, const char **argv) @@ -440,24 +441,24 @@ static int __cmd_record(int argc, const char **argv) exit(-1); } - header = perf_header__new(); - if (header == NULL) { + session = perf_session__new(output_name, O_WRONLY, force); + if (session == NULL) { pr_err("Not enough memory for reading perf file header\n"); return -1; } if (!file_new) { - err = perf_header__read(header, output); + err = perf_header__read(&session->header, output); if (err < 0) return err; } if (raw_samples) { - perf_header__set_feat(header, HEADER_TRACE_INFO); + perf_header__set_feat(&session->header, HEADER_TRACE_INFO); } else { for (i = 0; i < nr_counters; i++) { if (attrs[i].sample_type & PERF_SAMPLE_RAW) { - perf_header__set_feat(header, HEADER_TRACE_INFO); + perf_header__set_feat(&session->header, HEADER_TRACE_INFO); break; } } @@ -481,7 +482,7 @@ static int __cmd_record(int argc, const char **argv) } if (file_new) { - err = perf_header__write(header, output, false); + err = perf_header__write(&session->header, output, false); if (err < 0) return err; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2b9eb3a553ed..e2ec49a9b731 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -22,6 +22,7 @@ #include "perf.h" #include "util/debug.h" #include "util/header.h" +#include "util/session.h" #include "util/parse-options.h" #include "util/parse-events.h" @@ -52,7 +53,7 @@ static int exclude_other = 1; static char callchain_default_opt[] = "fractal,0.5"; -static struct perf_header *header; +static struct perf_session *session; static u64 sample_type; @@ -701,7 +702,7 @@ static int process_read_event(event_t *event) { struct perf_event_attr *attr; - attr = perf_header__find_attr(event->read.id, header); + attr = perf_header__find_attr(event->read.id, &session->header); if (show_threads) { const char *name = attr ? __event_name(attr->type, attr->config) @@ -766,6 +767,10 @@ static int __cmd_report(void) struct thread *idle; int ret; + session = perf_session__new(input_name, O_RDONLY, force); + if (session == NULL) + return -ENOMEM; + idle = register_idle_thread(); thread__comm_adjust(idle); @@ -774,14 +779,14 @@ static int __cmd_report(void) register_perf_file_handler(&file_handler); - ret = mmap_dispatch_perf_file(&header, input_name, force, - full_paths, &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, full_paths, + &event__cwdlen, &event__cwd); if (ret) - return ret; + goto out_delete; if (dump_trace) { event__print_totals(); - return 0; + goto out_delete; } if (verbose > 3) @@ -796,7 +801,8 @@ static int __cmd_report(void) if (show_threads) perf_read_values_destroy(&show_threads_values); - +out_delete: + perf_session__delete(session); return ret; } diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 7cca7c15b40a..65021fe1361e 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -6,6 +6,7 @@ #include "util/symbol.h" #include "util/thread.h" #include "util/header.h" +#include "util/session.h" #include "util/parse-options.h" #include "util/trace-event.h" @@ -21,7 +22,6 @@ static char const *input_name = "perf.data"; -static struct perf_header *header; static u64 sample_type; static char default_sort_order[] = "avg, max, switch, runtime"; @@ -1663,11 +1663,18 @@ static struct perf_file_handler file_handler = { static int read_events(void) { + int err; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); + + if (session == NULL) + return -ENOMEM; + register_idle_thread(); register_perf_file_handler(&file_handler); - return mmap_dispatch_perf_file(&header, input_name, 0, 0, - &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + perf_session__delete(session); + return err; } static void print_bad_events(void) diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index f472df9561ee..759dd2b35fdb 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1059,15 +1059,17 @@ static struct perf_file_handler file_handler = { static int __cmd_timechart(void) { - struct perf_header *header; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); int ret; + if (session == NULL) + return -ENOMEM; + register_perf_file_handler(&file_handler); - ret = mmap_dispatch_perf_file(&header, input_name, 0, 0, - &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); if (ret) - return EXIT_FAILURE; + goto out_delete; process_samples(); @@ -1079,8 +1081,9 @@ static int __cmd_timechart(void) pr_info("Written %2.1f seconds of trace to %s.\n", (last_time - first_time) / 1000000000.0, output_name); - - return EXIT_SUCCESS; +out_delete: + perf_session__delete(session); + return ret; } static const char * const timechart_usage[] = { diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c2fcc34486f5..0756664666f1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -7,6 +7,7 @@ #include "util/header.h" #include "util/exec_cmd.h" #include "util/trace-event.h" +#include "util/session.h" static char const *script_name; static char const *generate_script_lang; @@ -61,7 +62,7 @@ static int cleanup_scripting(void) static char const *input_name = "perf.data"; -static struct perf_header *header; +static struct perf_session *session; static u64 sample_type; static int process_sample_event(event_t *event) @@ -126,11 +127,18 @@ static struct perf_file_handler file_handler = { static int __cmd_trace(void) { + int err; + + session = perf_session__new(input_name, O_RDONLY, 0); + if (session == NULL) + return -ENOMEM; + register_idle_thread(); register_perf_file_handler(&file_handler); - return mmap_dispatch_perf_file(&header, input_name, - 0, 0, &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + perf_session__delete(session); + return err; } struct script_spec { @@ -348,11 +356,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) return -1; } - header = perf_header__new(); - if (header == NULL) - return -1; - - perf_header__read(header, input); + perf_header__read(&session->header, input); err = scripting_ops->generate_script("perf-trace"); goto out; } diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 59b65d0bd7c1..6d46dda53a29 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -129,23 +129,16 @@ out: return err; } -int mmap_dispatch_perf_file(struct perf_header **pheader, - const char *input_name, - int force, - int full_paths, - int *cwdlen, - char **cwd) +int perf_session__process_events(struct perf_session *self, + int full_paths, int *cwdlen, char **cwd) { int err; - struct perf_header *header; unsigned long head, shift; unsigned long offset = 0; - struct stat input_stat; size_t page_size; u64 sample_type; event_t *event; uint32_t size; - int input; char *buf; if (curr_handler == NULL) { @@ -155,56 +148,19 @@ int mmap_dispatch_perf_file(struct perf_header **pheader, page_size = getpagesize(); - input = open(input_name, O_RDONLY); - if (input < 0) { - pr_err("Failed to open file: %s", input_name); - if (!strcmp(input_name, "perf.data")) - pr_err(" (try 'perf record' first)"); - pr_err("\n"); - return -errno; - } - - if (fstat(input, &input_stat) < 0) { - pr_err("failed to stat file"); - err = -errno; - goto out_close; - } - - err = -EACCES; - if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) { - pr_err("file: %s not owned by current user or root\n", - input_name); - goto out_close; - } - - if (input_stat.st_size == 0) { - pr_info("zero-sized file, nothing to do!\n"); - goto done; - } - - err = -ENOMEM; - header = perf_header__new(); - if (header == NULL) - goto out_close; - - err = perf_header__read(header, input); - if (err < 0) - goto out_delete; - *pheader = header; - head = header->data_offset; - - sample_type = perf_header__sample_type(header); + head = self->header.data_offset; + sample_type = perf_header__sample_type(&self->header); err = -EINVAL; if (curr_handler->sample_type_check && curr_handler->sample_type_check(sample_type) < 0) - goto out_delete; + goto out_err; if (!full_paths) { if (getcwd(__cwd, sizeof(__cwd)) == NULL) { pr_err("failed to get the current directory\n"); err = -errno; - goto out_delete; + goto out_err; } *cwd = __cwd; *cwdlen = strlen(*cwd); @@ -219,11 +175,11 @@ int mmap_dispatch_perf_file(struct perf_header **pheader, remap: buf = mmap(NULL, page_size * mmap_window, PROT_READ, - MAP_SHARED, input, offset); + MAP_SHARED, self->fd, offset); if (buf == MAP_FAILED) { pr_err("failed to mmap file\n"); err = -errno; - goto out_delete; + goto out_err; } more: @@ -273,19 +229,14 @@ more: head += size; - if (offset + head >= header->data_offset + header->data_size) + if (offset + head >= self->header.data_offset + self->header.data_size) goto done; - if (offset + head < (unsigned long)input_stat.st_size) + if (offset + head < self->size) goto more; done: err = 0; -out_close: - close(input); - +out_err: return err; -out_delete: - perf_header__delete(header); - goto out_close; } diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h index 258a87bcc4fb..98c5b823388c 100644 --- a/tools/perf/util/data_map.h +++ b/tools/perf/util/data_map.h @@ -3,6 +3,7 @@ #include "event.h" #include "header.h" +#include "session.h" typedef int (*event_type_handler_t)(event_t *); @@ -21,12 +22,8 @@ struct perf_file_handler { }; void register_perf_file_handler(struct perf_file_handler *handler); -int mmap_dispatch_perf_file(struct perf_header **pheader, - const char *input_name, - int force, - int full_paths, - int *cwdlen, - char **cwd); +int perf_session__process_events(struct perf_session *self, + int full_paths, int *cwdlen, char **cwd); int perf_header__read_build_ids(int input, u64 offset, u64 file_size); #endif diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 59a9c0b3033e..f2e8d8715111 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -58,35 +58,19 @@ int perf_header_attr__add_id(struct perf_header_attr *self, u64 id) return 0; } -/* - * Create new perf.data header: - */ -struct perf_header *perf_header__new(void) +int perf_header__init(struct perf_header *self) { - struct perf_header *self = zalloc(sizeof(*self)); - - if (self != NULL) { - self->size = 1; - self->attr = malloc(sizeof(void *)); - - if (self->attr == NULL) { - free(self); - self = NULL; - } - } - - return self; + self->size = 1; + self->attr = malloc(sizeof(void *)); + return self->attr == NULL ? -ENOMEM : 0; } -void perf_header__delete(struct perf_header *self) +void perf_header__exit(struct perf_header *self) { int i; - for (i = 0; i < self->attrs; ++i) - perf_header_attr__delete(self->attr[i]); - + perf_header_attr__delete(self->attr[i]); free(self->attr); - free(self); } int perf_header__add_attr(struct perf_header *self, diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index d1dbe2b79c42..d118d05d3abe 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -55,8 +55,8 @@ struct perf_header { DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS); }; -struct perf_header *perf_header__new(void); -void perf_header__delete(struct perf_header *self); +int perf_header__init(struct perf_header *self); +void perf_header__exit(struct perf_header *self); int perf_header__read(struct perf_header *self, int fd); int perf_header__write(struct perf_header *self, int fd, bool at_exit); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c new file mode 100644 index 000000000000..707ce1cb1621 --- /dev/null +++ b/tools/perf/util/session.c @@ -0,0 +1,80 @@ +#include + +#include +#include + +#include "session.h" +#include "util.h" + +static int perf_session__open(struct perf_session *self, bool force) +{ + struct stat input_stat; + + self->fd = open(self->filename, O_RDONLY); + if (self->fd < 0) { + pr_err("failed to open file: %s", self->filename); + if (!strcmp(self->filename, "perf.data")) + pr_err(" (try 'perf record' first)"); + pr_err("\n"); + return -errno; + } + + if (fstat(self->fd, &input_stat) < 0) + goto out_close; + + if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) { + pr_err("file %s not owned by current user or root\n", + self->filename); + goto out_close; + } + + if (!input_stat.st_size) { + pr_info("zero-sized file (%s), nothing to do!\n", + self->filename); + goto out_close; + } + + if (perf_header__read(&self->header, self->fd) < 0) { + pr_err("incompatible file format"); + goto out_close; + } + + self->size = input_stat.st_size; + return 0; + +out_close: + close(self->fd); + self->fd = -1; + return -1; +} + +struct perf_session *perf_session__new(const char *filename, int mode, bool force) +{ + size_t len = strlen(filename) + 1; + struct perf_session *self = zalloc(sizeof(*self) + len); + + if (self == NULL) + goto out; + + if (perf_header__init(&self->header) < 0) + goto out_delete; + + memcpy(self->filename, filename, len); + + if (mode == O_RDONLY && perf_session__open(self, force) < 0) { + perf_session__delete(self); + self = NULL; + } +out: + return self; +out_delete: + free(self); + return NULL; +} + +void perf_session__delete(struct perf_session *self) +{ + perf_header__exit(&self->header); + close(self->fd); + free(self); +} diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h new file mode 100644 index 000000000000..f3699c8c8ed4 --- /dev/null +++ b/tools/perf/util/session.h @@ -0,0 +1,16 @@ +#ifndef __PERF_SESSION_H +#define __PERF_SESSION_H + +#include "header.h" + +struct perf_session { + struct perf_header header; + unsigned long size; + int fd; + char filename[0]; +}; + +struct perf_session *perf_session__new(const char *filename, int mode, bool force); +void perf_session__delete(struct perf_session *self); + +#endif /* __PERF_SESSION_H */ -- cgit v1.2.3 From d8f66248d6f25f7c935cc5307c43bf394db07272 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 13 Dec 2009 19:50:24 -0200 Subject: perf session: Pass the perf_session to the event handling operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They will need it to get the right threads list, etc. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260741029-4430-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-record.c | 11 +++++++---- tools/perf/builtin-report.c | 9 ++++----- tools/perf/builtin-sched.c | 6 ++++-- tools/perf/builtin-timechart.c | 13 +++++-------- tools/perf/builtin-top.c | 28 +++++++++++++++++----------- tools/perf/builtin-trace.c | 23 ++++++++++------------- tools/perf/util/data_map.c | 27 ++++++++++++++------------- tools/perf/util/data_map.h | 5 ++++- tools/perf/util/event.c | 37 +++++++++++++++++++++++-------------- tools/perf/util/event.h | 19 +++++++++++++------ 12 files changed, 103 insertions(+), 79 deletions(-) (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 21a78d30d53d..2e418b9fc1c4 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -132,7 +132,7 @@ static int hist_entry__add(struct addr_location *al, u64 count) return 0; } -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session __used) { struct addr_location al; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 2071d2485913..101b2682b4df 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -312,7 +312,7 @@ process_raw_event(event_t *raw_event __used, void *data, } } -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session __used) { struct sample_data data; struct thread *thread; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 4decbd14eaed..b7e15a1b1ec2 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -123,7 +123,8 @@ static void write_event(event_t *buf, size_t size) write_output(buf, size); } -static int process_synthesized_event(event_t *event) +static int process_synthesized_event(event_t *event, + struct perf_session *self __used) { write_event(event, event->header.size); return 0; @@ -488,9 +489,10 @@ static int __cmd_record(int argc, const char **argv) } if (!system_wide) - event__synthesize_thread(pid, process_synthesized_event); + event__synthesize_thread(pid, process_synthesized_event, + session); else - event__synthesize_threads(process_synthesized_event); + event__synthesize_threads(process_synthesized_event, session); if (target_pid == -1 && argc) { pid = fork(); @@ -510,7 +512,8 @@ static int __cmd_record(int argc, const char **argv) */ usleep(1000); event__synthesize_thread(pid, - process_synthesized_event); + process_synthesized_event, + session); } child_pid = pid; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index e2ec49a9b731..dcd8fedc298c 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -53,8 +53,6 @@ static int exclude_other = 1; static char callchain_default_opt[] = "fractal,0.5"; -static struct perf_session *session; - static u64 sample_type; struct symbol_conf symbol_conf; @@ -604,7 +602,7 @@ static int validate_chain(struct ip_callchain *chain, event_t *event) return 0; } -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session __used) { struct sample_data data; int cpumode; @@ -683,7 +681,7 @@ static int process_sample_event(event_t *event) return 0; } -static int process_comm_event(event_t *event) +static int process_comm_event(event_t *event, struct perf_session *session __used) { struct thread *thread = threads__findnew(event->comm.pid); @@ -698,7 +696,7 @@ static int process_comm_event(event_t *event) return 0; } -static int process_read_event(event_t *event) +static int process_read_event(event_t *event, struct perf_session *session __used) { struct perf_event_attr *attr; @@ -766,6 +764,7 @@ static int __cmd_report(void) { struct thread *idle; int ret; + struct perf_session *session; session = perf_session__new(input_name, O_RDONLY, force); if (session == NULL) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 65021fe1361e..48ab283ed86b 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1594,7 +1594,8 @@ process_raw_event(event_t *raw_event __used, void *data, process_sched_migrate_task_event(data, event, cpu, timestamp, thread); } -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, + struct perf_session *session __used) { struct sample_data data; struct thread *thread; @@ -1632,7 +1633,8 @@ static int process_sample_event(event_t *event) return 0; } -static int process_lost_event(event_t *event __used) +static int process_lost_event(event_t *event __used, + struct perf_session *session __used) { nr_lost_chunks++; nr_lost_events += event->lost.lost; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 759dd2b35fdb..db6caae1a404 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -281,21 +281,19 @@ 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) +static int process_comm_event(event_t *event, struct perf_session *session __used) { pid_set_comm(event->comm.pid, event->comm.comm); return 0; } -static int -process_fork_event(event_t *event) + +static int process_fork_event(event_t *event, 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) +static int process_exit_event(event_t *event, struct perf_session *session __used) { pid_exit(event->fork.pid, event->fork.time); return 0; @@ -594,8 +592,7 @@ static u64 sample_time(event_t *event) * We first queue all events, sorted backwards by insertion. * The order will get flipped later. */ -static int -queue_sample_event(event_t *event) +static int queue_sample_event(event_t *event, struct perf_session *session __used) { struct sample_wrapper *copy, *prev; int size; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e0a374d0e43a..b13f42625549 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -965,14 +965,14 @@ static void event__process_sample(const event_t *self, int counter) } } -static int event__process(event_t *event) +static int event__process(event_t *event, struct perf_session *session) { switch (event->header.type) { case PERF_RECORD_COMM: - event__process_comm(event); + event__process_comm(event, session); break; case PERF_RECORD_MMAP: - event__process_mmap(event); + event__process_mmap(event, session); break; default: break; @@ -999,7 +999,8 @@ static unsigned int mmap_read_head(struct mmap_data *md) return head; } -static void mmap_read_counter(struct mmap_data *md) +static void perf_session__mmap_read_counter(struct perf_session *self, + struct mmap_data *md) { unsigned int head = mmap_read_head(md); unsigned int old = md->prev; @@ -1054,7 +1055,7 @@ static void mmap_read_counter(struct mmap_data *md) if (event->header.type == PERF_RECORD_SAMPLE) event__process_sample(event, md->counter); else - event__process(event); + event__process(event, self); old += size; } @@ -1064,13 +1065,13 @@ static void mmap_read_counter(struct mmap_data *md) static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; -static void mmap_read(void) +static void perf_session__mmap_read(struct perf_session *self) { int i, counter; for (i = 0; i < nr_cpus; i++) { for (counter = 0; counter < nr_counters; counter++) - mmap_read_counter(&mmap_array[i][counter]); + perf_session__mmap_read_counter(self, &mmap_array[i][counter]); } } @@ -1155,11 +1156,16 @@ static int __cmd_top(void) pthread_t thread; int i, counter; int ret; + /* + * XXX perf_session__new should allow passing a O_MMAP, so that all this + * mmap reading, etc is encapsulated in it. + */ + struct perf_session *session = NULL; if (target_pid != -1) - event__synthesize_thread(target_pid, event__process); + event__synthesize_thread(target_pid, event__process, session); else - event__synthesize_threads(event__process); + event__synthesize_threads(event__process, session); for (i = 0; i < nr_cpus; i++) { group_fd = -1; @@ -1170,7 +1176,7 @@ static int __cmd_top(void) /* Wait for a minimal set of events before starting the snapshot */ poll(event_array, nr_poll, 100); - mmap_read(); + perf_session__mmap_read(session); if (pthread_create(&thread, NULL, display_thread, NULL)) { printf("Could not create display thread.\n"); @@ -1190,7 +1196,7 @@ static int __cmd_top(void) while (1) { int hits = samples; - mmap_read(); + perf_session__mmap_read(session); if (hits == samples) ret = poll(event_array, nr_poll, 100); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 0756664666f1..3057e1d387b9 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -62,10 +62,9 @@ static int cleanup_scripting(void) static char const *input_name = "perf.data"; -static struct perf_session *session; static u64 sample_type; -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session __used) { struct sample_data data; struct thread *thread; @@ -125,20 +124,12 @@ static struct perf_file_handler file_handler = { .sample_type_check = sample_type_check, }; -static int __cmd_trace(void) +static int __cmd_trace(struct perf_session *session) { - int err; - - session = perf_session__new(input_name, O_RDONLY, 0); - if (session == NULL) - return -ENOMEM; - register_idle_thread(); register_perf_file_handler(&file_handler); - err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); - perf_session__delete(session); - return err; + return perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); } struct script_spec { @@ -313,6 +304,7 @@ static const struct option options[] = { int cmd_trace(int argc, const char **argv, const char *prefix __used) { int err; + struct perf_session *session; symbol__init(0); @@ -330,6 +322,10 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) setup_pager(); + session = perf_session__new(input_name, O_RDONLY, 0); + if (session == NULL) + return -ENOMEM; + if (generate_script_lang) { struct stat perf_stat; @@ -367,8 +363,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) goto out; } - err = __cmd_trace(); + err = __cmd_trace(session); + perf_session__delete(session); cleanup_scripting(); out: return err; diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 6d46dda53a29..22bcdfeff55c 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -8,7 +8,8 @@ static struct perf_file_handler *curr_handler; static unsigned long mmap_window = 32; static char __cwd[PATH_MAX]; -static int process_event_stub(event_t *event __used) +static int process_event_stub(event_t *event __used, + struct perf_session *session __used) { dump_printf(": unhandled!\n"); return 0; @@ -61,8 +62,8 @@ void event__print_totals(void) event__name[i], event__total[i]); } -static int -process_event(event_t *event, unsigned long offset, unsigned long head) +static int process_event(event_t *event, struct perf_session *session, + unsigned long offset, unsigned long head) { trace_event(event); @@ -77,23 +78,23 @@ process_event(event_t *event, unsigned long offset, unsigned long head) switch (event->header.type) { case PERF_RECORD_SAMPLE: - return curr_handler->process_sample_event(event); + return curr_handler->process_sample_event(event, session); case PERF_RECORD_MMAP: - return curr_handler->process_mmap_event(event); + return curr_handler->process_mmap_event(event, session); case PERF_RECORD_COMM: - return curr_handler->process_comm_event(event); + return curr_handler->process_comm_event(event, session); case PERF_RECORD_FORK: - return curr_handler->process_fork_event(event); + return curr_handler->process_fork_event(event, session); case PERF_RECORD_EXIT: - return curr_handler->process_exit_event(event); + return curr_handler->process_exit_event(event, session); case PERF_RECORD_LOST: - return curr_handler->process_lost_event(event); + return curr_handler->process_lost_event(event, session); case PERF_RECORD_READ: - return curr_handler->process_read_event(event); + return curr_handler->process_read_event(event, session); case PERF_RECORD_THROTTLE: - return curr_handler->process_throttle_event(event); + return curr_handler->process_throttle_event(event, session); case PERF_RECORD_UNTHROTTLE: - return curr_handler->process_unthrottle_event(event); + return curr_handler->process_unthrottle_event(event, session); default: curr_handler->total_unknown++; return -1; @@ -209,7 +210,7 @@ more: (void *)(long)event->header.size, event->header.type); - if (!size || process_event(event, offset, head) < 0) { + if (!size || process_event(event, self, offset, head) < 0) { dump_printf("%p [%p]: skipping unknown header type: %d\n", (void *)(offset + head), diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h index 98c5b823388c..6d4ae52bc07b 100644 --- a/tools/perf/util/data_map.h +++ b/tools/perf/util/data_map.h @@ -5,7 +5,10 @@ #include "header.h" #include "session.h" -typedef int (*event_type_handler_t)(event_t *); +struct perf_session; + +typedef int (*event_type_handler_t)(event_t *self, + struct perf_session *session); struct perf_file_handler { event_type_handler_t process_sample_event; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index ba0de90cd3d4..e2c489533c6d 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -5,7 +5,9 @@ #include "thread.h" static pid_t event__synthesize_comm(pid_t pid, int full, - int (*process)(event_t *event)) + int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session) { event_t ev; char filename[PATH_MAX]; @@ -54,7 +56,7 @@ out_race: if (!full) { ev.comm.tid = pid; - process(&ev); + process(&ev, session); goto out_fclose; } @@ -72,7 +74,7 @@ out_race: ev.comm.tid = pid; - process(&ev); + process(&ev, session); } closedir(tasks); @@ -86,7 +88,9 @@ out_failure: } static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, - int (*process)(event_t *event)) + int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session) { char filename[PATH_MAX]; FILE *fp; @@ -141,7 +145,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, ev.mmap.pid = tgid; ev.mmap.tid = pid; - process(&ev); + process(&ev, session); } } @@ -149,15 +153,20 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, return 0; } -int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)) +int event__synthesize_thread(pid_t pid, + int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session) { - pid_t tgid = event__synthesize_comm(pid, 1, process); + pid_t tgid = event__synthesize_comm(pid, 1, process, session); if (tgid == -1) return -1; - return event__synthesize_mmap_events(pid, tgid, process); + return event__synthesize_mmap_events(pid, tgid, process, session); } -void event__synthesize_threads(int (*process)(event_t *event)) +void event__synthesize_threads(int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session) { DIR *proc; struct dirent dirent, *next; @@ -171,7 +180,7 @@ void event__synthesize_threads(int (*process)(event_t *event)) if (*end) /* only interested in proper numerical dirents */ continue; - event__synthesize_thread(pid, process); + event__synthesize_thread(pid, process, session); } closedir(proc); @@ -182,7 +191,7 @@ int event__cwdlen; struct events_stats event__stats; -int event__process_comm(event_t *self) +int event__process_comm(event_t *self, struct perf_session *session __used) { struct thread *thread = threads__findnew(self->comm.pid); @@ -196,14 +205,14 @@ int event__process_comm(event_t *self) return 0; } -int event__process_lost(event_t *self) +int event__process_lost(event_t *self, struct perf_session *session __used) { dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost); event__stats.lost += self->lost.lost; return 0; } -int event__process_mmap(event_t *self) +int event__process_mmap(event_t *self, struct perf_session *session __used) { struct thread *thread = threads__findnew(self->mmap.pid); struct map *map = map__new(&self->mmap, MAP__FUNCTION, @@ -224,7 +233,7 @@ int event__process_mmap(event_t *self) return 0; } -int event__process_task(event_t *self) +int event__process_task(event_t *self, struct perf_session *session __used) { struct thread *thread = threads__findnew(self->fork.pid); struct thread *parent = threads__findnew(self->fork.ppid); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 51a96c2effde..6b6429b63da3 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -156,18 +156,25 @@ struct symbol *map__find_symbol_by_name(struct map *self, const char *name, void map__fixup_start(struct map *self); void map__fixup_end(struct map *self); -int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)); -void event__synthesize_threads(int (*process)(event_t *event)); +struct perf_session; + +int event__synthesize_thread(pid_t pid, + int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session); +void event__synthesize_threads(int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session); extern char *event__cwd; extern int event__cwdlen; extern struct events_stats event__stats; extern unsigned long event__total[PERF_RECORD_MAX]; -int event__process_comm(event_t *self); -int event__process_lost(event_t *self); -int event__process_mmap(event_t *self); -int event__process_task(event_t *self); +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); struct addr_location; int event__preprocess_sample(const event_t *self, struct addr_location *al, -- cgit v1.2.3 From 301a0b020210360c6e441c7765521248bc87d58e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 13 Dec 2009 19:50:25 -0200 Subject: perf session: Ditch register_perf_file_handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the event_ops to perf_session__process_events instead. Also move the event_ops definition to session.h, starting to move things around to their right place, trimming the many unneeded headers we have. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260741029-4430-2-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar --- tools/perf/Makefile | 1 - tools/perf/builtin-annotate.c | 10 +++++----- tools/perf/builtin-buildid-list.c | 1 - tools/perf/builtin-kmem.c | 8 +++----- tools/perf/builtin-report.c | 7 ++----- tools/perf/builtin-sched.c | 7 +++---- tools/perf/builtin-timechart.c | 9 ++++----- tools/perf/builtin-trace.c | 8 +++----- tools/perf/util/data_map.c | 41 +++++++++++++++++---------------------- tools/perf/util/data_map.h | 32 ------------------------------ tools/perf/util/header.c | 2 +- tools/perf/util/session.c | 3 ++- tools/perf/util/session.h | 26 ++++++++++++++++++++++++- 13 files changed, 66 insertions(+), 89 deletions(-) delete mode 100644 tools/perf/util/data_map.h (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 406999668cab..a4cb79255383 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -370,7 +370,6 @@ LIB_H += util/values.h LIB_H += util/sort.h LIB_H += util/hist.h LIB_H += util/thread.h -LIB_H += util/data_map.h LIB_H += util/probe-finder.h LIB_H += util/probe-event.h diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 2e418b9fc1c4..43e3bb354442 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -26,7 +26,6 @@ #include "util/sort.h" #include "util/hist.h" #include "util/session.h" -#include "util/data_map.h" static char const *input_name = "perf.data"; @@ -454,7 +453,7 @@ static void find_annotations(void) } } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_sample_event = process_sample_event, .process_mmap_event = event__process_mmap, .process_comm_event = event__process_comm, @@ -463,7 +462,8 @@ static struct perf_file_handler file_handler = { static int __cmd_annotate(void) { - struct perf_session *session = perf_session__new(input_name, O_RDONLY, force); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + force); struct thread *idle; int ret; @@ -471,9 +471,9 @@ static int __cmd_annotate(void) return -ENOMEM; idle = register_idle_thread(); - register_perf_file_handler(&file_handler); - ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, &event_ops, 0, + &event__cwdlen, &event__cwd); if (ret) goto out_delete; diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index bfd16a1594e4..2629f76d95fe 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -9,7 +9,6 @@ #include "builtin.h" #include "perf.h" #include "util/cache.h" -#include "util/data_map.h" #include "util/debug.h" #include "util/parse-options.h" #include "util/session.h" diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 101b2682b4df..6f74bd8d20e6 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -12,7 +12,6 @@ #include "util/trace-event.h" #include "util/debug.h" -#include "util/data_map.h" #include @@ -359,7 +358,7 @@ static int sample_type_check(u64 type) return 0; } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_sample_event = process_sample_event, .process_comm_event = event__process_comm, .sample_type_check = sample_type_check, @@ -374,9 +373,8 @@ static int read_events(void) return -ENOMEM; register_idle_thread(); - register_perf_file_handler(&file_handler); - - err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, &event_ops, 0, + &event__cwdlen, &event__cwd); perf_session__delete(session); return err; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index dcd8fedc298c..c203eaf73a2f 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -27,7 +27,6 @@ #include "util/parse-options.h" #include "util/parse-events.h" -#include "util/data_map.h" #include "util/thread.h" #include "util/sort.h" #include "util/hist.h" @@ -748,7 +747,7 @@ static int sample_type_check(u64 type) return 0; } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_sample_event = process_sample_event, .process_mmap_event = event__process_mmap, .process_comm_event = process_comm_event, @@ -776,9 +775,7 @@ static int __cmd_report(void) if (show_threads) perf_read_values_init(&show_threads_values); - register_perf_file_handler(&file_handler); - - ret = perf_session__process_events(session, full_paths, + ret = perf_session__process_events(session, &event_ops, full_paths, &event__cwdlen, &event__cwd); if (ret) goto out_delete; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 48ab283ed86b..b5b447236261 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -12,7 +12,6 @@ #include "util/trace-event.h" #include "util/debug.h" -#include "util/data_map.h" #include @@ -1656,7 +1655,7 @@ static int sample_type_check(u64 type) return 0; } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_sample_event = process_sample_event, .process_comm_event = event__process_comm, .process_lost_event = process_lost_event, @@ -1672,9 +1671,9 @@ static int read_events(void) return -ENOMEM; register_idle_thread(); - register_perf_file_handler(&file_handler); - err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, &event_ops, 0, + &event__cwdlen, &event__cwd); perf_session__delete(session); return err; } diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index db6caae1a404..4b95cec6b4c5 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -30,7 +30,7 @@ #include "util/parse-options.h" #include "util/parse-events.h" #include "util/event.h" -#include "util/data_map.h" +#include "util/session.h" #include "util/svghelper.h" static char const *input_name = "perf.data"; @@ -1046,7 +1046,7 @@ static int sample_type_check(u64 type) return 0; } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_comm_event = process_comm_event, .process_fork_event = process_fork_event, .process_exit_event = process_exit_event, @@ -1062,9 +1062,8 @@ static int __cmd_timechart(void) if (session == NULL) return -ENOMEM; - register_perf_file_handler(&file_handler); - - ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, &event_ops, 0, + &event__cwdlen, &event__cwd); if (ret) goto out_delete; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 3057e1d387b9..c404dece950d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -57,7 +57,6 @@ static int cleanup_scripting(void) #include "util/debug.h" #include "util/trace-event.h" -#include "util/data_map.h" #include "util/exec_cmd.h" static char const *input_name = "perf.data"; @@ -118,7 +117,7 @@ static int sample_type_check(u64 type) return 0; } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_sample_event = process_sample_event, .process_comm_event = event__process_comm, .sample_type_check = sample_type_check, @@ -127,9 +126,8 @@ static struct perf_file_handler file_handler = { static int __cmd_trace(struct perf_session *session) { register_idle_thread(); - register_perf_file_handler(&file_handler); - - return perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + return perf_session__process_events(session, &event_ops, 0, + &event__cwdlen, &event__cwd); } struct script_spec { diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 22bcdfeff55c..ba5bcfa1f908 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -1,10 +1,8 @@ -#include "data_map.h" #include "symbol.h" #include "util.h" #include "debug.h" +#include "session.h" - -static struct perf_file_handler *curr_handler; static unsigned long mmap_window = 32; static char __cwd[PATH_MAX]; @@ -15,7 +13,7 @@ static int process_event_stub(event_t *event __used, return 0; } -void register_perf_file_handler(struct perf_file_handler *handler) +static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) { if (!handler->process_sample_event) handler->process_sample_event = process_event_stub; @@ -35,8 +33,6 @@ void register_perf_file_handler(struct perf_file_handler *handler) handler->process_throttle_event = process_event_stub; if (!handler->process_unthrottle_event) handler->process_unthrottle_event = process_event_stub; - - curr_handler = handler; } static const char *event__name[] = { @@ -63,6 +59,7 @@ void event__print_totals(void) } static int process_event(event_t *event, struct perf_session *session, + struct perf_event_ops *ops, unsigned long offset, unsigned long head) { trace_event(event); @@ -78,25 +75,25 @@ static int process_event(event_t *event, struct perf_session *session, switch (event->header.type) { case PERF_RECORD_SAMPLE: - return curr_handler->process_sample_event(event, session); + return ops->process_sample_event(event, session); case PERF_RECORD_MMAP: - return curr_handler->process_mmap_event(event, session); + return ops->process_mmap_event(event, session); case PERF_RECORD_COMM: - return curr_handler->process_comm_event(event, session); + return ops->process_comm_event(event, session); case PERF_RECORD_FORK: - return curr_handler->process_fork_event(event, session); + return ops->process_fork_event(event, session); case PERF_RECORD_EXIT: - return curr_handler->process_exit_event(event, session); + return ops->process_exit_event(event, session); case PERF_RECORD_LOST: - return curr_handler->process_lost_event(event, session); + return ops->process_lost_event(event, session); case PERF_RECORD_READ: - return curr_handler->process_read_event(event, session); + return ops->process_read_event(event, session); case PERF_RECORD_THROTTLE: - return curr_handler->process_throttle_event(event, session); + return ops->process_throttle_event(event, session); case PERF_RECORD_UNTHROTTLE: - return curr_handler->process_unthrottle_event(event, session); + return ops->process_unthrottle_event(event, session); default: - curr_handler->total_unknown++; + ops->total_unknown++; return -1; } } @@ -131,6 +128,7 @@ out: } int perf_session__process_events(struct perf_session *self, + struct perf_event_ops *ops, int full_paths, int *cwdlen, char **cwd) { int err; @@ -142,10 +140,7 @@ int perf_session__process_events(struct perf_session *self, uint32_t size; char *buf; - if (curr_handler == NULL) { - pr_debug("Forgot to register perf file handler\n"); - return -EINVAL; - } + perf_event_ops__fill_defaults(ops); page_size = getpagesize(); @@ -153,8 +148,8 @@ int perf_session__process_events(struct perf_session *self, sample_type = perf_header__sample_type(&self->header); err = -EINVAL; - if (curr_handler->sample_type_check && - curr_handler->sample_type_check(sample_type) < 0) + if (ops->sample_type_check && + ops->sample_type_check(sample_type) < 0) goto out_err; if (!full_paths) { @@ -210,7 +205,7 @@ more: (void *)(long)event->header.size, event->header.type); - if (!size || process_event(event, self, offset, head) < 0) { + if (!size || process_event(event, self, ops, offset, head) < 0) { dump_printf("%p [%p]: skipping unknown header type: %d\n", (void *)(offset + head), diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h deleted file mode 100644 index 6d4ae52bc07b..000000000000 --- a/tools/perf/util/data_map.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __PERF_DATAMAP_H -#define __PERF_DATAMAP_H - -#include "event.h" -#include "header.h" -#include "session.h" - -struct perf_session; - -typedef int (*event_type_handler_t)(event_t *self, - struct perf_session *session); - -struct perf_file_handler { - event_type_handler_t process_sample_event; - event_type_handler_t process_mmap_event; - event_type_handler_t process_comm_event; - event_type_handler_t process_fork_event; - event_type_handler_t process_exit_event; - event_type_handler_t process_lost_event; - event_type_handler_t process_read_event; - event_type_handler_t process_throttle_event; - event_type_handler_t process_unthrottle_event; - int (*sample_type_check)(u64 sample_type); - unsigned long total_unknown; -}; - -void register_perf_file_handler(struct perf_file_handler *handler); -int perf_session__process_events(struct perf_session *self, - int full_paths, int *cwdlen, char **cwd); -int perf_header__read_build_ids(int input, u64 offset, u64 file_size); - -#endif diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index f2e8d8715111..8a0bca55106f 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -8,8 +8,8 @@ #include "header.h" #include "../perf.h" #include "trace-event.h" +#include "session.h" #include "symbol.h" -#include "data_map.h" #include "debug.h" /* diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 707ce1cb1621..39766868d43a 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -48,7 +48,8 @@ out_close: return -1; } -struct perf_session *perf_session__new(const char *filename, int mode, bool force) +struct perf_session *perf_session__new(const char *filename, int mode, + bool force) { size_t len = strlen(filename) + 1; struct perf_session *self = zalloc(sizeof(*self) + len); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index f3699c8c8ed4..7a4c32c545f4 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -1,6 +1,7 @@ #ifndef __PERF_SESSION_H #define __PERF_SESSION_H +#include "event.h" #include "header.h" struct perf_session { @@ -10,7 +11,30 @@ struct perf_session { char filename[0]; }; -struct perf_session *perf_session__new(const char *filename, int mode, bool force); +typedef int (*event_op)(event_t *self, struct perf_session *session); + +struct perf_event_ops { + event_op process_sample_event; + event_op process_mmap_event; + event_op process_comm_event; + event_op process_fork_event; + event_op process_exit_event; + event_op process_lost_event; + event_op process_read_event; + event_op process_throttle_event; + event_op process_unthrottle_event; + int (*sample_type_check)(u64 sample_type); + unsigned long total_unknown; +}; + +struct perf_session *perf_session__new(const char *filename, int mode, + bool force); void perf_session__delete(struct perf_session *self); +int perf_session__process_events(struct perf_session *self, + struct perf_event_ops *event_ops, + int full_paths, int *cwdlen, char **cwd); + +int perf_header__read_build_ids(int input, u64 offset, u64 file_size); + #endif /* __PERF_SESSION_H */ -- cgit v1.2.3 From ec913369733923dbfd6bdff5953a918107059701 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 13 Dec 2009 19:50:27 -0200 Subject: perf session: Reduce the number of parms to perf_session__process_events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By having the cwd/cwdlen in the perf_session struct and full_paths in perf_event_ops. Now its just a matter of passing the ops. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260741029-4430-4-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 3 +-- tools/perf/builtin-kmem.c | 3 +-- tools/perf/builtin-report.c | 6 ++---- tools/perf/builtin-sched.c | 3 +-- tools/perf/builtin-timechart.c | 3 +-- tools/perf/builtin-trace.c | 3 +-- tools/perf/util/data_map.c | 32 ++++++++++++++++---------------- tools/perf/util/event.c | 8 +++----- tools/perf/util/session.c | 4 ++++ tools/perf/util/session.h | 7 +++++-- 10 files changed, 35 insertions(+), 37 deletions(-) (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 93d765a746f2..a931b133f3ac 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -469,8 +469,7 @@ static int __cmd_annotate(void) if (session == NULL) return -ENOMEM; - ret = perf_session__process_events(session, &event_ops, 0, - &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, &event_ops); if (ret) goto out_delete; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 37a849906afe..237155fa756b 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -372,8 +372,7 @@ static int read_events(void) if (session == NULL) return -ENOMEM; - err = perf_session__process_events(session, &event_ops, 0, - &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, &event_ops); perf_session__delete(session); return err; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 4b37ac4f128b..26b947860948 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -39,7 +39,6 @@ static struct strlist *dso_list, *comm_list, *sym_list; static int force; -static int full_paths; static int show_nr_samples; static int show_threads; @@ -771,8 +770,7 @@ static int __cmd_report(void) if (show_threads) perf_read_values_init(&show_threads_values); - ret = perf_session__process_events(session, &event_ops, full_paths, - &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, &event_ops); if (ret) goto out_delete; @@ -877,7 +875,7 @@ static const struct option options[] = { "pretty printing style key: normal raw"), OPT_STRING('s', "sort", &sort_order, "key[,key2...]", "sort by key(s): pid, comm, dso, symbol, parent"), - OPT_BOOLEAN('P', "full-paths", &full_paths, + OPT_BOOLEAN('P', "full-paths", &event_ops.full_paths, "Don't shorten the pathnames taking into account the cwd"), OPT_STRING('p', "parent", &parent_pattern, "regex", "regex filter to identify parent, see: '--sort parent'"), diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 847ed51248b1..1e4e508339a8 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1670,8 +1670,7 @@ static int read_events(void) if (session == NULL) return -ENOMEM; - err = perf_session__process_events(session, &event_ops, 0, - &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, &event_ops); perf_session__delete(session); return err; } diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 4b95cec6b4c5..b5211facddc6 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1062,8 +1062,7 @@ static int __cmd_timechart(void) if (session == NULL) return -ENOMEM; - ret = perf_session__process_events(session, &event_ops, 0, - &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, &event_ops); if (ret) goto out_delete; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 40cb896581dd..b7eb3fcc224e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -125,8 +125,7 @@ static struct perf_event_ops event_ops = { static int __cmd_trace(struct perf_session *session) { - return perf_session__process_events(session, &event_ops, 0, - &event__cwdlen, &event__cwd); + return perf_session__process_events(session, &event_ops); } struct script_spec { diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 36e3bfe73196..ba2eb2ce018a 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -4,9 +4,6 @@ #include "thread.h" #include "session.h" -static unsigned long mmap_window = 32; -static char __cwd[PATH_MAX]; - static int process_event_stub(event_t *event __used, struct perf_session *session __used) { @@ -141,8 +138,7 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se } int perf_session__process_events(struct perf_session *self, - struct perf_event_ops *ops, - int full_paths, int *cwdlen, char **cwd) + struct perf_event_ops *ops) { int err; unsigned long head, shift; @@ -168,17 +164,21 @@ int perf_session__process_events(struct perf_session *self, ops->sample_type_check(sample_type) < 0) goto out_err; - if (!full_paths) { - if (getcwd(__cwd, sizeof(__cwd)) == NULL) { - pr_err("failed to get the current directory\n"); + if (!ops->full_paths) { + char bf[PATH_MAX]; + + if (getcwd(bf, sizeof(bf)) == NULL) { err = -errno; +out_getcwd_err: + pr_err("failed to get the current directory\n"); goto out_err; } - *cwd = __cwd; - *cwdlen = strlen(*cwd); - } else { - *cwd = NULL; - *cwdlen = 0; + self->cwd = strdup(bf); + if (self->cwd == NULL) { + err = -ENOMEM; + goto out_getcwd_err; + } + self->cwdlen = strlen(self->cwd); } shift = page_size * (head / page_size); @@ -186,7 +186,7 @@ int perf_session__process_events(struct perf_session *self, head -= shift; remap: - buf = mmap(NULL, page_size * mmap_window, PROT_READ, + buf = mmap(NULL, page_size * self->mmap_window, PROT_READ, MAP_SHARED, self->fd, offset); if (buf == MAP_FAILED) { pr_err("failed to mmap file\n"); @@ -201,12 +201,12 @@ more: if (!size) size = 8; - if (head + event->header.size >= page_size * mmap_window) { + if (head + event->header.size >= page_size * self->mmap_window) { int munmap_ret; shift = page_size * (head / page_size); - munmap_ret = munmap(buf, page_size * mmap_window); + munmap_ret = munmap(buf, page_size * self->mmap_window); assert(munmap_ret == 0); offset += shift; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index e2c489533c6d..40d8d842a21f 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1,6 +1,7 @@ #include #include "event.h" #include "debug.h" +#include "session.h" #include "string.h" #include "thread.h" @@ -186,9 +187,6 @@ void event__synthesize_threads(int (*process)(event_t *event, closedir(proc); } -char *event__cwd; -int event__cwdlen; - struct events_stats event__stats; int event__process_comm(event_t *self, struct perf_session *session __used) @@ -212,11 +210,11 @@ int event__process_lost(event_t *self, struct perf_session *session __used) return 0; } -int event__process_mmap(event_t *self, struct perf_session *session __used) +int event__process_mmap(event_t *self, struct perf_session *session) { struct thread *thread = threads__findnew(self->mmap.pid); struct map *map = map__new(&self->mmap, MAP__FUNCTION, - event__cwd, event__cwdlen); + session->cwd, session->cwdlen); dump_printf(" %d/%d: [%p(%p) @ %p]: %s\n", self->mmap.pid, self->mmap.tid, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 39766868d43a..534a8770ee7f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -61,6 +61,9 @@ struct perf_session *perf_session__new(const char *filename, int mode, goto out_delete; memcpy(self->filename, filename, len); + self->mmap_window = 32; + self->cwd = NULL; + self->cwdlen = 0; if (mode == O_RDONLY && perf_session__open(self, force) < 0) { perf_session__delete(self); @@ -77,5 +80,6 @@ void perf_session__delete(struct perf_session *self) { perf_header__exit(&self->header); close(self->fd); + free(self->cwd); free(self); } diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7a4c32c545f4..1e0da9ca31aa 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -7,7 +7,10 @@ struct perf_session { struct perf_header header; unsigned long size; + unsigned long mmap_window; int fd; + int cwdlen; + char *cwd; char filename[0]; }; @@ -25,6 +28,7 @@ struct perf_event_ops { event_op process_unthrottle_event; int (*sample_type_check)(u64 sample_type); unsigned long total_unknown; + bool full_paths; }; struct perf_session *perf_session__new(const char *filename, int mode, @@ -32,8 +36,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, void perf_session__delete(struct perf_session *self); int perf_session__process_events(struct perf_session *self, - struct perf_event_ops *event_ops, - int full_paths, int *cwdlen, char **cwd); + struct perf_event_ops *event_ops); int perf_header__read_build_ids(int input, u64 offset, u64 file_size); -- cgit v1.2.3 From 4aa65636411ccb12f006a6ad593930655c445ff6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 13 Dec 2009 19:50:29 -0200 Subject: perf session: Move kmaps to perf_session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is still some more work to do to disentangle map creation from DSO loading, but this happens only for the kernel, and for the early adopters of perf diff, where this disentanglement matters most, we'll be testing different kernels, so no problem here. Further clarification: right now we create the kernel maps for the various modules and discontiguous kernel text maps when loading the DSO, we should do it as a two step process, first creating the maps, for multiple mappings with the same DSO store, then doing the dso load just once, for the first hit on one of the maps sharing this DSO backing store. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260741029-4430-6-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-buildid-list.c | 4 +- tools/perf/builtin-kmem.c | 41 +++++++++--------- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-report.c | 14 +++--- tools/perf/builtin-sched.c | 4 +- tools/perf/builtin-timechart.c | 3 +- tools/perf/builtin-top.c | 4 +- tools/perf/builtin-trace.c | 2 +- tools/perf/util/event.c | 13 +++--- tools/perf/util/event.h | 10 +++-- tools/perf/util/map.c | 14 +++--- tools/perf/util/session.c | 19 ++++++--- tools/perf/util/session.h | 6 ++- tools/perf/util/symbol.c | 89 +++++++++++++++++++-------------------- tools/perf/util/symbol.h | 11 ++--- tools/perf/util/thread.c | 3 +- tools/perf/util/thread.h | 11 ++--- 18 files changed, 134 insertions(+), 118 deletions(-) (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 795f865c1366..e44c54c79be4 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -463,7 +463,7 @@ static struct perf_event_ops event_ops = { static int __cmd_annotate(void) { struct perf_session *session = perf_session__new(input_name, O_RDONLY, - force); + force, &symbol_conf); int ret; if (session == NULL) diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 2629f76d95fe..7c36e4b2eccf 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -54,8 +54,8 @@ static int perf_file_section__process_buildids(struct perf_file_section *self, static int __cmd_buildid_list(void) { int err = -1; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, force); - + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + force, NULL); if (session == NULL) return -1; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index de194958fe6e..e79ecbc17181 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -364,19 +364,6 @@ static struct perf_event_ops event_ops = { .sample_type_check = sample_type_check, }; -static int read_events(void) -{ - int err; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); - - if (session == NULL) - return -ENOMEM; - - err = perf_session__process_events(session, &event_ops); - perf_session__delete(session); - return err; -} - static double fragmentation(unsigned long n_req, unsigned long n_alloc) { if (n_alloc == 0) @@ -385,7 +372,8 @@ static double fragmentation(unsigned long n_req, unsigned long n_alloc) return 100.0 - (100.0 * n_req / n_alloc); } -static void __print_result(struct rb_root *root, int n_lines, int is_caller) +static void __print_result(struct rb_root *root, struct perf_session *session, + int n_lines, int is_caller) { struct rb_node *next; @@ -406,7 +394,7 @@ static void __print_result(struct rb_root *root, int n_lines, int is_caller) if (is_caller) { addr = data->call_site; if (!raw_ip) - sym = map_groups__find_function(kmaps, addr, NULL); + sym = map_groups__find_function(&session->kmaps, session, addr, NULL); } else addr = data->ptr; @@ -447,12 +435,12 @@ static void print_summary(void) printf("Cross CPU allocations: %lu/%lu\n", nr_cross_allocs, nr_allocs); } -static void print_result(void) +static void print_result(struct perf_session *session) { if (caller_flag) - __print_result(&root_caller_sorted, caller_lines, 1); + __print_result(&root_caller_sorted, session, caller_lines, 1); if (alloc_flag) - __print_result(&root_alloc_sorted, alloc_lines, 0); + __print_result(&root_alloc_sorted, session, alloc_lines, 0); print_summary(); } @@ -520,12 +508,21 @@ static void sort_result(void) static int __cmd_kmem(void) { + int err; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, NULL); + if (session == NULL) + return -ENOMEM; + setup_pager(); - read_events(); + err = perf_session__process_events(session, &event_ops); + if (err != 0) + goto out_delete; sort_result(); - print_result(); - - return 0; + print_result(session); +out_delete: + perf_session__delete(session); + return err; } static const char * const kmem_usage[] = { diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index b7e15a1b1ec2..a66a58d52818 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -442,7 +442,7 @@ static int __cmd_record(int argc, const char **argv) exit(-1); } - session = perf_session__new(output_name, O_WRONLY, force); + session = perf_session__new(output_name, O_WRONLY, force, 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 efa8147b8991..3487224670a8 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -414,6 +414,7 @@ static int call__match(struct symbol *sym) } static struct symbol **resolve_callchain(struct thread *thread, + struct perf_session *session, struct ip_callchain *chain, struct symbol **parent) { @@ -447,8 +448,8 @@ static struct symbol **resolve_callchain(struct thread *thread, continue; } - thread__find_addr_location(thread, cpumode, MAP__FUNCTION, - ip, &al, NULL); + thread__find_addr_location(thread, session, cpumode, + MAP__FUNCTION, ip, &al, NULL); if (al.sym != NULL) { if (sort__has_parent && !*parent && call__match(al.sym)) @@ -467,6 +468,7 @@ static struct symbol **resolve_callchain(struct thread *thread, */ static int hist_entry__add(struct addr_location *al, + struct perf_session *session, struct ip_callchain *chain, u64 count) { struct symbol **syms = NULL, *parent = NULL; @@ -474,7 +476,7 @@ static int hist_entry__add(struct addr_location *al, struct hist_entry *he; if ((sort__has_parent || callchain) && chain) - syms = resolve_callchain(al->thread, chain, &parent); + syms = resolve_callchain(al->thread, session, chain, &parent); he = __hist_entry__add(al, parent, count, &hit); if (he == NULL) @@ -650,7 +652,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - thread__find_addr_location(thread, cpumode, + thread__find_addr_location(thread, session, cpumode, MAP__FUNCTION, data.ip, &al, NULL); /* * We have to do this here as we may have a dso with no symbol hit that @@ -669,7 +671,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name)) return 0; - if (hist_entry__add(&al, data.callchain, data.period)) { + if (hist_entry__add(&al, session, data.callchain, data.period)) { pr_debug("problem incrementing symbol count, skipping event\n"); return -1; } @@ -763,7 +765,7 @@ static int __cmd_report(void) int ret; struct perf_session *session; - session = perf_session__new(input_name, O_RDONLY, force); + session = perf_session__new(input_name, O_RDONLY, force, &symbol_conf); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 8d58d9e07a7b..bce05dff6dfe 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1679,8 +1679,8 @@ static struct perf_event_ops event_ops = { static int read_events(void) { int err; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); - + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, NULL); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index b5211facddc6..27018531404b 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1056,7 +1056,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); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, NULL); int ret; if (session == NULL) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0f7a4da2924c..3b212bb2e4df 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1162,8 +1162,8 @@ 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); - + struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, + &symbol_conf); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d76532375054..9d89ae423ca5 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -318,7 +318,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) setup_pager(); - session = perf_session__new(input_name, O_RDONLY, 0); + session = perf_session__new(input_name, O_RDONLY, 0, NULL); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2d09c29b3a6c..222efb1fc3bd 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -256,7 +256,8 @@ int event__process_task(event_t *self, struct perf_session *session) return 0; } -void thread__find_addr_location(struct thread *self, u8 cpumode, +void thread__find_addr_location(struct thread *self, + struct perf_session *session, u8 cpumode, enum map_type type, u64 addr, struct addr_location *al, symbol_filter_t filter) @@ -268,7 +269,7 @@ void thread__find_addr_location(struct thread *self, u8 cpumode, if (cpumode & PERF_RECORD_MISC_KERNEL) { al->level = 'k'; - mg = kmaps; + mg = &session->kmaps; } else if (cpumode & PERF_RECORD_MISC_USER) al->level = '.'; else { @@ -289,14 +290,14 @@ try_again: * "[vdso]" dso, but for now lets use the old trick of looking * in the whole kernel symbol list. */ - if ((long long)al->addr < 0 && mg != kmaps) { - mg = kmaps; + if ((long long)al->addr < 0 && mg != &session->kmaps) { + mg = &session->kmaps; goto try_again; } al->sym = NULL; } else { al->addr = al->map->map_ip(al->map, al->addr); - al->sym = map__find_symbol(al->map, al->addr, filter); + al->sym = map__find_symbol(al->map, session, al->addr, filter); } } @@ -311,7 +312,7 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - thread__find_addr_location(thread, cpumode, MAP__FUNCTION, + thread__find_addr_location(thread, session, cpumode, MAP__FUNCTION, self->ip.ip, al, filter); dump_printf(" ...... dso: %s\n", al->map ? al->map->dso->long_name : diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index bb090257570e..035ecf3c25cc 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -149,15 +149,17 @@ void map__delete(struct map *self); struct map *map__clone(struct map *self); int map__overlap(struct map *l, struct map *r); size_t map__fprintf(struct map *self, FILE *fp); -struct symbol *map__find_symbol(struct map *self, u64 addr, - symbol_filter_t filter); + +struct perf_session; + +struct symbol *map__find_symbol(struct map *self, struct perf_session *session, + u64 addr, symbol_filter_t filter); struct symbol *map__find_symbol_by_name(struct map *self, const char *name, + struct perf_session *session, symbol_filter_t filter); void map__fixup_start(struct map *self); void map__fixup_end(struct map *self); -struct perf_session; - int event__synthesize_thread(pid_t pid, int (*process)(event_t *event, struct perf_session *session), diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 76bdca640a9b..8b3dd467adb5 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -104,10 +104,11 @@ void map__fixup_end(struct map *self) #define DSO__DELETED "(deleted)" -static int map__load(struct map *self, symbol_filter_t filter) +static int map__load(struct map *self, struct perf_session *session, + symbol_filter_t filter) { const char *name = self->dso->long_name; - int nr = dso__load(self->dso, self, filter); + int nr = dso__load(self->dso, self, session, filter); if (nr < 0) { if (self->dso->has_build_id) { @@ -143,19 +144,20 @@ static int map__load(struct map *self, symbol_filter_t filter) return 0; } -struct symbol *map__find_symbol(struct map *self, u64 addr, - symbol_filter_t filter) +struct symbol *map__find_symbol(struct map *self, struct perf_session *session, + u64 addr, symbol_filter_t filter) { - if (!dso__loaded(self->dso, self->type) && map__load(self, filter) < 0) + if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0) return NULL; return dso__find_symbol(self->dso, self->type, addr); } struct symbol *map__find_symbol_by_name(struct map *self, const char *name, + struct perf_session *session, symbol_filter_t filter) { - if (!dso__loaded(self->dso, self->type) && map__load(self, filter) < 0) + if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0) return NULL; if (!dso__sorted_by_name(self->dso, self->type)) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 09836a537fc5..fe87a2f2e5a5 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -49,7 +49,7 @@ out_close: } struct perf_session *perf_session__new(const char *filename, int mode, - bool force) + bool force, struct symbol_conf *conf) { size_t len = filename ? strlen(filename) + 1 : 0; struct perf_session *self = zalloc(sizeof(*self) + len); @@ -58,7 +58,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, goto out; if (perf_header__init(&self->header) < 0) - goto out_delete; + goto out_free; memcpy(self->filename, filename, len); self->threads = RB_ROOT; @@ -66,16 +66,21 @@ struct perf_session *perf_session__new(const char *filename, int mode, self->mmap_window = 32; self->cwd = NULL; self->cwdlen = 0; + map_groups__init(&self->kmaps); - if (mode == O_RDONLY && perf_session__open(self, force) < 0) { - perf_session__delete(self); - self = NULL; - } + if (perf_session__create_kernel_maps(self, conf) < 0) + goto out_delete; + + if (mode == O_RDONLY && perf_session__open(self, force) < 0) + goto out_delete; out: return self; -out_delete: +out_free: free(self); return NULL; +out_delete: + perf_session__delete(self); + return NULL; } void perf_session__delete(struct perf_session *self) diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 1dbef7cdd489..20b2c9cc834b 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -3,19 +3,23 @@ #include "event.h" #include "header.h" +#include "thread.h" #include struct thread; +struct symbol_conf; struct perf_session { struct perf_header header; unsigned long size; unsigned long mmap_window; + struct map_groups kmaps; struct rb_root threads; struct thread *last_match; int fd; int cwdlen; char *cwd; + bool use_modules; char filename[0]; }; @@ -37,7 +41,7 @@ struct perf_event_ops { }; struct perf_session *perf_session__new(const char *filename, int mode, - bool force); + bool force, struct symbol_conf *conf); void perf_session__delete(struct perf_session *self); int perf_session__process_events(struct perf_session *self, diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index d3d9fed74f1d..185b9eec192b 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1,5 +1,6 @@ #include "util.h" #include "../perf.h" +#include "session.h" #include "string.h" #include "symbol.h" #include "thread.h" @@ -31,7 +32,7 @@ enum dso_origin { static void dsos__add(struct list_head *head, struct dso *dso); static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); static int dso__load_kernel_sym(struct dso *self, struct map *map, - struct map_groups *mg, symbol_filter_t filter); + struct perf_session *session, symbol_filter_t filter); unsigned int symbol__priv_size; static int vmlinux_path__nr_entries; static char **vmlinux_path; @@ -41,9 +42,6 @@ static struct symbol_conf symbol_conf__defaults = { .try_vmlinux_path = true, }; -static struct map_groups kmaps_mem; -struct map_groups *kmaps = &kmaps_mem; - bool dso__loaded(const struct dso *self, enum map_type type) { return self->loaded & (1 << type); @@ -456,7 +454,7 @@ out_failure: * the original ELF section names vmlinux have. */ static int dso__split_kallsyms(struct dso *self, struct map *map, - struct map_groups *mg, symbol_filter_t filter) + struct perf_session *session, symbol_filter_t filter) { struct map *curr_map = map; struct symbol *pos; @@ -473,13 +471,13 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, module = strchr(pos->name, '\t'); if (module) { - if (!mg->use_modules) + if (!session->use_modules) goto discard_symbol; *module++ = '\0'; if (strcmp(self->name, module)) { - curr_map = map_groups__find_by_name(mg, map->type, module); + curr_map = map_groups__find_by_name(&session->kmaps, map->type, module); if (curr_map == NULL) { pr_debug("/proc/{kallsyms,modules} " "inconsistency!\n"); @@ -510,7 +508,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, } curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; - map_groups__insert(mg, curr_map); + map_groups__insert(&session->kmaps, curr_map); ++kernel_range; } @@ -531,7 +529,7 @@ discard_symbol: rb_erase(&pos->rb_node, root); static int dso__load_kallsyms(struct dso *self, struct map *map, - struct map_groups *mg, symbol_filter_t filter) + struct perf_session *session, symbol_filter_t filter) { if (dso__load_all_kallsyms(self, map) < 0) return -1; @@ -539,14 +537,7 @@ static int dso__load_kallsyms(struct dso *self, struct map *map, symbols__fixup_end(&self->symbols[map->type]); self->origin = DSO__ORIG_KERNEL; - return dso__split_kallsyms(self, map, mg, filter); -} - -size_t kernel_maps__fprintf(FILE *fp) -{ - size_t printed = fprintf(fp, "Kernel maps:\n"); - printed += map_groups__fprintf_maps(kmaps, fp); - return printed + fprintf(fp, "END kernel maps\n"); + return dso__split_kallsyms(self, map, session, filter); } static int dso__load_perf_map(struct dso *self, struct map *map, @@ -873,7 +864,7 @@ static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type } static int dso__load_sym(struct dso *self, struct map *map, - struct map_groups *mg, const char *name, int fd, + struct perf_session *session, const char *name, int fd, symbol_filter_t filter, int kernel, int kmodule) { struct map *curr_map = map; @@ -977,7 +968,7 @@ static int dso__load_sym(struct dso *self, struct map *map, snprintf(dso_name, sizeof(dso_name), "%s%s", self->short_name, section_name); - curr_map = map_groups__find_by_name(mg, map->type, dso_name); + curr_map = map_groups__find_by_name(&session->kmaps, map->type, dso_name); if (curr_map == NULL) { u64 start = sym.st_value; @@ -996,7 +987,7 @@ static int dso__load_sym(struct dso *self, struct map *map, curr_map->map_ip = identity__map_ip; curr_map->unmap_ip = identity__map_ip; curr_dso->origin = DSO__ORIG_KERNEL; - map_groups__insert(kmaps, curr_map); + map_groups__insert(&session->kmaps, curr_map); dsos__add(&dsos__kernel, curr_dso); } else curr_dso = curr_map->dso; @@ -1211,7 +1202,8 @@ char dso__symtab_origin(const struct dso *self) return origin[self->origin]; } -int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) +int dso__load(struct dso *self, struct map *map, struct perf_session *session, + symbol_filter_t filter) { int size = PATH_MAX; char *name; @@ -1222,7 +1214,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) dso__set_loaded(self, map->type); if (self->kernel) - return dso__load_kernel_sym(self, map, kmaps, filter); + return dso__load_kernel_sym(self, map, session, filter); name = malloc(size); if (!name) @@ -1323,7 +1315,7 @@ struct map *map_groups__find_by_name(struct map_groups *self, return NULL; } -static int dsos__set_modules_path_dir(char *dirname) +static int perf_session__set_modules_path_dir(struct perf_session *self, char *dirname) { struct dirent *dent; DIR *dir = opendir(dirname); @@ -1343,7 +1335,7 @@ static int dsos__set_modules_path_dir(char *dirname) snprintf(path, sizeof(path), "%s/%s", dirname, dent->d_name); - if (dsos__set_modules_path_dir(path) < 0) + if (perf_session__set_modules_path_dir(self, path) < 0) goto failure; } else { char *dot = strrchr(dent->d_name, '.'), @@ -1357,7 +1349,7 @@ static int dsos__set_modules_path_dir(char *dirname) (int)(dot - dent->d_name), dent->d_name); strxfrchar(dso_name, '-', '_'); - map = map_groups__find_by_name(kmaps, MAP__FUNCTION, dso_name); + map = map_groups__find_by_name(&self->kmaps, MAP__FUNCTION, dso_name); if (map == NULL) continue; @@ -1377,7 +1369,7 @@ failure: return -1; } -static int dsos__set_modules_path(void) +static int perf_session__set_modules_path(struct perf_session *self) { struct utsname uts; char modules_path[PATH_MAX]; @@ -1388,7 +1380,7 @@ static int dsos__set_modules_path(void) snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel", uts.release); - return dsos__set_modules_path_dir(modules_path); + return perf_session__set_modules_path_dir(self, modules_path); } /* @@ -1410,7 +1402,7 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) return self; } -static int map_groups__create_module_maps(struct map_groups *self) +static int perf_session__create_module_maps(struct perf_session *self) { char *line = NULL; size_t n; @@ -1467,14 +1459,14 @@ static int map_groups__create_module_maps(struct map_groups *self) dso->has_build_id = true; dso->origin = DSO__ORIG_KMODULE; - map_groups__insert(self, map); + map_groups__insert(&self->kmaps, map); dsos__add(&dsos__kernel, dso); } free(line); fclose(file); - return dsos__set_modules_path(); + return perf_session__set_modules_path(self); out_delete_line: free(line); @@ -1483,7 +1475,7 @@ out_failure: } static int dso__load_vmlinux(struct dso *self, struct map *map, - struct map_groups *mg, + struct perf_session *session, const char *vmlinux, symbol_filter_t filter) { int err = -1, fd; @@ -1517,14 +1509,14 @@ static int dso__load_vmlinux(struct dso *self, struct map *map, return -1; dso__set_loaded(self, map->type); - err = dso__load_sym(self, map, mg, self->long_name, fd, filter, 1, 0); + err = dso__load_sym(self, map, session, self->long_name, fd, filter, 1, 0); close(fd); return err; } static int dso__load_kernel_sym(struct dso *self, struct map *map, - struct map_groups *mg, symbol_filter_t filter) + struct perf_session *session, symbol_filter_t filter) { int err; bool is_kallsyms; @@ -1534,7 +1526,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, pr_debug("Looking at the vmlinux_path (%d entries long)\n", vmlinux_path__nr_entries); for (i = 0; i < vmlinux_path__nr_entries; ++i) { - err = dso__load_vmlinux(self, map, mg, + err = dso__load_vmlinux(self, map, session, vmlinux_path[i], filter); if (err > 0) { pr_debug("Using %s for symbols\n", @@ -1550,12 +1542,12 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, if (is_kallsyms) goto do_kallsyms; - err = dso__load_vmlinux(self, map, mg, self->long_name, filter); + err = dso__load_vmlinux(self, map, session, self->long_name, filter); if (err <= 0) { pr_info("The file %s cannot be used, " "trying to use /proc/kallsyms...", self->long_name); do_kallsyms: - err = dso__load_kallsyms(self, map, mg, filter); + err = dso__load_kallsyms(self, map, session, filter); if (err > 0 && !is_kallsyms) dso__set_long_name(self, strdup("[kernel.kallsyms]")); } @@ -1757,23 +1749,30 @@ int symbol__init(struct symbol_conf *conf) if (pconf->sort_by_name) symbol__priv_size += (sizeof(struct symbol_name_rb_node) - sizeof(struct symbol)); - map_groups__init(kmaps); if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) return -1; - if (map_groups__create_kernel_maps(kmaps, pconf->vmlinux_name) < 0) { - vmlinux_path__exit(); + return 0; +} + +int perf_session__create_kernel_maps(struct perf_session *self, + struct symbol_conf *conf) +{ + const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults; + + if (map_groups__create_kernel_maps(&self->kmaps, + pconf->vmlinux_name) < 0) return -1; - } - kmaps->use_modules = pconf->use_modules; - if (pconf->use_modules && map_groups__create_module_maps(kmaps) < 0) - pr_debug("Failed to load list of modules in use, " - "continuing...\n"); + self->use_modules = pconf->use_modules; + + if (pconf->use_modules && perf_session__create_module_maps(self) < 0) + pr_debug("Failed to load list of modules for session %s, " + "continuing...\n", self->filename); /* * Now that we have all the maps created, just set the ->end of them: */ - map_groups__fixup_end(kmaps); + map_groups__fixup_end(&self->kmaps); return 0; } diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index cf99f88adf39..941ef331790e 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -98,8 +98,11 @@ bool dso__sorted_by_name(const struct dso *self, enum map_type type); void dso__sort_by_name(struct dso *self, enum map_type type); +struct perf_session; + struct dso *dsos__findnew(const char *name); -int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); +int dso__load(struct dso *self, struct map *map, struct perf_session *session, + symbol_filter_t filter); void dsos__fprintf(FILE *fp); size_t dsos__fprintf_buildid(FILE *fp); @@ -116,12 +119,10 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size); bool dsos__read_build_ids(void); int build_id__sprintf(u8 *self, int len, char *bf); -size_t kernel_maps__fprintf(FILE *fp); - int symbol__init(struct symbol_conf *conf); +int perf_session__create_kernel_maps(struct perf_session *self, + struct symbol_conf *conf); -struct map_groups; -struct map_groups *kmaps; extern struct list_head dsos__user, dsos__kernel; extern struct dso *vdso; #endif /* __PERF_SYMBOL */ diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 634b7f7140d5..4a08dcf50b68 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -282,13 +282,14 @@ size_t perf_session__fprintf(struct perf_session *self, FILE *fp) } struct symbol *map_groups__find_symbol(struct map_groups *self, + struct perf_session *session, enum map_type type, u64 addr, symbol_filter_t filter) { struct map *map = map_groups__find(self, type, addr); if (map != NULL) - return map__find_symbol(map, map->map_ip(map, addr), filter); + return map__find_symbol(map, session, map->map_ip(map, addr), filter); return NULL; } diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index e93abf2d9cb6..c206f72c8881 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -8,7 +8,6 @@ struct map_groups { struct rb_root maps[MAP__NR_TYPES]; struct list_head removed_maps[MAP__NR_TYPES]; - bool use_modules; }; struct thread { @@ -49,19 +48,21 @@ static inline struct map *thread__find_map(struct thread *self, return self ? map_groups__find(&self->mg, type, addr) : NULL; } -void thread__find_addr_location(struct thread *self, u8 cpumode, +void thread__find_addr_location(struct thread *self, + struct perf_session *session, u8 cpumode, enum map_type type, u64 addr, struct addr_location *al, symbol_filter_t filter); struct symbol *map_groups__find_symbol(struct map_groups *self, + struct perf_session *session, enum map_type type, u64 addr, symbol_filter_t filter); static inline struct symbol * -map_groups__find_function(struct map_groups *self, u64 addr, - symbol_filter_t filter) +map_groups__find_function(struct map_groups *self, struct perf_session *session, + u64 addr, symbol_filter_t filter) { - return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter); + return map_groups__find_symbol(self, session, MAP__FUNCTION, addr, filter); } struct map *map_groups__find_by_name(struct map_groups *self, -- cgit v1.2.3 From 4e4f06e4c8f17ea96f7dd76251cab99511026401 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Dec 2009 13:10:39 -0200 Subject: perf session: Move the hist_entries rb tree to perf_session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As we'll need to sort multiple times for multiple perf sessions, so that we can then do a diff. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260803439-16783-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 19 ++++++++------- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-report.c | 55 +++++++++++++++++++++++------------------- tools/perf/builtin-sched.c | 2 +- tools/perf/builtin-timechart.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/util/data_map.c | 2 +- tools/perf/util/hist.c | 43 ++++++++++++++++++--------------- tools/perf/util/hist.h | 43 +++++++++++---------------------- tools/perf/util/session.h | 5 +++- 10 files changed, 86 insertions(+), 89 deletions(-) (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index f25e89e9c9b0..1f1341f1dd84 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -121,10 +121,12 @@ static void hist_hit(struct hist_entry *he, u64 ip) h->ip[offset]); } -static int hist_entry__add(struct addr_location *al, u64 count) +static int perf_session__add_hist_entry(struct perf_session *self, + struct addr_location *al, u64 count) { bool hit; - struct hist_entry *he = __hist_entry__add(al, NULL, count, &hit); + struct hist_entry *he = __perf_session__add_hist_entry(self, al, NULL, + count, &hit); if (he == NULL) return -ENOMEM; hist_hit(he, al->addr); @@ -144,7 +146,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) return -1; } - if (hist_entry__add(&al, 1)) { + if (perf_session__add_hist_entry(session, &al, 1)) { fprintf(stderr, "problem incrementing symbol count, " "skipping event\n"); return -1; @@ -428,11 +430,11 @@ static void annotate_sym(struct hist_entry *he) free_source_line(he, len); } -static void find_annotations(void) +static void perf_session__find_annotations(struct perf_session *self) { struct rb_node *nd; - for (nd = rb_first(&hist); nd; nd = rb_next(nd)) { + for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) { struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); struct sym_priv *priv; @@ -484,10 +486,9 @@ static int __cmd_annotate(void) if (verbose > 2) dsos__fprintf(stdout); - collapse__resort(); - output__resort(event__total[0]); - - find_annotations(); + perf_session__collapse_resort(session); + perf_session__output_resort(session, event__total[0]); + perf_session__find_annotations(session); out_delete: perf_session__delete(session); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index e79ecbc17181..3b329c66b505 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -344,7 +344,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) return 0; } -static int sample_type_check(u64 type) +static int sample_type_check(u64 type, struct perf_session *session __used) { sample_type = type; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 9cbdcbc4cd56..854427f0e57e 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -38,6 +38,7 @@ static char *dso_list_str, *comm_list_str, *sym_list_str, static struct strlist *dso_list, *comm_list, *sym_list; static int force; +static bool use_callchain; static int show_nr_samples; @@ -312,8 +313,9 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, return ret; } -static size_t -hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples) +static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self, + struct perf_session *session, + u64 total_samples) { struct sort_entry *se; size_t ret; @@ -345,7 +347,7 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples) ret += fprintf(fp, "\n"); - if (callchain) { + if (session->use_callchain) { int left_margin = 0; if (sort__first_dimension == SORT_COMM) { @@ -422,7 +424,7 @@ static struct symbol **resolve_callchain(struct thread *thread, struct symbol **syms = NULL; unsigned int i; - if (callchain) { + if (session->use_callchain) { syms = calloc(chain->nr, sizeof(*syms)); if (!syms) { fprintf(stderr, "Can't allocate memory for symbols\n"); @@ -454,7 +456,7 @@ static struct symbol **resolve_callchain(struct thread *thread, if (sort__has_parent && !*parent && call__match(al.sym)) *parent = al.sym; - if (!callchain) + if (!session->use_callchain) break; syms[i] = al.sym; } @@ -467,25 +469,25 @@ static struct symbol **resolve_callchain(struct thread *thread, * collect histogram counts */ -static int hist_entry__add(struct addr_location *al, - struct perf_session *session, - struct ip_callchain *chain, u64 count) +static int perf_session__add_hist_entry(struct perf_session *self, + struct addr_location *al, + struct ip_callchain *chain, u64 count) { struct symbol **syms = NULL, *parent = NULL; bool hit; struct hist_entry *he; - if ((sort__has_parent || callchain) && chain) - syms = resolve_callchain(al->thread, session, chain, &parent); + if ((sort__has_parent || self->use_callchain) && chain) + syms = resolve_callchain(al->thread, self, chain, &parent); - he = __hist_entry__add(al, parent, count, &hit); + he = __perf_session__add_hist_entry(self, al, parent, count, &hit); if (he == NULL) return -ENOMEM; if (hit) he->count += count; - if (callchain) { + if (self->use_callchain) { if (!hit) callchain_init(&he->callchain); append_chain(&he->callchain, chain, syms); @@ -495,7 +497,8 @@ static int hist_entry__add(struct addr_location *al, return 0; } -static size_t output__fprintf(FILE *fp, u64 total_samples) +static size_t perf_session__fprintf_hist_entries(struct perf_session *self, + u64 total_samples, FILE *fp) { struct hist_entry *pos; struct sort_entry *se; @@ -567,9 +570,9 @@ static size_t output__fprintf(FILE *fp, u64 total_samples) fprintf(fp, "#\n"); print_entries: - for (nd = rb_first(&hist); nd; nd = rb_next(nd)) { + for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) { pos = rb_entry(nd, struct hist_entry, rb_node); - ret += hist_entry__fprintf(fp, pos, total_samples); + ret += hist_entry__fprintf(fp, pos, self, total_samples); } if (sort_order == default_sort_order && @@ -671,7 +674,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name)) return 0; - if (hist_entry__add(&al, session, data.callchain, data.period)) { + if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) { pr_debug("problem incrementing symbol count, skipping event\n"); return -1; } @@ -719,7 +722,7 @@ static int process_read_event(event_t *event, struct perf_session *session __use return 0; } -static int sample_type_check(u64 type) +static int sample_type_check(u64 type, struct perf_session *session) { sample_type = type; @@ -730,14 +733,14 @@ static int sample_type_check(u64 type) " perf record without -g?\n"); return -1; } - if (callchain) { + if (session->use_callchain) { fprintf(stderr, "selected -g but no callchain data." " Did you call perf record without" " -g?\n"); return -1; } - } else if (callchain_param.mode != CHAIN_NONE && !callchain) { - callchain = 1; + } else if (callchain_param.mode != CHAIN_NONE && !session->use_callchain) { + session->use_callchain = true; if (register_callchain_param(&callchain_param) < 0) { fprintf(stderr, "Can't register callchain" " params\n"); @@ -769,6 +772,8 @@ static int __cmd_report(void) if (session == NULL) return -ENOMEM; + session->use_callchain = use_callchain; + if (show_threads) perf_read_values_init(&show_threads_values); @@ -787,9 +792,9 @@ static int __cmd_report(void) if (verbose > 2) dsos__fprintf(stdout); - collapse__resort(); - output__resort(event__stats.total); - output__fprintf(stdout, event__stats.total); + perf_session__collapse_resort(session); + perf_session__output_resort(session, event__stats.total); + perf_session__fprintf_hist_entries(session, event__stats.total, stdout); if (show_threads) perf_read_values_destroy(&show_threads_values); @@ -805,7 +810,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg, char *tok; char *endptr; - callchain = 1; + use_callchain = true; if (!arg) return 0; @@ -826,7 +831,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg, else if (!strncmp(tok, "none", strlen(arg))) { callchain_param.mode = CHAIN_NONE; - callchain = 0; + use_callchain = true; return 0; } diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index bce05dff6dfe..412ae924640a 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1655,7 +1655,7 @@ static int process_lost_event(event_t *event __used, return 0; } -static int sample_type_check(u64 type) +static int sample_type_check(u64 type, struct perf_session *session __used) { sample_type = type; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 27018531404b..3a0a89e41523 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1033,7 +1033,7 @@ static void process_samples(void) } } -static int sample_type_check(u64 type) +static int sample_type_check(u64 type, struct perf_session *session __used) { sample_type = type; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 9d89ae423ca5..adce442dd603 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -103,7 +103,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) return 0; } -static int sample_type_check(u64 type) +static int sample_type_check(u64 type, struct perf_session *session __used) { sample_type = type; diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 44dea211cc65..08c4cf5e66ba 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -161,7 +161,7 @@ int perf_session__process_events(struct perf_session *self, err = -EINVAL; if (ops->sample_type_check && - ops->sample_type_check(sample_type) < 0) + ops->sample_type_check(sample_type, self) < 0) goto out_err; if (!ops->full_paths) { diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index b40e37ded4bf..b9828fce7bf0 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1,7 +1,6 @@ #include "hist.h" - -struct rb_root hist; -int callchain; +#include "session.h" +#include "sort.h" struct callchain_param callchain_param = { .mode = CHAIN_GRAPH_REL, @@ -12,11 +11,12 @@ struct callchain_param callchain_param = { * histogram, sorted on item, collects counts */ -struct hist_entry *__hist_entry__add(struct addr_location *al, - struct symbol *sym_parent, - u64 count, bool *hit) +struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self, + struct addr_location *al, + struct symbol *sym_parent, + u64 count, bool *hit) { - struct rb_node **p = &hist.rb_node; + struct rb_node **p = &self->hists.rb_node; struct rb_node *parent = NULL; struct hist_entry *he; struct hist_entry entry = { @@ -52,7 +52,7 @@ struct hist_entry *__hist_entry__add(struct addr_location *al, return NULL; *he = entry; rb_link_node(&he->rb_node, parent, p); - rb_insert_color(&he->rb_node, &hist); + rb_insert_color(&he->rb_node, &self->hists); *hit = false; return he; } @@ -129,7 +129,7 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he) rb_insert_color(&he->rb_node, root); } -void collapse__resort(void) +void perf_session__collapse_resort(struct perf_session *self) { struct rb_root tmp; struct rb_node *next; @@ -139,31 +139,33 @@ void collapse__resort(void) return; tmp = RB_ROOT; - next = rb_first(&hist); + next = rb_first(&self->hists); while (next) { n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); - rb_erase(&n->rb_node, &hist); + rb_erase(&n->rb_node, &self->hists); collapse__insert_entry(&tmp, n); } - hist = tmp; + self->hists = tmp; } /* * reverse the map, sort on count. */ -static void output__insert_entry(struct rb_root *root, struct hist_entry *he, - u64 min_callchain_hits) +static void perf_session__insert_output_hist_entry(struct perf_session *self, + struct rb_root *root, + struct hist_entry *he, + u64 min_callchain_hits) { struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct hist_entry *iter; - if (callchain) + if (self->use_callchain) callchain_param.sort(&he->sorted_chain, &he->callchain, min_callchain_hits, &callchain_param); @@ -181,7 +183,7 @@ static void output__insert_entry(struct rb_root *root, struct hist_entry *he, rb_insert_color(&he->rb_node, root); } -void output__resort(u64 total_samples) +void perf_session__output_resort(struct perf_session *self, u64 total_samples) { struct rb_root tmp; struct rb_node *next; @@ -192,15 +194,16 @@ void output__resort(u64 total_samples) total_samples * (callchain_param.min_percent / 100); tmp = RB_ROOT; - next = rb_first(&hist); + next = rb_first(&self->hists); while (next) { n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); - rb_erase(&n->rb_node, &hist); - output__insert_entry(&tmp, n, min_callchain_hits); + rb_erase(&n->rb_node, &self->hists); + perf_session__insert_output_hist_entry(self, &tmp, n, + min_callchain_hits); } - hist = tmp; + self->hists = tmp; } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index a6cb1485e3b9..7efdb1b6d8c8 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -1,40 +1,25 @@ #ifndef __PERF_HIST_H #define __PERF_HIST_H -#include "../builtin.h" -#include "util.h" - -#include "color.h" -#include -#include "cache.h" -#include -#include "symbol.h" -#include "string.h" +#include #include "callchain.h" -#include "strlist.h" -#include "values.h" - -#include "../perf.h" -#include "debug.h" -#include "header.h" - -#include "parse-options.h" -#include "parse-events.h" -#include "thread.h" -#include "sort.h" - -extern struct rb_root hist; -extern int callchain; extern struct callchain_param callchain_param; -struct hist_entry *__hist_entry__add(struct addr_location *al, - struct symbol *parent, - u64 count, bool *hit); +struct perf_session; +struct hist_entry; +struct addr_location; +struct symbol; + +struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self, + struct addr_location *al, + struct symbol *parent, + u64 count, bool *hit); extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); -extern void hist_entry__free(struct hist_entry *); -extern void collapse__resort(void); -extern void output__resort(u64); +void hist_entry__free(struct hist_entry *); + +void perf_session__output_resort(struct perf_session *self, u64 total_samples); +void perf_session__collapse_resort(struct perf_session *self); #endif /* __PERF_HIST_H */ diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 20b2c9cc834b..759d96022a39 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -16,10 +16,12 @@ struct perf_session { struct map_groups kmaps; struct rb_root threads; struct thread *last_match; + struct rb_root hists; int fd; int cwdlen; char *cwd; bool use_modules; + bool use_callchain; char filename[0]; }; @@ -35,7 +37,8 @@ struct perf_event_ops { event_op process_read_event; event_op process_throttle_event; event_op process_unthrottle_event; - int (*sample_type_check)(u64 sample_type); + int (*sample_type_check)(u64 sample_type, + struct perf_session *session); unsigned long total_unknown; bool full_paths; }; -- cgit v1.2.3 From c019879bcc5692ec9267c1cedad91f1794d0b693 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Dec 2009 14:23:00 -0200 Subject: perf session: Adopt the sample_type variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All tools had copies, and perf diff would have to specify a sample_type_check method just for copying it. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260807780-19377-2-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar --- tools/perf/builtin-kmem.c | 10 +++------- tools/perf/builtin-report.c | 12 ++++-------- tools/perf/builtin-sched.c | 12 ++++-------- tools/perf/builtin-timechart.c | 36 +++++++++++++++--------------------- tools/perf/builtin-trace.c | 12 ++++-------- tools/perf/util/data_map.c | 6 ++---- tools/perf/util/session.h | 4 ++-- 7 files changed, 34 insertions(+), 58 deletions(-) (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 3b329c66b505..dda60869faad 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -20,8 +20,6 @@ typedef int (*sort_fn_t)(struct alloc_stat *, struct alloc_stat *); static char const *input_name = "perf.data"; -static u64 sample_type; - static int alloc_flag; static int caller_flag; @@ -321,7 +319,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) data.cpu = -1; data.period = 1; - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, @@ -344,11 +342,9 @@ static int process_sample_event(event_t *event, struct perf_session *session) return 0; } -static int sample_type_check(u64 type, struct perf_session *session __used) +static int sample_type_check(struct perf_session *session) { - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_RAW)) { + if (!(session->sample_type & PERF_SAMPLE_RAW)) { fprintf(stderr, "No trace sample to read. Did you call perf record " "without -R?"); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 5141cdccbb65..142c475f9918 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -52,8 +52,6 @@ static int exclude_other = 1; static char callchain_default_opt[] = "fractal,0.5"; -static u64 sample_type; - struct symbol_conf symbol_conf; @@ -557,7 +555,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) memset(&data, 0, sizeof(data)); data.period = 1; - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, @@ -565,7 +563,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) (void *)(long)data.ip, (long long)data.period); - if (sample_type & PERF_SAMPLE_CALLCHAIN) { + if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { unsigned int i; dump_printf("... chain: nr:%Lu\n", data.callchain->nr); @@ -664,11 +662,9 @@ static int process_read_event(event_t *event, struct perf_session *session __use return 0; } -static int sample_type_check(u64 type, struct perf_session *session) +static int sample_type_check(struct perf_session *session) { - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) { + if (!(session->sample_type & PERF_SAMPLE_CALLCHAIN)) { if (sort__has_parent) { fprintf(stderr, "selected --sort parent, but no" " callchain data. Did you call" diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 412ae924640a..d67f274adba0 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -21,8 +21,6 @@ static char const *input_name = "perf.data"; -static u64 sample_type; - static char default_sort_order[] = "avg, max, switch, runtime"; static char *sort_order = default_sort_order; @@ -1613,7 +1611,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) struct sample_data data; struct thread *thread; - if (!(sample_type & PERF_SAMPLE_RAW)) + if (!(session->sample_type & PERF_SAMPLE_RAW)) return 0; memset(&data, 0, sizeof(data)); @@ -1621,7 +1619,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) data.cpu = -1; data.period = -1; - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, @@ -1655,11 +1653,9 @@ static int process_lost_event(event_t *event __used, return 0; } -static int sample_type_check(u64 type, struct perf_session *session __used) +static int sample_type_check(struct perf_session *session __used) { - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_RAW)) { + if (!(session->sample_type & PERF_SAMPLE_RAW)) { fprintf(stderr, "No trace sample to read. Did you call perf record " "without -R?"); diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 3a0a89e41523..ffd81e87ce69 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -36,9 +36,6 @@ static char const *input_name = "perf.data"; static char const *output_name = "output.svg"; - -static u64 sample_type; - static unsigned int numcpus; static u64 min_freq; /* Lowest CPU frequency seen */ static u64 max_freq; /* Highest CPU frequency seen */ @@ -478,17 +475,16 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te) } -static int -process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session) { struct sample_data data; struct trace_entry *te; memset(&data, 0, sizeof(data)); - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); - if (sample_type & PERF_SAMPLE_TIME) { + if (session->sample_type & PERF_SAMPLE_TIME) { if (!first_time || first_time > data.time) first_time = data.time; if (last_time < data.time) @@ -496,7 +492,7 @@ process_sample_event(event_t *event) } te = (void *)data.raw_data; - if (sample_type & PERF_SAMPLE_RAW && data.raw_size > 0) { + if (session->sample_type & PERF_SAMPLE_RAW && data.raw_size > 0) { char *event_str; struct power_entry *pe; @@ -573,16 +569,16 @@ static void end_sample_processing(void) } } -static u64 sample_time(event_t *event) +static u64 sample_time(event_t *event, const struct perf_session *session) { int cursor; cursor = 0; - if (sample_type & PERF_SAMPLE_IP) + if (session->sample_type & PERF_SAMPLE_IP) cursor++; - if (sample_type & PERF_SAMPLE_TID) + if (session->sample_type & PERF_SAMPLE_TID) cursor++; - if (sample_type & PERF_SAMPLE_TIME) + if (session->sample_type & PERF_SAMPLE_TIME) return event->sample.array[cursor]; return 0; } @@ -592,7 +588,7 @@ static u64 sample_time(event_t *event) * We first queue all events, sorted backwards by insertion. * The order will get flipped later. */ -static int queue_sample_event(event_t *event, struct perf_session *session __used) +static int queue_sample_event(event_t *event, struct perf_session *session) { struct sample_wrapper *copy, *prev; int size; @@ -606,7 +602,7 @@ static int queue_sample_event(event_t *event, struct perf_session *session __use memset(copy, 0, size); copy->next = NULL; - copy->timestamp = sample_time(event); + copy->timestamp = sample_time(event, session); memcpy(©->data, event, event->sample.header.size); @@ -1018,7 +1014,7 @@ static void write_svg_file(const char *filename) svg_close(); } -static void process_samples(void) +static void process_samples(struct perf_session *session) { struct sample_wrapper *cursor; event_t *event; @@ -1029,15 +1025,13 @@ static void process_samples(void) while (cursor) { event = (void *)&cursor->data; cursor = cursor->next; - process_sample_event(event); + process_sample_event(event, session); } } -static int sample_type_check(u64 type, struct perf_session *session __used) +static int sample_type_check(struct perf_session *session) { - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_RAW)) { + if (!(session->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; @@ -1067,7 +1061,7 @@ static int __cmd_timechart(void) if (ret) goto out_delete; - process_samples(); + process_samples(session); end_sample_processing(); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index adce442dd603..9ee976dc395b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -61,8 +61,6 @@ static int cleanup_scripting(void) static char const *input_name = "perf.data"; -static u64 sample_type; - static int process_sample_event(event_t *event, struct perf_session *session) { struct sample_data data; @@ -73,7 +71,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) data.cpu = -1; data.period = 1; - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, @@ -88,7 +86,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) return -1; } - if (sample_type & PERF_SAMPLE_RAW) { + if (session->sample_type & PERF_SAMPLE_RAW) { /* * FIXME: better resolve from pid from the struct trace_entry * field, although it should be the same than this perf @@ -103,11 +101,9 @@ static int process_sample_event(event_t *event, struct perf_session *session) return 0; } -static int sample_type_check(u64 type, struct perf_session *session __used) +static int sample_type_check(struct perf_session *session) { - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_RAW)) { + if (!(session->sample_type & PERF_SAMPLE_RAW)) { fprintf(stderr, "No trace sample to read. Did you call perf record " "without -R?"); diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 08c4cf5e66ba..b557b836de3d 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -144,7 +144,6 @@ int perf_session__process_events(struct perf_session *self, unsigned long head, shift; unsigned long offset = 0; size_t page_size; - u64 sample_type; event_t *event; uint32_t size; char *buf; @@ -157,11 +156,10 @@ int perf_session__process_events(struct perf_session *self, page_size = getpagesize(); head = self->header.data_offset; - sample_type = perf_header__sample_type(&self->header); + self->sample_type = perf_header__sample_type(&self->header); err = -EINVAL; - if (ops->sample_type_check && - ops->sample_type_check(sample_type, self) < 0) + if (ops->sample_type_check && ops->sample_type_check(self) < 0) goto out_err; if (!ops->full_paths) { diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index a8f3a49ca43a..4e8a21c5304c 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -19,6 +19,7 @@ struct perf_session { struct rb_root threads; struct thread *last_match; struct rb_root hists; + u64 sample_type; int fd; int cwdlen; char *cwd; @@ -39,8 +40,7 @@ struct perf_event_ops { event_op process_read_event; event_op process_throttle_event; event_op process_unthrottle_event; - int (*sample_type_check)(u64 sample_type, - struct perf_session *session); + int (*sample_type_check)(struct perf_session *session); unsigned long total_unknown; bool full_paths; }; -- cgit v1.2.3 From 75be6cf48738aec68aac49b428423569492cfba3 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 15 Dec 2009 20:04:39 -0200 Subject: perf symbols: Make symbol_conf global MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This simplifies a lot of functions, less stuff to be done by tool writers. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260914682-29652-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 14 ++++++-------- tools/perf/builtin-buildid-list.c | 5 +++-- tools/perf/builtin-diff.c | 8 +++----- tools/perf/builtin-kmem.c | 5 ++--- tools/perf/builtin-probe.c | 14 ++++++-------- tools/perf/builtin-record.c | 4 ++-- tools/perf/builtin-report.c | 7 ++----- tools/perf/builtin-sched.c | 5 ++--- tools/perf/builtin-timechart.c | 5 ++--- tools/perf/builtin-top.c | 6 ++---- tools/perf/builtin-trace.c | 4 ++-- tools/perf/util/session.c | 5 ++--- tools/perf/util/session.h | 5 +---- tools/perf/util/symbol.c | 38 +++++++++++++++----------------------- tools/perf/util/symbol.h | 9 ++++----- 15 files changed, 54 insertions(+), 80 deletions(-) (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 2e2855a685c6..e656e25f1c14 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -51,11 +51,6 @@ struct sym_priv { struct sym_ext *ext; }; -static struct symbol_conf symbol_conf = { - .priv_size = sizeof(struct sym_priv), - .try_vmlinux_path = true, -}; - static const char *sym_hist_filter; static int symbol_filter(struct map *map __used, struct symbol *sym) @@ -464,10 +459,10 @@ static struct perf_event_ops event_ops = { static int __cmd_annotate(void) { - struct perf_session *session = perf_session__new(input_name, O_RDONLY, - force, &symbol_conf); int ret; + struct perf_session *session; + session = perf_session__new(input_name, O_RDONLY, force); if (session == NULL) return -ENOMEM; @@ -523,7 +518,10 @@ static const struct option options[] = { int cmd_annotate(int argc, const char **argv, const char *prefix __used) { - if (symbol__init(&symbol_conf) < 0) + symbol_conf.priv_size = sizeof(struct sym_priv); + symbol_conf.try_vmlinux_path = true; + + if (symbol__init() < 0) return -1; argc = parse_options(argc, argv, options, annotate_usage, 0); diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 7c36e4b2eccf..e693e6777af5 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -54,8 +54,9 @@ static int perf_file_section__process_buildids(struct perf_file_section *self, static int __cmd_buildid_list(void) { int err = -1; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, - force, NULL); + struct perf_session *session; + + session = perf_session__new(input_name, O_RDONLY, force); if (session == NULL) return -1; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 0d528018ffb8..67328d106994 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -21,8 +21,6 @@ static char const *input_old = "perf.data.old", static int force; static bool show_percent; -struct symbol_conf symbol_conf; - static int perf_session__add_hist_entry(struct perf_session *self, struct addr_location *al, u64 count) { @@ -226,8 +224,8 @@ static int __cmd_diff(void) int ret, i; struct perf_session *session[2]; - session[0] = perf_session__new(input_old, O_RDONLY, force, &symbol_conf); - session[1] = perf_session__new(input_new, O_RDONLY, force, &symbol_conf); + session[0] = perf_session__new(input_old, O_RDONLY, force); + session[1] = perf_session__new(input_new, O_RDONLY, force); if (session[0] == NULL || session[1] == NULL) return -ENOMEM; @@ -267,7 +265,7 @@ static const struct option options[] = { int cmd_diff(int argc, const char **argv, const char *prefix __used) { - if (symbol__init(&symbol_conf) < 0) + if (symbol__init() < 0) return -1; setup_sorting(diff_usage, options); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index dda60869faad..e078797ab1f1 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -505,8 +505,7 @@ static void sort_result(void) static int __cmd_kmem(void) { int err; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, - 0, NULL); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); if (session == NULL) return -ENOMEM; @@ -767,7 +766,7 @@ static int __cmd_record(int argc, const char **argv) int cmd_kmem(int argc, const char **argv, const char *prefix __used) { - symbol__init(0); + symbol__init(); argc = parse_options(argc, argv, kmem_options, kmem_usage, 0); diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 520b064b46d8..7e741f54d798 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -57,7 +57,6 @@ static struct { int nr_probe; struct probe_point probes[MAX_PROBES]; struct strlist *dellist; - struct symbol_conf conf; struct perf_session *psession; struct map *kmap; } session; @@ -151,7 +150,7 @@ static const struct option options[] = { OPT_BOOLEAN('v', "verbose", &verbose, "be more verbose (show parsed arguments, etc)"), #ifndef NO_LIBDWARF - OPT_STRING('k', "vmlinux", &session.conf.vmlinux_name, + OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, "file", "vmlinux pathname"), #endif OPT_BOOLEAN('l', "list", &session.list_events, @@ -224,13 +223,12 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) } /* Initialize symbol maps for vmlinux */ - session.conf.sort_by_name = true; - if (session.conf.vmlinux_name == NULL) - session.conf.try_vmlinux_path = true; - if (symbol__init(&session.conf) < 0) + symbol_conf.sort_by_name = true; + if (symbol_conf.vmlinux_name == NULL) + symbol_conf.try_vmlinux_path = true; + if (symbol__init() < 0) die("Failed to init symbol map."); - session.psession = perf_session__new(NULL, O_WRONLY, false, - &session.conf); + session.psession = perf_session__new(NULL, O_WRONLY, false); if (session.psession == NULL) die("Failed to init perf_session."); session.kmap = map_groups__find_by_name(&session.psession->kmaps, diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 66979a5553b8..1da48a8fe9cc 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -451,7 +451,7 @@ static int __cmd_record(int argc, const char **argv) exit(-1); } - session = perf_session__new(output_name, O_WRONLY, force, NULL); + session = perf_session__new(output_name, O_WRONLY, force); if (session == NULL) { pr_err("Not enough memory for reading perf file header\n"); return -1; @@ -632,7 +632,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) { int counter; - symbol__init(0); + symbol__init(); argc = parse_options(argc, argv, options, record_usage, PARSE_OPT_STOP_AT_NON_OPTION); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 40389c0e38c6..c349bdbb9474 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -52,9 +52,6 @@ static int exclude_other = 1; static char callchain_default_opt[] = "fractal,0.5"; -static struct symbol_conf symbol_conf; - - static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) { @@ -705,7 +702,7 @@ static int __cmd_report(void) int ret; struct perf_session *session; - session = perf_session__new(input_name, O_RDONLY, force, &symbol_conf); + session = perf_session__new(input_name, O_RDONLY, force); if (session == NULL) return -ENOMEM; @@ -864,7 +861,7 @@ static void setup_list(struct strlist **list, const char *list_str, int cmd_report(int argc, const char **argv, const char *prefix __used) { - if (symbol__init(&symbol_conf) < 0) + if (symbol__init() < 0) return -1; argc = parse_options(argc, argv, options, report_usage, 0); diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index d67f274adba0..80209df6cfe8 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1675,8 +1675,7 @@ static struct perf_event_ops event_ops = { static int read_events(void) { int err; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, - 0, NULL); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); if (session == NULL) return -ENOMEM; @@ -1912,7 +1911,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __used) if (!strcmp(argv[0], "trace")) return cmd_trace(argc, argv, prefix); - symbol__init(0); + symbol__init(); if (!strncmp(argv[0], "rec", 3)) { return __cmd_record(argc, argv); } else if (!strncmp(argv[0], "lat", 3)) { diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index ffd81e87ce69..9c98b7a2b19a 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1050,8 +1050,7 @@ static struct perf_event_ops event_ops = { static int __cmd_timechart(void) { - struct perf_session *session = perf_session__new(input_name, O_RDONLY, - 0, NULL); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); int ret; if (session == NULL) @@ -1138,7 +1137,7 @@ static const struct option options[] = { int cmd_timechart(int argc, const char **argv, const char *prefix __used) { - symbol__init(0); + symbol__init(); argc = parse_options(argc, argv, options, timechart_usage, PARSE_OPT_STOP_AT_NON_OPTION); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 296e809c2538..cd89b6d036b7 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -80,7 +80,6 @@ static int dump_symtab = 0; static bool hide_kernel_symbols = false; static bool hide_user_symbols = false; static struct winsize winsize; -static struct symbol_conf symbol_conf; /* * Source @@ -1162,8 +1161,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, - &symbol_conf); + struct perf_session *session = perf_session__new(NULL, O_WRONLY, false); if (session == NULL) return -ENOMEM; @@ -1284,7 +1282,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) (nr_counters + 1) * sizeof(unsigned long)); if (symbol_conf.vmlinux_name == NULL) symbol_conf.try_vmlinux_path = true; - if (symbol__init(&symbol_conf) < 0) + if (symbol__init() < 0) return -1; if (delay_secs < 1) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 7e744f774047..07ad25ca654f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -579,7 +579,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) exit(-1); } - symbol__init(0); + symbol__init(); setup_scripting(); @@ -588,7 +588,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) setup_pager(); - session = perf_session__new(input_name, O_RDONLY, 0, NULL); + session = perf_session__new(input_name, O_RDONLY, 0); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index ecd54bedfb1c..bceaa09f55a1 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -49,8 +49,7 @@ out_close: return -1; } -struct perf_session *perf_session__new(const char *filename, int mode, - bool force, struct symbol_conf *conf) +struct perf_session *perf_session__new(const char *filename, int mode, bool force) { size_t len = filename ? strlen(filename) + 1 : 0; struct perf_session *self = zalloc(sizeof(*self) + len); @@ -69,7 +68,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, self->cwdlen = 0; map_groups__init(&self->kmaps); - if (perf_session__create_kernel_maps(self, conf) < 0) + if (perf_session__create_kernel_maps(self) < 0) goto out_delete; if (mode == O_RDONLY && perf_session__open(self, force) < 0) diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index bdfc4b8eee7a..faf18a8e0311 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -10,7 +10,6 @@ struct ip_callchain; struct thread; struct symbol; -struct symbol_conf; struct perf_session { struct perf_header header; @@ -26,7 +25,6 @@ struct perf_session { int fd; int cwdlen; char *cwd; - bool use_modules; bool use_callchain; char filename[0]; }; @@ -48,8 +46,7 @@ struct perf_event_ops { bool full_paths; }; -struct perf_session *perf_session__new(const char *filename, int mode, - bool force, struct symbol_conf *conf); +struct perf_session *perf_session__new(const char *filename, int mode, bool force); void perf_session__delete(struct perf_session *self); int perf_session__process_events(struct perf_session *self, diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 185b9eec192b..17ce01269a91 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -33,11 +33,10 @@ static void dsos__add(struct list_head *head, struct dso *dso); static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); static int dso__load_kernel_sym(struct dso *self, struct map *map, struct perf_session *session, symbol_filter_t filter); -unsigned int symbol__priv_size; static int vmlinux_path__nr_entries; static char **vmlinux_path; -static struct symbol_conf symbol_conf__defaults = { +struct symbol_conf symbol_conf = { .use_modules = true, .try_vmlinux_path = true, }; @@ -130,13 +129,13 @@ static void map_groups__fixup_end(struct map_groups *self) static struct symbol *symbol__new(u64 start, u64 len, const char *name) { size_t namelen = strlen(name) + 1; - struct symbol *self = zalloc(symbol__priv_size + + struct symbol *self = zalloc(symbol_conf.priv_size + sizeof(*self) + namelen); if (self == NULL) return NULL; - if (symbol__priv_size) - self = ((void *)self) + symbol__priv_size; + if (symbol_conf.priv_size) + self = ((void *)self) + symbol_conf.priv_size; self->start = start; self->end = len ? start + len - 1 : start; @@ -150,7 +149,7 @@ static struct symbol *symbol__new(u64 start, u64 len, const char *name) static void symbol__delete(struct symbol *self) { - free(((void *)self) - symbol__priv_size); + free(((void *)self) - symbol_conf.priv_size); } static size_t symbol__fprintf(struct symbol *self, FILE *fp) @@ -471,7 +470,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, module = strchr(pos->name, '\t'); if (module) { - if (!session->use_modules) + if (!symbol_conf.use_modules) goto discard_symbol; *module++ = '\0'; @@ -1740,34 +1739,27 @@ out_fail: return -1; } -int symbol__init(struct symbol_conf *conf) +int symbol__init(void) { - const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults; - elf_version(EV_CURRENT); - symbol__priv_size = pconf->priv_size; - if (pconf->sort_by_name) - symbol__priv_size += (sizeof(struct symbol_name_rb_node) - - sizeof(struct symbol)); + if (symbol_conf.sort_by_name) + symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - + sizeof(struct symbol)); - if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) + if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0) return -1; return 0; } -int perf_session__create_kernel_maps(struct perf_session *self, - struct symbol_conf *conf) +int perf_session__create_kernel_maps(struct perf_session *self) { - const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults; - if (map_groups__create_kernel_maps(&self->kmaps, - pconf->vmlinux_name) < 0) + symbol_conf.vmlinux_name) < 0) return -1; - self->use_modules = pconf->use_modules; - - if (pconf->use_modules && perf_session__create_module_maps(self) < 0) + if (symbol_conf.use_modules && + perf_session__create_module_maps(self) < 0) pr_debug("Failed to load list of modules for session %s, " "continuing...\n", self->filename); /* diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 941ef331790e..766294735f93 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -57,11 +57,11 @@ struct symbol_conf { const char *vmlinux_name; }; -extern unsigned int symbol__priv_size; +extern struct symbol_conf symbol_conf; static inline void *symbol__priv(struct symbol *self) { - return ((void *)self) - symbol__priv_size; + return ((void *)self) - symbol_conf.priv_size; } struct addr_location { @@ -119,9 +119,8 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size); bool dsos__read_build_ids(void); int build_id__sprintf(u8 *self, int len, char *bf); -int symbol__init(struct symbol_conf *conf); -int perf_session__create_kernel_maps(struct perf_session *self, - struct symbol_conf *conf); +int symbol__init(void); +int perf_session__create_kernel_maps(struct perf_session *self); extern struct list_head dsos__user, dsos__kernel; extern struct dso *vdso; -- cgit v1.2.3 From 655000e7c75a559681ee7f15f6fa870c80ae3194 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 15 Dec 2009 20:04:40 -0200 Subject: perf symbols: Adopt the strlists for dso, comm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Will be used in perf diff too. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260914682-29652-2-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 4 +-- tools/perf/builtin-diff.c | 9 +++--- tools/perf/builtin-kmem.c | 4 +-- tools/perf/builtin-record.c | 6 ++-- tools/perf/builtin-report.c | 73 ++++++++++++++++++------------------------ tools/perf/builtin-timechart.c | 4 +-- tools/perf/builtin-trace.c | 4 +-- tools/perf/util/symbol.c | 33 +++++++++++++++++++ tools/perf/util/symbol.h | 9 ++++++ 9 files changed, 89 insertions(+), 57 deletions(-) (limited to 'tools/perf/builtin-timechart.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index e656e25f1c14..645d58058431 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -518,14 +518,14 @@ static const struct option options[] = { int cmd_annotate(int argc, const char **argv, const char *prefix __used) { + argc = parse_options(argc, argv, options, annotate_usage, 0); + symbol_conf.priv_size = sizeof(struct sym_priv); symbol_conf.try_vmlinux_path = true; if (symbol__init() < 0) return -1; - argc = parse_options(argc, argv, options, annotate_usage, 0); - setup_sorting(annotate_usage, options); if (argc) { diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 67328d106994..4fde60655341 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -265,11 +265,6 @@ static const struct option options[] = { int cmd_diff(int argc, const char **argv, const char *prefix __used) { - if (symbol__init() < 0) - return -1; - - setup_sorting(diff_usage, options); - argc = parse_options(argc, argv, options, diff_usage, 0); if (argc) { if (argc > 2) @@ -281,6 +276,10 @@ int cmd_diff(int argc, const char **argv, const char *prefix __used) input_new = argv[0]; } + if (symbol__init() < 0) + return -1; + + setup_sorting(diff_usage, options); setup_pager(); return __cmd_diff(); } diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index e078797ab1f1..fc21ad79dd83 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -766,13 +766,13 @@ static int __cmd_record(int argc, const char **argv) int cmd_kmem(int argc, const char **argv, const char *prefix __used) { - symbol__init(); - argc = parse_options(argc, argv, kmem_options, kmem_usage, 0); if (!argc) usage_with_options(kmem_usage, kmem_options); + symbol__init(); + if (!strncmp(argv[0], "rec", 3)) { return __cmd_record(argc, argv); } else if (!strcmp(argv[0], "stat")) { diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 1da48a8fe9cc..65301c5ca1de 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -632,13 +632,13 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) { int counter; - symbol__init(); - argc = parse_options(argc, argv, options, record_usage, - PARSE_OPT_STOP_AT_NON_OPTION); + PARSE_OPT_STOP_AT_NON_OPTION); if (!argc && target_pid == -1 && !system_wide) usage_with_options(record_usage, options); + symbol__init(); + if (!nr_counters) { nr_counters = 1; attrs[0].type = PERF_TYPE_HARDWARE; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c349bdbb9474..03afac3b56ef 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -33,10 +33,6 @@ static char const *input_name = "perf.data"; -static char *dso_list_str, *comm_list_str, *sym_list_str, - *col_width_list_str; -static struct strlist *dso_list, *comm_list, *sym_list; - static int force; static bool use_callchain; @@ -365,8 +361,9 @@ static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self, static void dso__calc_col_width(struct dso *self) { - if (!col_width_list_str && !field_sep && - (!dso_list || strlist__has_entry(dso_list, self->name))) { + if (!symbol_conf.col_width_list_str && !field_sep && + (!symbol_conf.dso_list || + strlist__has_entry(symbol_conf.dso_list, self->name))) { unsigned int slen = strlen(self->name); if (slen > dsos__col_width) dsos__col_width = slen; @@ -379,8 +376,9 @@ static void thread__comm_adjust(struct thread *self) { char *comm = self->comm; - if (!col_width_list_str && !field_sep && - (!comm_list || strlist__has_entry(comm_list, comm))) { + if (!symbol_conf.col_width_list_str && !field_sep && + (!symbol_conf.comm_list || + strlist__has_entry(symbol_conf.comm_list, comm))) { unsigned int slen = strlen(comm); if (slen > comms__col_width) { @@ -442,7 +440,7 @@ static size_t perf_session__fprintf_hist_entries(struct perf_session *self, struct rb_node *nd; size_t ret = 0; unsigned int width; - char *col_width = col_width_list_str; + char *col_width = symbol_conf.col_width_list_str; int raw_printing_style; raw_printing_style = !strcmp(pretty_printing_style, "raw"); @@ -468,7 +466,7 @@ static size_t perf_session__fprintf_hist_entries(struct perf_session *self, } width = strlen(se->header); if (se->width) { - if (col_width_list_str) { + if (symbol_conf.col_width_list_str) { if (col_width) { *se->width = atoi(col_width); col_width = strchr(col_width, ','); @@ -587,7 +585,8 @@ static int process_sample_event(event_t *event, struct perf_session *session) dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - if (comm_list && !strlist__has_entry(comm_list, thread->comm)) + if (symbol_conf.comm_list && + !strlist__has_entry(symbol_conf.comm_list, thread->comm)) return 0; cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; @@ -601,14 +600,15 @@ static int process_sample_event(event_t *event, struct perf_session *session) if (al.map && !sort_dso.elide && !al.map->dso->slen_calculated) dso__calc_col_width(al.map->dso); - if (dso_list && + if (symbol_conf.dso_list && (!al.map || !al.map->dso || - !(strlist__has_entry(dso_list, al.map->dso->short_name) || + !(strlist__has_entry(symbol_conf.dso_list, al.map->dso->short_name) || (al.map->dso->short_name != al.map->dso->long_name && - strlist__has_entry(dso_list, al.map->dso->long_name))))) + strlist__has_entry(symbol_conf.dso_list, al.map->dso->long_name))))) return 0; - if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name)) + if (symbol_conf.sym_list && al.sym && + !strlist__has_entry(symbol_conf.sym_list, al.sym->name)) return 0; if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) { @@ -825,13 +825,13 @@ static const struct option options[] = { OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent", "Display callchains using output_type and min percent threshold. " "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt), - OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]", + OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", "only consider symbols in these dsos"), - OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]", + OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", "only consider symbols in these comms"), - OPT_STRING('S', "symbols", &sym_list_str, "symbol[,symbol...]", + OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", "only consider these symbols"), - OPT_STRING('w', "column-widths", &col_width_list_str, + OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str, "width[,width...]", "don't try to adjust column width, use these fixed values"), OPT_STRING('t', "field-separator", &field_sep, "separator", @@ -840,32 +840,25 @@ static const struct option options[] = { OPT_END() }; -static void setup_list(struct strlist **list, const char *list_str, - struct sort_entry *se, const char *list_name, - FILE *fp) +static void sort_entry__setup_elide(struct sort_entry *self, + struct strlist *list, + const char *list_name, FILE *fp) { - if (list_str) { - *list = strlist__new(true, list_str); - if (!*list) { - fprintf(stderr, "problems parsing %s list\n", - list_name); - exit(129); - } - if (strlist__nr_entries(*list) == 1) { - fprintf(fp, "# %s: %s\n", list_name, - strlist__entry(*list, 0)->s); - se->elide = true; - } + if (list && strlist__nr_entries(list) == 1) { + fprintf(fp, "# %s: %s\n", list_name, strlist__entry(list, 0)->s); + self->elide = true; } } int cmd_report(int argc, const char **argv, const char *prefix __used) { + argc = parse_options(argc, argv, options, report_usage, 0); + + setup_pager(); + if (symbol__init() < 0) return -1; - argc = parse_options(argc, argv, options, report_usage, 0); - setup_sorting(report_usage, options); if (parent_pattern != default_parent_pattern) { @@ -880,11 +873,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) if (argc) usage_with_options(report_usage, options); - setup_pager(); - - setup_list(&dso_list, dso_list_str, &sort_dso, "dso", stdout); - setup_list(&comm_list, comm_list_str, &sort_comm, "comm", stdout); - setup_list(&sym_list, sym_list_str, &sort_sym, "symbol", stdout); + sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout); + sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout); + sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout); if (field_sep && *field_sep == '.') { fputs("'.' is the only non valid --field-separator argument\n", diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 9c98b7a2b19a..a589a43112d6 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1137,11 +1137,11 @@ static const struct option options[] = { int cmd_timechart(int argc, const char **argv, const char *prefix __used) { - symbol__init(); - argc = parse_options(argc, argv, options, timechart_usage, PARSE_OPT_STOP_AT_NON_OPTION); + symbol__init(); + if (argc && !strncmp(argv[0], "rec", 3)) return __cmd_record(argc, argv); else if (argc) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 07ad25ca654f..e2285e28720f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -579,13 +579,13 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) exit(-1); } - symbol__init(); - setup_scripting(); argc = parse_options(argc, argv, options, annotate_usage, PARSE_OPT_STOP_AT_NON_OPTION); + if (symbol__init() < 0) + return -1; setup_pager(); session = perf_session__new(input_name, O_RDONLY, 0); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 17ce01269a91..164286ace7df 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1,6 +1,7 @@ #include "util.h" #include "../perf.h" #include "session.h" +#include "sort.h" #include "string.h" #include "symbol.h" #include "thread.h" @@ -1739,6 +1740,20 @@ out_fail: return -1; } +static int setup_list(struct strlist **list, const char *list_str, + const char *list_name) +{ + if (list_str == NULL) + return 0; + + *list = strlist__new(true, list_str); + if (!*list) { + pr_err("problems parsing %s list\n", list_name); + return -1; + } + return 0; +} + int symbol__init(void) { elf_version(EV_CURRENT); @@ -1749,7 +1764,25 @@ int symbol__init(void) if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0) return -1; + if (setup_list(&symbol_conf.dso_list, + symbol_conf.dso_list_str, "dso") < 0) + return -1; + + if (setup_list(&symbol_conf.comm_list, + symbol_conf.comm_list_str, "comm") < 0) + goto out_free_dso_list; + + if (setup_list(&symbol_conf.sym_list, + symbol_conf.sym_list_str, "symbol") < 0) + goto out_free_comm_list; + return 0; + +out_free_dso_list: + strlist__delete(symbol_conf.dso_list); +out_free_comm_list: + strlist__delete(symbol_conf.comm_list); + return -1; } int perf_session__create_kernel_maps(struct perf_session *self) diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 766294735f93..d61f35074997 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -49,12 +49,21 @@ struct symbol { char name[0]; }; +struct strlist; + struct symbol_conf { unsigned short priv_size; bool try_vmlinux_path, use_modules, sort_by_name; const char *vmlinux_name; + char *dso_list_str, + *comm_list_str, + *sym_list_str, + *col_width_list_str; + struct strlist *dso_list, + *comm_list, + *sym_list; }; extern struct symbol_conf symbol_conf; -- cgit v1.2.3