From 47390ae2afb6695c56810a9fc74fb930266addd0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 4 Jun 2013 14:20:28 +0900 Subject: perf script: Adopt latency_format variable It's the only user of the variable, so move it. Signed-off-by: Namhyung Kim Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1370323231-14022-14-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 92d4658f56f..3de8979fe87 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -24,6 +24,7 @@ static u64 last_timestamp; static u64 nr_unordered; extern const struct option record_options[]; static bool no_callchain; +static bool latency_format; static bool system_wide; static const char *cpu_list; static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); -- cgit v1.2.3-70-g09d2 From 6065210db932fd183cbc8bc77558fee275360e71 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 11 Jul 2013 17:28:33 +0200 Subject: perf tools: Remove event types framework completely Removing event types framework completely. The only remainder (apart from few comments) is following enum: enum perf_user_event_type { ... PERF_RECORD_HEADER_EVENT_TYPE = 65, /* deprecated */ ... } It's kept as deprecated, resulting in error when processed in perf_session__process_user_event function. Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1373556513-3000-6-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 7 ---- tools/perf/builtin-record.c | 7 ---- tools/perf/builtin-report.c | 1 - tools/perf/builtin-script.c | 1 - tools/perf/util/event.h | 2 +- tools/perf/util/header.c | 90 --------------------------------------------- tools/perf/util/header.h | 13 ------- tools/perf/util/session.c | 11 ------ tools/perf/util/tool.h | 3 -- 9 files changed, 1 insertion(+), 134 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index ad1296c6f88..1d8de2e4a40 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -67,12 +67,6 @@ static int perf_event__repipe_op2_synth(struct perf_tool *tool, return perf_event__repipe_synth(tool, event); } -static int perf_event__repipe_event_type_synth(struct perf_tool *tool, - union perf_event *event) -{ - return perf_event__repipe_synth(tool, event); -} - static int perf_event__repipe_attr(struct perf_tool *tool, union perf_event *event, struct perf_evlist **pevlist) @@ -402,7 +396,6 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) .throttle = perf_event__repipe, .unthrottle = perf_event__repipe, .attr = perf_event__repipe_attr, - .event_type = perf_event__repipe_event_type_synth, .tracing_data = perf_event__repipe_op2_synth, .finished_round = perf_event__repipe_op2_synth, .build_id = perf_event__repipe_op2_synth, diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 1f5243c1c47..a41ac41546c 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -474,13 +474,6 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) goto out_delete_session; } - err = perf_event__synthesize_event_types(tool, process_synthesized_event, - machine); - if (err < 0) { - pr_err("Couldn't synthesize event_types.\n"); - goto out_delete_session; - } - if (have_tracepoints(&evsel_list->entries)) { /* * FIXME err <= 0 here actually means that diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 188c265751c..a34c587900c 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -741,7 +741,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) .lost = perf_event__process_lost, .read = process_read_event, .attr = perf_event__process_attr, - .event_type = perf_event__process_event_type, .tracing_data = perf_event__process_tracing_data, .build_id = perf_event__process_build_id, .ordered_samples = true, diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 3de8979fe87..ecb697998d3 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -524,7 +524,6 @@ static struct perf_tool perf_script = { .exit = perf_event__process_exit, .fork = perf_event__process_fork, .attr = perf_event__process_attr, - .event_type = perf_event__process_event_type, .tracing_data = perf_event__process_tracing_data, .build_id = perf_event__process_build_id, .ordered_samples = true, diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 181389535c0..1ebb8fb0178 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -116,7 +116,7 @@ struct build_id_event { enum perf_user_event_type { /* above any possible kernel type */ PERF_RECORD_USER_TYPE_START = 64, PERF_RECORD_HEADER_ATTR = 64, - PERF_RECORD_HEADER_EVENT_TYPE = 65, + PERF_RECORD_HEADER_EVENT_TYPE = 65, /* depreceated */ PERF_RECORD_HEADER_TRACING_DATA = 66, PERF_RECORD_HEADER_BUILD_ID = 67, PERF_RECORD_FINISHED_ROUND = 68, diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 88626678bfc..b28a65ecd61 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -25,41 +25,9 @@ static bool no_buildid_cache = false; -static int trace_event_count; -static struct perf_trace_event_type *trace_events; - static u32 header_argc; static const char **header_argv; -int perf_header__push_event(u64 id, const char *name) -{ - struct perf_trace_event_type *nevents; - - if (strlen(name) > MAX_EVENT_NAME) - pr_warning("Event %s will be truncated\n", name); - - nevents = realloc(trace_events, (trace_event_count + 1) * sizeof(*trace_events)); - if (nevents == NULL) - return -ENOMEM; - trace_events = nevents; - - memset(&trace_events[trace_event_count], 0, sizeof(struct perf_trace_event_type)); - trace_events[trace_event_count].event_id = id; - strncpy(trace_events[trace_event_count].name, name, MAX_EVENT_NAME - 1); - trace_event_count++; - return 0; -} - -char *perf_header__find_event(u64 id) -{ - int i; - for (i = 0 ; i < trace_event_count; i++) { - if (trace_events[i].event_id == id) - return trace_events[i].name; - } - return NULL; -} - /* * magic2 = "PERFILE2" * must be a numerical value to let the endianness @@ -2936,64 +2904,6 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, return 0; } -int perf_event__synthesize_event_type(struct perf_tool *tool, - u64 event_id, char *name, - perf_event__handler_t process, - struct machine *machine) -{ - union perf_event ev; - size_t size = 0; - int err = 0; - - memset(&ev, 0, sizeof(ev)); - - ev.event_type.event_type.event_id = event_id; - memset(ev.event_type.event_type.name, 0, MAX_EVENT_NAME); - strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1); - - ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE; - size = strlen(ev.event_type.event_type.name); - size = PERF_ALIGN(size, sizeof(u64)); - ev.event_type.header.size = sizeof(ev.event_type) - - (sizeof(ev.event_type.event_type.name) - size); - - err = process(tool, &ev, NULL, machine); - - return err; -} - -int perf_event__synthesize_event_types(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine) -{ - struct perf_trace_event_type *type; - int i, err = 0; - - for (i = 0; i < trace_event_count; i++) { - type = &trace_events[i]; - - err = perf_event__synthesize_event_type(tool, type->event_id, - type->name, process, - machine); - if (err) { - pr_debug("failed to create perf header event type\n"); - return err; - } - } - - return err; -} - -int perf_event__process_event_type(struct perf_tool *tool __maybe_unused, - union perf_event *event) -{ - if (perf_header__push_event(event->event_type.event_type.event_id, - event->event_type.event_type.name) < 0) - return -ENOMEM; - - return 0; -} - int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct perf_evlist *evlist, perf_event__handler_t process) diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 298982fb195..669fda531da 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -102,9 +102,6 @@ int perf_session__write_header(struct perf_session *session, int fd, bool at_exit); int perf_header__write_pipe(int fd); -int perf_header__push_event(u64 id, const char *name); -char *perf_header__find_event(u64 id); - void perf_header__set_feat(struct perf_header *header, int feat); void perf_header__clear_feat(struct perf_header *header, int feat); bool perf_header__has_feat(const struct perf_header *header, int feat); @@ -132,16 +129,6 @@ int perf_event__synthesize_attrs(struct perf_tool *tool, int perf_event__process_attr(struct perf_tool *tool, union perf_event *event, struct perf_evlist **pevlist); -int perf_event__synthesize_event_type(struct perf_tool *tool, - u64 event_id, char *name, - perf_event__handler_t process, - struct machine *machine); -int perf_event__synthesize_event_types(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine); -int perf_event__process_event_type(struct perf_tool *tool, - union perf_event *event); - int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct perf_evlist *evlist, perf_event__handler_t process); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 1eb58eedcac..d0d9f946a1b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -241,13 +241,6 @@ static int process_finished_round_stub(struct perf_tool *tool __maybe_unused, return 0; } -static int process_event_type_stub(struct perf_tool *tool __maybe_unused, - union perf_event *event __maybe_unused) -{ - dump_printf(": unhandled!\n"); - return 0; -} - static int process_finished_round(struct perf_tool *tool, union perf_event *event, struct perf_session *session); @@ -274,8 +267,6 @@ static void perf_tool__fill_defaults(struct perf_tool *tool) tool->unthrottle = process_event_stub; if (tool->attr == NULL) tool->attr = process_event_synth_attr_stub; - if (tool->event_type == NULL) - tool->event_type = process_event_type_stub; if (tool->tracing_data == NULL) tool->tracing_data = process_event_synth_tracing_data_stub; if (tool->build_id == NULL) @@ -928,8 +919,6 @@ static int perf_session__process_user_event(struct perf_session *session, union if (err == 0) perf_session__set_id_hdr_size(session); return err; - case PERF_RECORD_HEADER_EVENT_TYPE: - return tool->event_type(tool, event); case PERF_RECORD_HEADER_TRACING_DATA: /* setup for reading amidst mmap */ lseek(session->fd, file_offset, SEEK_SET); diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index 88f8cbdb8a3..62b16b6165b 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -22,8 +22,6 @@ typedef int (*event_attr_op)(struct perf_tool *tool, union perf_event *event, struct perf_evlist **pevlist); -typedef int (*event_simple_op)(struct perf_tool *tool, union perf_event *event); - typedef int (*event_op2)(struct perf_tool *tool, union perf_event *event, struct perf_session *session); @@ -39,7 +37,6 @@ struct perf_tool { unthrottle; event_attr_op attr; event_op2 tracing_data; - event_simple_op event_type; event_op2 finished_round, build_id; bool ordered_samples; -- cgit v1.2.3-70-g09d2 From 2eaa1b407aa6592a884f1be061ef61de7012c97a Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 18 Jul 2013 16:06:15 -0600 Subject: perf script: Fix named threads support Commit 73994dc broke named thread support in perf-script. The thread struct in al is the main thread for a multithreaded process. The thread struct used for analysis (e.g., dumping events) should be the specific thread for the sample. Signed-off-by: David Ahern Cc: Feng Tang Link: http://lkml.kernel.org/r/1374185175-28272-1-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 6 +++--- tools/perf/util/scripting-engines/trace-event-perl.c | 14 ++++++++------ tools/perf/util/scripting-engines/trace-event-python.c | 9 +++++---- tools/perf/util/trace-event-scripting.c | 3 ++- tools/perf/util/trace-event.h | 4 +++- 5 files changed, 21 insertions(+), 15 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index ecb697998d3..1cad3701467 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -397,10 +397,10 @@ static void print_sample_bts(union perf_event *event, static void process_event(union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, - struct addr_location *al) + struct thread *thread, + struct addr_location *al __maybe_unused) { struct perf_event_attr *attr = &evsel->attr; - struct thread *thread = al->thread; if (output[attr->type].fields == 0) return; @@ -511,7 +511,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) return 0; - scripting_ops->process_event(event, sample, evsel, machine, &al); + scripting_ops->process_event(event, sample, evsel, machine, thread, &al); evsel->hists.stats.total_period += sample->period; return 0; diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index eacec859f29..a85e4ae5f3a 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -261,7 +261,8 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine __maybe_unused, - struct addr_location *al) + struct thread *thread, + struct addr_location *al) { struct format_field *field; static char handler[256]; @@ -272,7 +273,6 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused, int cpu = sample->cpu; void *data = sample->raw_data; unsigned long long nsecs = sample->time; - struct thread *thread = al->thread; char *comm = thread->comm; dSP; @@ -351,7 +351,8 @@ static void perl_process_event_generic(union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine __maybe_unused, - struct addr_location *al __maybe_unused) + struct thread *thread __maybe_unused, + struct addr_location *al __maybe_unused) { dSP; @@ -377,10 +378,11 @@ static void perl_process_event(union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, - struct addr_location *al) + struct thread *thread, + struct addr_location *al) { - perl_process_tracepoint(event, sample, evsel, machine, al); - perl_process_event_generic(event, sample, evsel, machine, al); + perl_process_tracepoint(event, sample, evsel, machine, thread, al); + perl_process_event_generic(event, sample, evsel, machine, thread, al); } static void run_start_sub(void) diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index e87aa5d9696..cc75a3cef38 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -225,6 +225,7 @@ static void python_process_tracepoint(union perf_event *perf_event struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine __maybe_unused, + struct thread *thread, struct addr_location *al) { PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; @@ -238,7 +239,6 @@ static void python_process_tracepoint(union perf_event *perf_event int cpu = sample->cpu; void *data = sample->raw_data; unsigned long long nsecs = sample->time; - struct thread *thread = al->thread; char *comm = thread->comm; t = PyTuple_New(MAX_FIELDS); @@ -345,12 +345,12 @@ static void python_process_general_event(union perf_event *perf_event struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine __maybe_unused, + struct thread *thread, struct addr_location *al) { PyObject *handler, *retval, *t, *dict; static char handler_name[64]; unsigned n = 0; - struct thread *thread = al->thread; /* * Use the MAX_FIELDS to make the function expandable, though @@ -404,17 +404,18 @@ static void python_process_event(union perf_event *perf_event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, + struct thread *thread, struct addr_location *al) { switch (evsel->attr.type) { case PERF_TYPE_TRACEPOINT: python_process_tracepoint(perf_event, sample, evsel, - machine, al); + machine, thread, al); break; /* Reserve for future process_hw/sw/raw APIs */ default: python_process_general_event(perf_event, sample, evsel, - machine, al); + machine, thread, al); } } diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 8715a1006d0..95199e4eea9 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -39,7 +39,8 @@ static void process_event_unsupported(union perf_event *event __maybe_unused, struct perf_sample *sample __maybe_unused, struct perf_evsel *evsel __maybe_unused, struct machine *machine __maybe_unused, - struct addr_location *al __maybe_unused) + struct thread *thread __maybe_unused, + struct addr_location *al __maybe_unused) { } diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 669a64a660d..fafe1a40444 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -9,6 +9,7 @@ struct machine; struct perf_sample; union perf_event; struct perf_tool; +struct thread; extern struct pevent *perf_pevent; @@ -68,7 +69,8 @@ struct scripting_ops { struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, - struct addr_location *al); + struct thread *thread, + struct addr_location *al); int (*generate_script) (struct pevent *pevent, const char *outfile); }; -- cgit v1.2.3-70-g09d2 From 5b7ba82a75915e739709d0ace4bb559cb280db09 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 7 Aug 2013 14:38:46 +0300 Subject: perf symbols: Load kernel maps before using In order to use kernel maps to read object code, those maps must be adjusted to map to the dso file offset. Because lazy-initialization is used, that is not done until symbols are loaded. However the maps are first used by thread__find_addr_map() before symbols are loaded. So this patch changes thread__find_addr() to "load" kernel maps before using them. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1375875537-4509-3-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-script.c | 4 ++-- tools/perf/tests/code-reading.c | 2 +- tools/perf/util/build-id.c | 2 +- tools/perf/util/event.c | 18 ++++++++++++++---- tools/perf/util/thread.h | 2 +- tools/perf/util/unwind.c | 4 ++-- 7 files changed, 22 insertions(+), 12 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 1d8de2e4a40..f012a98c726 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -206,7 +206,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool, } thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, &al); + event->ip.ip, &al, NULL); if (al.map != NULL) { if (!al.map->dso->hit) { diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 1cad3701467..cd616ff5d22 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -341,10 +341,10 @@ static void print_sample_addr(union perf_event *event, return; thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - sample->addr, &al); + sample->addr, &al, NULL); if (!al.map) thread__find_addr_map(thread, machine, cpumode, MAP__VARIABLE, - sample->addr, &al); + sample->addr, &al, NULL); al.cpu = sample->cpu; al.sym = NULL; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 28bee6285f5..0c7b052cead 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -138,7 +138,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, addr, - &al); + &al, NULL); if (!al.map || !al.map->dso) { pr_debug("thread__find_addr_map failed\n"); return -1; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 5295625c0c0..3a0f5089379 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -33,7 +33,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, } thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, &al); + event->ip.ip, &al, NULL); if (al.map != NULL) al.map->dso->hit = 1; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 95412705d0d..cc7c0c9c9ea 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -592,9 +592,10 @@ int perf_event__process(struct perf_tool *tool __maybe_unused, void thread__find_addr_map(struct thread *self, struct machine *machine, u8 cpumode, enum map_type type, u64 addr, - struct addr_location *al) + struct addr_location *al, symbol_filter_t filter) { struct map_groups *mg = &self->mg; + bool load_map = false; al->thread = self; al->addr = addr; @@ -609,11 +610,13 @@ void thread__find_addr_map(struct thread *self, if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { al->level = 'k'; mg = &machine->kmaps; + load_map = true; } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { al->level = '.'; } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { al->level = 'g'; mg = &machine->kmaps; + load_map = true; } else { /* * 'u' means guest os user space. @@ -654,8 +657,15 @@ try_again: mg = &machine->kmaps; goto try_again; } - } else + } else { + /* + * Kernel maps might be changed when loading symbols so loading + * must be done prior to using kernel maps. + */ + if (load_map) + map__load(al->map, filter); al->addr = al->map->map_ip(al->map, al->addr); + } } void thread__find_addr_location(struct thread *thread, struct machine *machine, @@ -663,7 +673,7 @@ void thread__find_addr_location(struct thread *thread, struct machine *machine, struct addr_location *al, symbol_filter_t filter) { - thread__find_addr_map(thread, machine, cpumode, type, addr, al); + thread__find_addr_map(thread, machine, cpumode, type, addr, al, filter); if (al->map != NULL) al->sym = map__find_symbol(al->map, al->addr, filter); else @@ -699,7 +709,7 @@ int perf_event__preprocess_sample(const union perf_event *event, machine__create_kernel_maps(machine); thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, al); + event->ip.ip, al, filter); dump_printf(" ...... dso: %s\n", al->map ? al->map->dso->long_name : al->level == 'H' ? "[hypervisor]" : ""); diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 0fe1f9c0586..f98d1d98354 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -41,7 +41,7 @@ static inline struct map *thread__find_map(struct thread *self, void thread__find_addr_map(struct thread *thread, struct machine *machine, u8 cpumode, enum map_type type, u64 addr, - struct addr_location *al); + struct addr_location *al, symbol_filter_t filter); void thread__find_addr_location(struct thread *thread, struct machine *machine, u8 cpumode, enum map_type type, u64 addr, diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c index 958723ba3d2..5bbd4947c27 100644 --- a/tools/perf/util/unwind.c +++ b/tools/perf/util/unwind.c @@ -272,7 +272,7 @@ static struct map *find_map(unw_word_t ip, struct unwind_info *ui) struct addr_location al; thread__find_addr_map(ui->thread, ui->machine, PERF_RECORD_MISC_USER, - MAP__FUNCTION, ip, &al); + MAP__FUNCTION, ip, &al, NULL); return al.map; } @@ -349,7 +349,7 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr, ssize_t size; thread__find_addr_map(ui->thread, ui->machine, PERF_RECORD_MISC_USER, - MAP__FUNCTION, addr, &al); + MAP__FUNCTION, addr, &al, NULL); if (!al.map) { pr_debug("unwind: no map for %lx\n", (unsigned long)addr); return -1; -- cgit v1.2.3-70-g09d2 From a6ffaf91302dc1689fc72da0068b87226747fbe0 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Wed, 7 Aug 2013 22:50:51 -0400 Subject: perf tool: Simplify options to perf_evsel__print_ip Make print options based on flags. Simplifies addition of more print options which is the subject of upcoming patches. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1375930261-77273-10-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 27 +++++++++++++++++++++++---- tools/perf/util/session.c | 14 +++++++++++--- tools/perf/util/session.h | 7 ++++++- 3 files changed, 40 insertions(+), 8 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index cd616ff5d22..ee5d6f8b741 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -66,6 +66,7 @@ struct output_option { static struct { bool user_set; bool wildcard_set; + unsigned int print_ip_opts; u64 fields; u64 invalid_fields; } output[PERF_TYPE_MAX] = { @@ -235,6 +236,7 @@ static int perf_session__check_output_opt(struct perf_session *session) { int j; struct perf_evsel *evsel; + struct perf_event_attr *attr; for (j = 0; j < PERF_TYPE_MAX; ++j) { evsel = perf_session__find_first_evtype(session, j); @@ -253,6 +255,24 @@ static int perf_session__check_output_opt(struct perf_session *session) if (evsel && output[j].fields && perf_evsel__check_attr(evsel, session)) return -1; + + if (evsel == NULL) + continue; + + attr = &evsel->attr; + + output[j].print_ip_opts = 0; + if (PRINT_FIELD(IP)) + output[j].print_ip_opts |= PRINT_IP_OPT_IP; + + if (PRINT_FIELD(SYM)) + output[j].print_ip_opts |= PRINT_IP_OPT_SYM; + + if (PRINT_FIELD(DSO)) + output[j].print_ip_opts |= PRINT_IP_OPT_DSO; + + if (PRINT_FIELD(SYMOFFSET)) + output[j].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET; } return 0; @@ -382,8 +402,7 @@ static void print_sample_bts(union perf_event *event, else printf("\n"); perf_evsel__print_ip(evsel, event, sample, machine, - PRINT_FIELD(SYM), PRINT_FIELD(DSO), - PRINT_FIELD(SYMOFFSET)); + output[attr->type].print_ip_opts); } printf(" => "); @@ -423,9 +442,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample, printf(" "); else printf("\n"); + perf_evsel__print_ip(evsel, event, sample, machine, - PRINT_FIELD(SYM), PRINT_FIELD(DSO), - PRINT_FIELD(SYMOFFSET)); + output[attr->type].print_ip_opts); } printf("\n"); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index dedaeb22b7b..e5fd65802ed 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1489,10 +1489,14 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, struct perf_sample *sample, struct machine *machine, - int print_sym, int print_dso, int print_symoffset) + unsigned int print_opts) { struct addr_location al; struct callchain_cursor_node *node; + int print_ip = print_opts & PRINT_IP_OPT_IP; + int print_sym = print_opts & PRINT_IP_OPT_SYM; + int print_dso = print_opts & PRINT_IP_OPT_DSO; + int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET; if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) { @@ -1516,7 +1520,9 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, if (!node) break; - printf("\t%16" PRIx64, node->ip); + if (print_ip) + printf("%16" PRIx64, node->ip); + if (print_sym) { printf(" "); if (print_symoffset) { @@ -1537,7 +1543,9 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, } } else { - printf("%16" PRIx64, sample->ip); + if (print_ip) + printf("%16" PRIx64, sample->ip); + if (print_sym) { printf(" "); if (print_symoffset) diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 8bed17e64a9..69e554a29c1 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -41,6 +41,11 @@ struct perf_session { char filename[1]; }; +#define PRINT_IP_OPT_IP (1<<0) +#define PRINT_IP_OPT_SYM (1<<1) +#define PRINT_IP_OPT_DSO (1<<2) +#define PRINT_IP_OPT_SYMOFFSET (1<<3) + struct perf_tool; struct perf_session *perf_session__new(const char *filename, int mode, @@ -103,7 +108,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, struct perf_sample *sample, struct machine *machine, - int print_sym, int print_dso, int print_symoffset); + unsigned int print_opts); int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap); -- cgit v1.2.3-70-g09d2 From 307cbb92aa2bdc9eed7c74409ff4d5fc9135b4e2 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Wed, 7 Aug 2013 22:50:53 -0400 Subject: perf evsel: Add option to limit stack depth in callchain dumps Option is used by upcoming timehist command. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1375930261-77273-12-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 6 ++++-- tools/perf/util/session.c | 6 ++++-- tools/perf/util/session.h | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index ee5d6f8b741..33b2d830eab 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -402,7 +402,8 @@ static void print_sample_bts(union perf_event *event, else printf("\n"); perf_evsel__print_ip(evsel, event, sample, machine, - output[attr->type].print_ip_opts); + output[attr->type].print_ip_opts, + PERF_MAX_STACK_DEPTH); } printf(" => "); @@ -444,7 +445,8 @@ static void process_event(union perf_event *event, struct perf_sample *sample, printf("\n"); perf_evsel__print_ip(evsel, event, sample, machine, - output[attr->type].print_ip_opts); + output[attr->type].print_ip_opts, + PERF_MAX_STACK_DEPTH); } printf("\n"); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 0d895e7040e..5a8996493d9 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1489,7 +1489,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, struct perf_sample *sample, struct machine *machine, - unsigned int print_opts) + unsigned int print_opts, unsigned int stack_depth) { struct addr_location al; struct callchain_cursor_node *node; @@ -1517,7 +1517,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, } callchain_cursor_commit(&callchain_cursor); - while (1) { + while (stack_depth) { node = callchain_cursor_current(&callchain_cursor); if (!node) break; @@ -1544,6 +1544,8 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, printf("\n"); callchain_cursor_advance(&callchain_cursor); + + stack_depth--; } } else { diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7c00ccb1173..3aa75fb2225 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -109,7 +109,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, struct perf_sample *sample, struct machine *machine, - unsigned int print_opts); + unsigned int print_opts, unsigned int stack_depth); int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap); -- cgit v1.2.3-70-g09d2 From e44baa3ea1eaa09d7d247a9b245fcff06561bf96 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 8 Aug 2013 14:32:25 +0300 Subject: perf tools: Remove filter parameter of perf_event__preprocess_sample() Now that the symbol filter is recorded on the machine there is no need to pass it to perf_event__preprocess_sample(). So remove it. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1375961547-30267-7-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 3 +-- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-mem.c | 3 +-- tools/perf/builtin-report.c | 3 +-- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-top.c | 3 +-- tools/perf/tests/hists_link.c | 4 ++-- tools/perf/util/event.c | 8 ++++---- tools/perf/util/event.h | 3 +-- tools/perf/util/session.c | 3 +-- 10 files changed, 14 insertions(+), 20 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 9754cb140a5..f988d380c52 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -90,8 +90,7 @@ static int process_sample_event(struct perf_tool *tool, struct perf_annotate *ann = container_of(tool, struct perf_annotate, tool); struct addr_location al; - if (perf_event__preprocess_sample(event, machine, &al, sample, - machine->symbol_filter) < 0) { + if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 93de3ac177c..f28799e94f2 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -319,7 +319,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, { struct addr_location al; - if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) { + if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index f96168c769c..706a1faa955 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -68,8 +68,7 @@ dump_raw_samples(struct perf_tool *tool, struct addr_location al; const char *fmt; - if (perf_event__preprocess_sample(event, machine, &al, sample, - NULL) < 0) { + if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { fprintf(stderr, "problem processing %d event, skipping it.\n", event->header.type); return -1; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index f06a5a228c7..958a56a0e39 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -304,8 +304,7 @@ static int process_sample_event(struct perf_tool *tool, struct addr_location al; int ret; - if (perf_event__preprocess_sample(event, machine, &al, sample, - machine->symbol_filter) < 0) { + if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { fprintf(stderr, "problem processing %d event, skipping it.\n", event->header.type); return -1; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 33b2d830eab..a7d623f39c4 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -520,7 +520,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, return 0; } - if (perf_event__preprocess_sample(event, machine, &al, sample, 0) < 0) { + if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { pr_err("problem processing %d event, skipping it.\n", event->header.type); return -1; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index a63ade22cbc..e37521fc715 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -716,8 +716,7 @@ static void perf_event__process_sample(struct perf_tool *tool, if (event->header.misc & PERF_RECORD_MISC_EXACT_IP) top->exact_samples++; - if (perf_event__preprocess_sample(event, machine, &al, sample, - machine->symbol_filter) < 0 || + if (perf_event__preprocess_sample(event, machine, &al, sample) < 0 || al.filtered) return; diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 89085a9615e..50bfb01183e 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -220,7 +220,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) }; if (perf_event__preprocess_sample(&event, machine, &al, - &sample, 0) < 0) + &sample) < 0) goto out; he = __hists__add_entry(&evsel->hists, &al, NULL, 1, 1); @@ -244,7 +244,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) }; if (perf_event__preprocess_sample(&event, machine, &al, - &sample, 0) < 0) + &sample) < 0) goto out; he = __hists__add_entry(&evsel->hists, &al, NULL, 1, 1); diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index cc7c0c9c9ea..f3cf771d362 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -683,8 +683,7 @@ void thread__find_addr_location(struct thread *thread, struct machine *machine, int perf_event__preprocess_sample(const union perf_event *event, struct machine *machine, struct addr_location *al, - struct perf_sample *sample, - symbol_filter_t filter) + struct perf_sample *sample) { u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; struct thread *thread = machine__findnew_thread(machine, event->ip.pid); @@ -709,7 +708,7 @@ int perf_event__preprocess_sample(const union perf_event *event, machine__create_kernel_maps(machine); thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, al, filter); + event->ip.ip, al, machine->symbol_filter); dump_printf(" ...... dso: %s\n", al->map ? al->map->dso->long_name : al->level == 'H' ? "[hypervisor]" : ""); @@ -727,7 +726,8 @@ int perf_event__preprocess_sample(const union perf_event *event, dso->long_name))))) goto out_filtered; - al->sym = map__find_symbol(al->map, al->addr, filter); + al->sym = map__find_symbol(al->map, al->addr, + machine->symbol_filter); } if (symbol_conf.sym_list && diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 6119a649d86..15db071d96b 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -234,8 +234,7 @@ struct addr_location; int perf_event__preprocess_sample(const union perf_event *self, struct machine *machine, struct addr_location *al, - struct perf_sample *sample, - symbol_filter_t filter); + struct perf_sample *sample); const char *perf_event__name(unsigned int id); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 4d9028eef34..de16a773685 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1503,8 +1503,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, int print_oneline = print_opts & PRINT_IP_OPT_ONELINE; char s = print_oneline ? ' ' : '\t'; - if (perf_event__preprocess_sample(event, machine, &al, sample, - NULL) < 0) { + if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { error("problem processing %d event, skipping it.\n", event->header.type); return; -- cgit v1.2.3-70-g09d2 From 326f59bf645ea6c99709c67d9712df46019fa7a8 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 8 Aug 2013 14:32:27 +0300 Subject: perf tools: Remove filter parameter of thread__find_addr_map() Now that the symbol filter is recorded on the machine there is no need to pass it to thread__find_addr_map(). So remove it. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1375961547-30267-9-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-script.c | 4 ++-- tools/perf/tests/code-reading.c | 2 +- tools/perf/util/build-id.c | 2 +- tools/perf/util/event.c | 9 ++++----- tools/perf/util/thread.h | 2 +- tools/perf/util/unwind.c | 4 ++-- 7 files changed, 12 insertions(+), 13 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index f012a98c726..1d8de2e4a40 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -206,7 +206,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool, } thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, &al, NULL); + event->ip.ip, &al); if (al.map != NULL) { if (!al.map->dso->hit) { diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index a7d623f39c4..2ad9d5b6fb3 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -361,10 +361,10 @@ static void print_sample_addr(union perf_event *event, return; thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - sample->addr, &al, NULL); + sample->addr, &al); if (!al.map) thread__find_addr_map(thread, machine, cpumode, MAP__VARIABLE, - sample->addr, &al, NULL); + sample->addr, &al); al.cpu = sample->cpu; al.sym = NULL; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 8e0943b966d..eec1421a7e6 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -147,7 +147,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, addr, - &al, NULL); + &al); if (!al.map || !al.map->dso) { pr_debug("thread__find_addr_map failed\n"); return -1; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 3a0f5089379..5295625c0c0 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -33,7 +33,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, } thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, &al, NULL); + event->ip.ip, &al); if (al.map != NULL) al.map->dso->hit = 1; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 9d301c92310..49713ae4655 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -592,7 +592,7 @@ int perf_event__process(struct perf_tool *tool __maybe_unused, void thread__find_addr_map(struct thread *self, struct machine *machine, u8 cpumode, enum map_type type, u64 addr, - struct addr_location *al, symbol_filter_t filter) + struct addr_location *al) { struct map_groups *mg = &self->mg; bool load_map = false; @@ -663,7 +663,7 @@ try_again: * must be done prior to using kernel maps. */ if (load_map) - map__load(al->map, filter); + map__load(al->map, machine->symbol_filter); al->addr = al->map->map_ip(al->map, al->addr); } } @@ -672,8 +672,7 @@ void thread__find_addr_location(struct thread *thread, struct machine *machine, u8 cpumode, enum map_type type, u64 addr, struct addr_location *al) { - thread__find_addr_map(thread, machine, cpumode, type, addr, al, - machine->symbol_filter); + thread__find_addr_map(thread, machine, cpumode, type, addr, al); if (al->map != NULL) al->sym = map__find_symbol(al->map, al->addr, machine->symbol_filter); @@ -709,7 +708,7 @@ int perf_event__preprocess_sample(const union perf_event *event, machine__create_kernel_maps(machine); thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, al, machine->symbol_filter); + event->ip.ip, al); dump_printf(" ...... dso: %s\n", al->map ? al->map->dso->long_name : al->level == 'H' ? "[hypervisor]" : ""); diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 0ab47d860d4..13c62c90939 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -41,7 +41,7 @@ static inline struct map *thread__find_map(struct thread *self, void thread__find_addr_map(struct thread *thread, struct machine *machine, u8 cpumode, enum map_type type, u64 addr, - struct addr_location *al, symbol_filter_t filter); + struct addr_location *al); void thread__find_addr_location(struct thread *thread, struct machine *machine, u8 cpumode, enum map_type type, u64 addr, diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c index abac3f97d95..2f891f7e70b 100644 --- a/tools/perf/util/unwind.c +++ b/tools/perf/util/unwind.c @@ -272,7 +272,7 @@ static struct map *find_map(unw_word_t ip, struct unwind_info *ui) struct addr_location al; thread__find_addr_map(ui->thread, ui->machine, PERF_RECORD_MISC_USER, - MAP__FUNCTION, ip, &al, NULL); + MAP__FUNCTION, ip, &al); return al.map; } @@ -349,7 +349,7 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr, ssize_t size; thread__find_addr_map(ui->thread, ui->machine, PERF_RECORD_MISC_USER, - MAP__FUNCTION, addr, &al, NULL); + MAP__FUNCTION, addr, &al); if (!al.map) { pr_debug("unwind: no map for %lx\n", (unsigned long)addr); return -1; -- cgit v1.2.3-70-g09d2 From 314add6b1f045b59ca39683bd0cbc5310cd203f2 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 27 Aug 2013 11:23:03 +0300 Subject: perf tools: change machine__findnew_thread() to set thread pid Add a new parameter for 'pid' to machine__findnew_thread(). Change callers to pass 'pid' when it is known. Note that callers sometimes want to find the main thread which has the memory maps. The main thread has tid == pid so the usage in that case is: machine__findnew_thread(machine, pid, pid) whereas the usage to find the specific thread is: machine__findnew_thread(machine, pid, tid) Signed-off-by: Adrian Hunter Acked-by: David Ahern Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1377591794-30553-2-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-kmem.c | 3 ++- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-lock.c | 3 ++- tools/perf/builtin-sched.c | 20 +++++++++++--------- tools/perf/builtin-script.c | 3 ++- tools/perf/builtin-trace.c | 10 +++++++--- tools/perf/tests/code-reading.c | 4 ++-- tools/perf/tests/hists_link.c | 3 ++- tools/perf/util/build-id.c | 7 +++++-- tools/perf/util/event.c | 3 ++- tools/perf/util/machine.c | 22 +++++++++++++++------- tools/perf/util/machine.h | 3 ++- tools/perf/util/session.c | 2 +- 14 files changed, 55 insertions(+), 32 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 1d8de2e4a40..0d4ae1dd7b6 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -198,7 +198,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool, cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - thread = machine__findnew_thread(machine, event->ip.pid); + thread = machine__findnew_thread(machine, event->ip.pid, event->ip.pid); if (thread == NULL) { pr_err("problem processing %d event, skipping it.\n", event->header.type); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index b49f5c58e15..c32477837cb 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -305,7 +305,8 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, struct perf_evsel *evsel, struct machine *machine) { - struct thread *thread = machine__findnew_thread(machine, event->ip.pid); + struct thread *thread = machine__findnew_thread(machine, event->ip.pid, + event->ip.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 6cd4de59be2..47b35407c2f 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -815,7 +815,7 @@ static int process_sample_event(struct perf_tool *tool, if (skip_sample(kvm, sample)) return 0; - thread = machine__findnew_thread(machine, sample->tid); + thread = machine__findnew_thread(machine, sample->pid, sample->tid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 76543a4a7a3..ee33ba2f05d 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -805,7 +805,8 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, struct perf_evsel *evsel, struct machine *machine) { - struct thread *thread = machine__findnew_thread(machine, sample->tid); + struct thread *thread = machine__findnew_thread(machine, sample->pid, + sample->tid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index f809cc7fb7d..d8c51b2f263 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -724,8 +724,10 @@ static int replay_fork_event(struct perf_sched *sched, { struct thread *child, *parent; - child = machine__findnew_thread(machine, event->fork.tid); - parent = machine__findnew_thread(machine, event->fork.ptid); + child = machine__findnew_thread(machine, event->fork.pid, + event->fork.tid); + parent = machine__findnew_thread(machine, event->fork.ppid, + event->fork.ptid); if (child == NULL || parent == NULL) { pr_debug("thread does not exist on fork event: child %p, parent %p\n", @@ -934,8 +936,8 @@ static int latency_switch_event(struct perf_sched *sched, return -1; } - sched_out = machine__findnew_thread(machine, prev_pid); - sched_in = machine__findnew_thread(machine, next_pid); + sched_out = machine__findnew_thread(machine, 0, prev_pid); + sched_in = machine__findnew_thread(machine, 0, next_pid); out_events = thread_atoms_search(&sched->atom_root, sched_out, &sched->cmp_pid); if (!out_events) { @@ -978,7 +980,7 @@ static int latency_runtime_event(struct perf_sched *sched, { const u32 pid = perf_evsel__intval(evsel, sample, "pid"); const u64 runtime = perf_evsel__intval(evsel, sample, "runtime"); - struct thread *thread = machine__findnew_thread(machine, pid); + struct thread *thread = machine__findnew_thread(machine, 0, pid); struct work_atoms *atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid); u64 timestamp = sample->time; int cpu = sample->cpu; @@ -1016,7 +1018,7 @@ static int latency_wakeup_event(struct perf_sched *sched, if (!success) return 0; - wakee = machine__findnew_thread(machine, pid); + wakee = machine__findnew_thread(machine, 0, pid); atoms = thread_atoms_search(&sched->atom_root, wakee, &sched->cmp_pid); if (!atoms) { if (thread_atoms_insert(sched, wakee)) @@ -1070,7 +1072,7 @@ static int latency_migrate_task_event(struct perf_sched *sched, if (sched->profile_cpu == -1) return 0; - migrant = machine__findnew_thread(machine, pid); + migrant = machine__findnew_thread(machine, 0, pid); atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid); if (!atoms) { if (thread_atoms_insert(sched, migrant)) @@ -1289,8 +1291,8 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, return -1; } - sched_out = machine__findnew_thread(machine, prev_pid); - sched_in = machine__findnew_thread(machine, next_pid); + sched_out = machine__findnew_thread(machine, 0, prev_pid); + sched_in = machine__findnew_thread(machine, 0, next_pid); sched->curr_thread[this_cpu] = sched_in; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 2ad9d5b6fb3..d82712f169b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -501,7 +501,8 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, struct machine *machine) { struct addr_location al; - struct thread *thread = machine__findnew_thread(machine, event->ip.tid); + struct thread *thread = machine__findnew_thread(machine, event->ip.pid, + event->ip.tid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index b72afc73f9a..88387c56568 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -521,7 +521,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, if (sc->filtered) return 0; - thread = machine__findnew_thread(&trace->host, sample->tid); + thread = machine__findnew_thread(&trace->host, sample->pid, + sample->tid); ttrace = thread__trace(thread, trace->output); if (ttrace == NULL) return -1; @@ -572,7 +573,8 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, if (sc->filtered) return 0; - thread = machine__findnew_thread(&trace->host, sample->tid); + thread = machine__findnew_thread(&trace->host, sample->pid, + sample->tid); ttrace = thread__trace(thread, trace->output); if (ttrace == NULL) return -1; @@ -628,7 +630,9 @@ static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evs { u64 runtime = perf_evsel__intval(evsel, sample, "runtime"); double runtime_ms = (double)runtime / NSEC_PER_MSEC; - struct thread *thread = machine__findnew_thread(&trace->host, sample->tid); + struct thread *thread = machine__findnew_thread(&trace->host, + sample->pid, + sample->tid); struct thread_trace *ttrace = thread__trace(thread, trace->output); if (ttrace == NULL) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index df9afd9cab4..6fb781d5586 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -257,7 +257,7 @@ static int process_sample_event(struct machine *machine, return -1; } - thread = machine__findnew_thread(machine, sample.pid); + thread = machine__findnew_thread(machine, sample.pid, sample.pid); if (!thread) { pr_debug("machine__findnew_thread failed\n"); return -1; @@ -446,7 +446,7 @@ static int do_test_code_reading(bool try_kcore) goto out_err; } - thread = machine__findnew_thread(machine, pid); + thread = machine__findnew_thread(machine, pid, pid); if (!thread) { pr_debug("machine__findnew_thread failed\n"); goto out_err; diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 50bfb01183e..87f9f7280c4 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -88,7 +88,8 @@ static struct machine *setup_fake_machine(struct machines *machines) for (i = 0; i < ARRAY_SIZE(fake_threads); i++) { struct thread *thread; - thread = machine__findnew_thread(machine, fake_threads[i].pid); + thread = machine__findnew_thread(machine, fake_threads[i].pid, + fake_threads[i].pid); if (thread == NULL) goto out; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 5295625c0c0..0f9d27a6bc8 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -24,7 +24,8 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, { struct addr_location al; u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - struct thread *thread = machine__findnew_thread(machine, event->ip.pid); + struct thread *thread = machine__findnew_thread(machine, event->ip.pid, + event->ip.pid); if (thread == NULL) { pr_err("problem processing %d event, skipping it.\n", @@ -47,7 +48,9 @@ static int perf_event__exit_del_thread(struct perf_tool *tool __maybe_unused, __maybe_unused, struct machine *machine) { - struct thread *thread = machine__findnew_thread(machine, event->fork.tid); + struct thread *thread = machine__findnew_thread(machine, + event->fork.pid, + event->fork.tid); dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid, event->fork.ppid, event->fork.ptid); diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 49713ae4655..61cecf9caff 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -686,7 +686,8 @@ int perf_event__preprocess_sample(const union perf_event *event, struct perf_sample *sample) { u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - struct thread *thread = machine__findnew_thread(machine, event->ip.pid); + struct thread *thread = machine__findnew_thread(machine, event->ip.pid, + event->ip.pid); if (thread == NULL) return -1; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 59486c18062..1dca61f0512 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -32,7 +32,8 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) return -ENOMEM; if (pid != HOST_KERNEL_ID) { - struct thread *thread = machine__findnew_thread(machine, pid); + struct thread *thread = machine__findnew_thread(machine, 0, + pid); char comm[64]; if (thread == NULL) @@ -302,9 +303,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine, return th; } -struct thread *machine__findnew_thread(struct machine *machine, pid_t tid) +struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, + pid_t tid) { - return __machine__findnew_thread(machine, 0, tid, true); + return __machine__findnew_thread(machine, pid, tid, true); } struct thread *machine__find_thread(struct machine *machine, pid_t tid) @@ -314,7 +316,9 @@ struct thread *machine__find_thread(struct machine *machine, pid_t tid) int machine__process_comm_event(struct machine *machine, union perf_event *event) { - struct thread *thread = machine__findnew_thread(machine, event->comm.tid); + struct thread *thread = machine__findnew_thread(machine, + event->comm.pid, + event->comm.tid); if (dump_trace) perf_event__fprintf_comm(event, stdout); @@ -1012,7 +1016,8 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event return 0; } - thread = machine__findnew_thread(machine, event->mmap.pid); + thread = machine__findnew_thread(machine, event->mmap.pid, + event->mmap.pid); if (thread == NULL) goto out_problem; @@ -1051,13 +1056,16 @@ static void machine__remove_thread(struct machine *machine, struct thread *th) int machine__process_fork_event(struct machine *machine, union perf_event *event) { struct thread *thread = machine__find_thread(machine, event->fork.tid); - struct thread *parent = machine__findnew_thread(machine, event->fork.ptid); + struct thread *parent = machine__findnew_thread(machine, + event->fork.ppid, + event->fork.ptid); /* if a thread currently exists for the thread id remove it */ if (thread != NULL) machine__remove_thread(machine, thread); - thread = machine__findnew_thread(machine, event->fork.tid); + thread = machine__findnew_thread(machine, event->fork.pid, + event->fork.tid); if (dump_trace) perf_event__fprintf_task(event, stdout); diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 603ffba999d..0df925ba6a4 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -106,7 +106,8 @@ static inline bool machine__is_host(struct machine *machine) return machine ? machine->pid == HOST_KERNEL_ID : false; } -struct thread *machine__findnew_thread(struct machine *machine, pid_t tid); +struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, + pid_t tid); size_t machine__fprintf(struct machine *machine, FILE *fp); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index de16a773685..57b6f38f246 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1099,7 +1099,7 @@ void perf_event_header__bswap(struct perf_event_header *self) struct thread *perf_session__findnew(struct perf_session *session, pid_t pid) { - return machine__findnew_thread(&session->machines.host, pid); + return machine__findnew_thread(&session->machines.host, 0, pid); } static struct thread *perf_session__register_idle_thread(struct perf_session *self) -- cgit v1.2.3-70-g09d2 From ef89325f773bc9f2f4e6019bd7f3d968ba85df9a Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 27 Aug 2013 11:23:06 +0300 Subject: perf tools: Remove references to struct ip_event The ip_event struct assumes fixed positions for ip, pid and tid. That is no longer true with the addition of PERF_SAMPLE_IDENTIFIER. The information is anyway in struct sample, so use that instead. Signed-off-by: Adrian Hunter Acked-by: Namhyung Kim Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1377591794-30553-5-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 4 ++-- tools/perf/builtin-kmem.c | 4 ++-- tools/perf/builtin-mem.c | 2 +- tools/perf/builtin-script.c | 4 ++-- tools/perf/builtin-top.c | 11 ++++++----- tools/perf/tests/hists_link.c | 20 ++++++++------------ tools/perf/util/build-id.c | 8 ++++---- tools/perf/util/event.c | 6 +++--- tools/perf/util/event.h | 11 ----------- tools/perf/util/evsel.c | 4 ++-- tools/perf/util/session.c | 8 +++++--- 11 files changed, 35 insertions(+), 47 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 0d4ae1dd7b6..ffacd464f9f 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -198,7 +198,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool, cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - thread = machine__findnew_thread(machine, event->ip.pid, event->ip.pid); + thread = machine__findnew_thread(machine, sample->pid, sample->pid); if (thread == NULL) { pr_err("problem processing %d event, skipping it.\n", event->header.type); @@ -206,7 +206,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool, } thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, &al); + sample->ip, &al); if (al.map != NULL) { if (!al.map->dso->hit) { diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index c32477837cb..c2dff9cb1f2 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -305,8 +305,8 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, struct perf_evsel *evsel, struct machine *machine) { - struct thread *thread = machine__findnew_thread(machine, event->ip.pid, - event->ip.pid); + struct thread *thread = machine__findnew_thread(machine, sample->pid, + sample->pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 706a1faa955..791b432df84 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -94,7 +94,7 @@ dump_raw_samples(struct perf_tool *tool, symbol_conf.field_sep, sample->tid, symbol_conf.field_sep, - event->ip.ip, + sample->ip, symbol_conf.field_sep, sample->addr, symbol_conf.field_sep, diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index d82712f169b..93a34cef967 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -501,8 +501,8 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, struct machine *machine) { struct addr_location al; - struct thread *thread = machine__findnew_thread(machine, event->ip.pid, - event->ip.tid); + struct thread *thread = machine__findnew_thread(machine, sample->pid, + sample->tid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e37521fc715..212214162bb 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -689,7 +689,7 @@ static void perf_event__process_sample(struct perf_tool *tool, { struct perf_top *top = container_of(tool, struct perf_top, tool); struct symbol *parent = NULL; - u64 ip = event->ip.ip; + u64 ip = sample->ip; struct addr_location al; int err; @@ -699,10 +699,10 @@ static void perf_event__process_sample(struct perf_tool *tool, if (!seen) seen = intlist__new(NULL); - if (!intlist__has_entry(seen, event->ip.pid)) { + if (!intlist__has_entry(seen, sample->pid)) { pr_err("Can't find guest [%d]'s kernel information\n", - event->ip.pid); - intlist__add(seen, event->ip.pid); + sample->pid); + intlist__add(seen, sample->pid); } return; } @@ -836,7 +836,8 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) break; case PERF_RECORD_MISC_GUEST_KERNEL: ++top->guest_kernel_samples; - machine = perf_session__find_machine(session, event->ip.pid); + machine = perf_session__find_machine(session, + sample.pid); break; case PERF_RECORD_MISC_GUEST_USER: ++top->guest_us_samples; diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 87f9f7280c4..4228ffc0d96 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -211,15 +211,13 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) list_for_each_entry(evsel, &evlist->entries, node) { for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) { const union perf_event event = { - .ip = { - .header = { - .misc = PERF_RECORD_MISC_USER, - }, - .pid = fake_common_samples[k].pid, - .ip = fake_common_samples[k].ip, + .header = { + .misc = PERF_RECORD_MISC_USER, }, }; + sample.pid = fake_common_samples[k].pid; + sample.ip = fake_common_samples[k].ip; if (perf_event__preprocess_sample(&event, machine, &al, &sample) < 0) goto out; @@ -235,15 +233,13 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) for (k = 0; k < ARRAY_SIZE(fake_samples[i]); k++) { const union perf_event event = { - .ip = { - .header = { - .misc = PERF_RECORD_MISC_USER, - }, - .pid = fake_samples[i][k].pid, - .ip = fake_samples[i][k].ip, + .header = { + .misc = PERF_RECORD_MISC_USER, }, }; + sample.pid = fake_samples[i][k].pid; + sample.ip = fake_samples[i][k].ip; if (perf_event__preprocess_sample(&event, machine, &al, &sample) < 0) goto out; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 0f9d27a6bc8..fb584092eb8 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -18,14 +18,14 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, union perf_event *event, - struct perf_sample *sample __maybe_unused, + struct perf_sample *sample, struct perf_evsel *evsel __maybe_unused, struct machine *machine) { struct addr_location al; u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - struct thread *thread = machine__findnew_thread(machine, event->ip.pid, - event->ip.pid); + struct thread *thread = machine__findnew_thread(machine, sample->pid, + sample->pid); if (thread == NULL) { pr_err("problem processing %d event, skipping it.\n", @@ -34,7 +34,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, } thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, &al); + sample->ip, &al); if (al.map != NULL) al.map->dso->hit = 1; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 61cecf9caff..8d51f21107a 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -686,8 +686,8 @@ int perf_event__preprocess_sample(const union perf_event *event, struct perf_sample *sample) { u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - struct thread *thread = machine__findnew_thread(machine, event->ip.pid, - event->ip.pid); + struct thread *thread = machine__findnew_thread(machine, sample->pid, + sample->pid); if (thread == NULL) return -1; @@ -709,7 +709,7 @@ int perf_event__preprocess_sample(const union perf_event *event, machine__create_kernel_maps(machine); thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, - event->ip.ip, al); + sample->ip, al); dump_printf(" ...... dso: %s\n", al->map ? al->map->dso->long_name : al->level == 'H' ? "[hypervisor]" : ""); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 15db071d96b..19d911c011c 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -8,16 +8,6 @@ #include "map.h" #include "build-id.h" -/* - * PERF_SAMPLE_IP | PERF_SAMPLE_TID | * - */ -struct ip_event { - struct perf_event_header header; - u64 ip; - u32 pid, tid; - unsigned char __more_data[]; -}; - struct mmap_event { struct perf_event_header header; u32 pid, tid; @@ -166,7 +156,6 @@ struct tracing_data_event { union perf_event { struct perf_event_header header; - struct ip_event ip; struct mmap_event mmap; struct comm_event comm; struct fork_event fork; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 9a5fb23ff8e..7e328c47f3b 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1185,7 +1185,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, return -EFAULT; if (type & PERF_SAMPLE_IP) { - data->ip = event->ip.ip; + data->ip = *array; array++; } @@ -1397,7 +1397,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, array = event->sample.array; if (type & PERF_SAMPLE_IP) { - event->ip.ip = sample->ip; + *array = sample->ip; array++; } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 07590c3c68b..c3ac483be48 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -840,7 +840,8 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event, static struct machine * perf_session__find_machine_for_cpumode(struct perf_session *session, - union perf_event *event) + union perf_event *event, + struct perf_sample *sample) { const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; @@ -852,7 +853,7 @@ static struct machine * if (event->header.type == PERF_RECORD_MMAP) pid = event->mmap.pid; else - pid = event->ip.pid; + pid = sample->pid; return perf_session__findnew_machine(session, pid); } @@ -958,7 +959,8 @@ static int perf_session_deliver_event(struct perf_session *session, hists__inc_nr_events(&evsel->hists, event->header.type); } - machine = perf_session__find_machine_for_cpumode(session, event); + machine = perf_session__find_machine_for_cpumode(session, event, + sample); switch (event->header.type) { case PERF_RECORD_SAMPLE: -- cgit v1.2.3-70-g09d2 From 5c5e854bc760a2e2c878df3cfcf2afa4febcd511 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Wed, 21 Aug 2013 12:10:25 +0200 Subject: perf tools: Add attr->mmap2 support This patch adds support for the new PERF_RECORD_MMAP2 record type exposed by the kernel. This is an extended PERF_RECORD_MMAP record. It adds for each file-backed mapping the device major, minor number and the inode number and generation. This triplet uniquely identifies the source of a file-backed mapping. It can be used to detect identical virtual mappings between processes, for instance. The patch will prefer MMAP2 over MMAP. Signed-off-by: Stephane Eranian Cc: Andi Kleen Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1377079825-19057-3-git-send-email-eranian@google.com [ Cope with 314add6 "Change machine__findnew_thread() to set thread pid", fix 'perf test' regression test entry affected, use perf_missing_features.mmap2 to fallback to not using .mmap2 in older kernels, so that new tools can work with kernels where this feature is not present ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 1 + tools/perf/builtin-inject.c | 15 +++++++++++ tools/perf/builtin-mem.c | 1 + tools/perf/builtin-report.c | 1 + tools/perf/builtin-script.c | 1 + tools/perf/tests/perf-record.c | 15 ++++++++--- tools/perf/util/build-id.c | 1 + tools/perf/util/event.c | 56 +++++++++++++++++++++++++++++++++--------- tools/perf/util/event.h | 19 ++++++++++++++ tools/perf/util/evsel.c | 16 +++++++++--- tools/perf/util/header.c | 3 +++ tools/perf/util/machine.c | 53 ++++++++++++++++++++++++++++++++++++++- tools/perf/util/machine.h | 1 + tools/perf/util/map.c | 8 +++++- tools/perf/util/map.h | 8 ++++-- tools/perf/util/session.c | 25 ++++++++++++++++++- tools/perf/util/tool.h | 1 + 17 files changed, 200 insertions(+), 25 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index f988d380c52..5ebd0c3b71b 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -277,6 +277,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) .tool = { .sample = process_sample_event, .mmap = perf_event__process_mmap, + .mmap2 = perf_event__process_mmap2, .comm = perf_event__process_comm, .exit = perf_event__process_exit, .fork = perf_event__process_fork, diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 9b336fdb6f7..423875c999b 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -123,6 +123,19 @@ static int perf_event__repipe_mmap(struct perf_tool *tool, return err; } +static int perf_event__repipe_mmap2(struct perf_tool *tool, + union perf_event *event, + struct perf_sample *sample, + struct machine *machine) +{ + int err; + + err = perf_event__process_mmap2(tool, event, sample, machine); + perf_event__repipe(tool, event, sample, machine); + + return err; +} + static int perf_event__repipe_fork(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -339,6 +352,7 @@ static int __cmd_inject(struct perf_inject *inject) if (inject->build_ids || inject->sched_stat) { inject->tool.mmap = perf_event__repipe_mmap; + inject->tool.mmap2 = perf_event__repipe_mmap2; inject->tool.fork = perf_event__repipe_fork; inject->tool.tracing_data = perf_event__repipe_tracing_data; } @@ -390,6 +404,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) .tool = { .sample = perf_event__repipe_sample, .mmap = perf_event__repipe, + .mmap2 = perf_event__repipe, .comm = perf_event__repipe, .fork = perf_event__repipe, .exit = perf_event__repipe, diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 791b432df84..253133a6251 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -190,6 +190,7 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused) .tool = { .sample = process_sample_event, .mmap = perf_event__process_mmap, + .mmap2 = perf_event__process_mmap2, .comm = perf_event__process_comm, .lost = perf_event__process_lost, .fork = perf_event__process_fork, diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 9725aa37541..8e50d8d7741 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -744,6 +744,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) .tool = { .sample = process_sample_event, .mmap = perf_event__process_mmap, + .mmap2 = perf_event__process_mmap2, .comm = perf_event__process_comm, .exit = perf_event__process_exit, .fork = perf_event__process_fork, diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 93a34cef967..7f31a3ded1b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -542,6 +542,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, static struct perf_tool perf_script = { .sample = process_sample_event, .mmap = perf_event__process_mmap, + .mmap2 = perf_event__process_mmap2, .comm = perf_event__process_comm, .exit = perf_event__process_exit, .fork = perf_event__process_fork, diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 72d8881873b..b8a7056519a 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -50,7 +50,7 @@ int test__PERF_RECORD(void) struct perf_sample sample; const char *cmd = "sleep"; const char *argv[] = { cmd, "1", NULL, }; - char *bname; + char *bname, *mmap_filename; u64 prev_time = 0; bool found_cmd_mmap = false, found_libc_mmap = false, @@ -212,6 +212,7 @@ int test__PERF_RECORD(void) if ((type == PERF_RECORD_COMM || type == PERF_RECORD_MMAP || + type == PERF_RECORD_MMAP2 || type == PERF_RECORD_FORK || type == PERF_RECORD_EXIT) && (pid_t)event->comm.pid != evlist->workload.pid) { @@ -220,7 +221,8 @@ int test__PERF_RECORD(void) } if ((type == PERF_RECORD_COMM || - type == PERF_RECORD_MMAP) && + type == PERF_RECORD_MMAP || + type == PERF_RECORD_MMAP2) && event->comm.pid != event->comm.tid) { pr_debug("%s with different pid/tid!\n", name); ++errs; @@ -236,7 +238,12 @@ int test__PERF_RECORD(void) case PERF_RECORD_EXIT: goto found_exit; case PERF_RECORD_MMAP: - bname = strrchr(event->mmap.filename, '/'); + mmap_filename = event->mmap.filename; + goto check_bname; + case PERF_RECORD_MMAP2: + mmap_filename = event->mmap2.filename; + check_bname: + bname = strrchr(mmap_filename, '/'); if (bname != NULL) { if (!found_cmd_mmap) found_cmd_mmap = !strcmp(bname + 1, cmd); @@ -245,7 +252,7 @@ int test__PERF_RECORD(void) if (!found_ld_mmap) found_ld_mmap = !strncmp(bname + 1, "ld", 2); } else if (!found_vdso_mmap) - found_vdso_mmap = !strcmp(event->mmap.filename, "[vdso]"); + found_vdso_mmap = !strcmp(mmap_filename, "[vdso]"); break; case PERF_RECORD_SAMPLE: diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index fb584092eb8..7ded71d19d7 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -67,6 +67,7 @@ static int perf_event__exit_del_thread(struct perf_tool *tool __maybe_unused, struct perf_tool build_id__mark_dso_hit_ops = { .sample = build_id__mark_dso_hit, .mmap = perf_event__process_mmap, + .mmap2 = perf_event__process_mmap2, .fork = perf_event__process_fork, .exit = perf_event__exit_del_thread, .attr = perf_event__process_attr, diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 8d51f21107a..9b393e7dca6 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -11,6 +11,7 @@ static const char *perf_event__names[] = { [0] = "TOTAL", [PERF_RECORD_MMAP] = "MMAP", + [PERF_RECORD_MMAP2] = "MMAP2", [PERF_RECORD_LOST] = "LOST", [PERF_RECORD_COMM] = "COMM", [PERF_RECORD_EXIT] = "EXIT", @@ -186,7 +187,7 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, return -1; } - event->header.type = PERF_RECORD_MMAP; + event->header.type = PERF_RECORD_MMAP2; /* * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c */ @@ -197,7 +198,9 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, char prot[5]; char execname[PATH_MAX]; char anonstr[] = "//anon"; + unsigned int ino; size_t size; + ssize_t n; if (fgets(bf, sizeof(bf), fp) == NULL) break; @@ -206,9 +209,16 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, strcpy(execname, ""); /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ - sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n", - &event->mmap.start, &event->mmap.len, prot, - &event->mmap.pgoff, execname); + n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %s\n", + &event->mmap2.start, &event->mmap2.len, prot, + &event->mmap2.pgoff, &event->mmap2.maj, + &event->mmap2.min, + &ino, execname); + + event->mmap2.ino = (u64)ino; + + if (n != 8) + continue; if (prot[2] != 'x') continue; @@ -217,15 +227,15 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, strcpy(execname, anonstr); size = strlen(execname) + 1; - memcpy(event->mmap.filename, execname, size); + memcpy(event->mmap2.filename, execname, size); size = PERF_ALIGN(size, sizeof(u64)); - event->mmap.len -= event->mmap.start; - event->mmap.header.size = (sizeof(event->mmap) - - (sizeof(event->mmap.filename) - size)); - memset(event->mmap.filename + size, 0, machine->id_hdr_size); - event->mmap.header.size += machine->id_hdr_size; - event->mmap.pid = tgid; - event->mmap.tid = pid; + event->mmap2.len -= event->mmap.start; + event->mmap2.header.size = (sizeof(event->mmap2) - + (sizeof(event->mmap2.filename) - size)); + memset(event->mmap2.filename + size, 0, machine->id_hdr_size); + event->mmap2.header.size += machine->id_hdr_size; + event->mmap2.pid = tgid; + event->mmap2.tid = pid; if (process(tool, event, &synth_sample, machine) != 0) { rc = -1; @@ -527,6 +537,17 @@ size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) event->mmap.len, event->mmap.pgoff, event->mmap.filename); } +size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) +{ + return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 + " %02x:%02x %"PRIu64" %"PRIu64"]: %s\n", + event->mmap2.pid, event->mmap2.tid, event->mmap2.start, + event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj, + event->mmap2.min, event->mmap2.ino, + event->mmap2.ino_generation, + event->mmap2.filename); +} + int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused, @@ -535,6 +556,14 @@ int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, return machine__process_mmap_event(machine, event); } +int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, + union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine) +{ + return machine__process_mmap2_event(machine, event); +} + size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) { return fprintf(fp, "(%d:%d):(%d:%d)\n", @@ -574,6 +603,9 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp) case PERF_RECORD_MMAP: ret += perf_event__fprintf_mmap(event, fp); break; + case PERF_RECORD_MMAP2: + ret += perf_event__fprintf_mmap2(event, fp); + break; default: ret += fprintf(fp, "\n"); } diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 93130d856bf..c67ecc457d2 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -17,6 +17,19 @@ struct mmap_event { char filename[PATH_MAX]; }; +struct mmap2_event { + struct perf_event_header header; + u32 pid, tid; + u64 start; + u64 len; + u64 pgoff; + u32 maj; + u32 min; + u64 ino; + u64 ino_generation; + char filename[PATH_MAX]; +}; + struct comm_event { struct perf_event_header header; u32 pid, tid; @@ -159,6 +172,7 @@ struct tracing_data_event { union perf_event { struct perf_event_header header; struct mmap_event mmap; + struct mmap2_event mmap2; struct comm_event comm; struct fork_event fork; struct lost_event lost; @@ -208,6 +222,10 @@ int perf_event__process_mmap(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine); +int perf_event__process_mmap2(struct perf_tool *tool, + union perf_event *event, + struct perf_sample *sample, + struct machine *machine); int perf_event__process_fork(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -238,6 +256,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp); size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp); +size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp); size_t perf_event__fprintf_task(union perf_event *event, FILE *fp); size_t perf_event__fprintf(union perf_event *event, FILE *fp); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 3612183e2cc..0ce9febf1ba 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -27,6 +27,7 @@ static struct { bool sample_id_all; bool exclude_guest; + bool mmap2; } perf_missing_features; #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) @@ -676,8 +677,9 @@ void perf_evsel__config(struct perf_evsel *evsel, if (opts->sample_weight) attr->sample_type |= PERF_SAMPLE_WEIGHT; - attr->mmap = track; - attr->comm = track; + attr->mmap = track; + attr->mmap2 = track && !perf_missing_features.mmap2; + attr->comm = track; /* * XXX see the function comment above @@ -1016,6 +1018,8 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, } fallback_missing_features: + if (perf_missing_features.mmap2) + evsel->attr.mmap2 = 0; if (perf_missing_features.exclude_guest) evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; retry_sample_id: @@ -1080,8 +1084,11 @@ try_fallback: if (err != -EINVAL || cpu > 0 || thread > 0) goto out_close; - if (!perf_missing_features.exclude_guest && - (evsel->attr.exclude_guest || evsel->attr.exclude_host)) { + if (!perf_missing_features.mmap2 && evsel->attr.mmap2) { + perf_missing_features.mmap2 = true; + goto fallback_missing_features; + } else if (!perf_missing_features.exclude_guest && + (evsel->attr.exclude_guest || evsel->attr.exclude_host)) { perf_missing_features.exclude_guest = true; goto fallback_missing_features; } else if (!perf_missing_features.sample_id_all) { @@ -1925,6 +1932,7 @@ int perf_evsel__fprintf(struct perf_evsel *evsel, if_print(exclude_hv); if_print(exclude_idle); if_print(mmap); + if_print(mmap2); if_print(comm); if_print(freq); if_print(inherit_stat); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index a33197a4fd2..26441d0e571 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1351,6 +1351,9 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) fprintf(fp, ", precise_ip = %d", evsel->attr.precise_ip); + fprintf(fp, ", attr_mmap2 = %d", evsel->attr.mmap2); + fprintf(fp, ", attr_mmap = %d", evsel->attr.mmap); + fprintf(fp, ", attr_mmap_data = %d", evsel->attr.mmap_data); if (evsel->ids) { fprintf(fp, ", id = {"); for (j = 0, id = evsel->id; j < evsel->ids; j++, id++) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 1dca61f0512..933d14f287c 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -997,6 +997,54 @@ out_problem: return -1; } +int machine__process_mmap2_event(struct machine *machine, + union perf_event *event) +{ + u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; + struct thread *thread; + struct map *map; + enum map_type type; + int ret = 0; + + if (dump_trace) + perf_event__fprintf_mmap2(event, stdout); + + if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || + cpumode == PERF_RECORD_MISC_KERNEL) { + ret = machine__process_kernel_mmap_event(machine, event); + if (ret < 0) + goto out_problem; + return 0; + } + + thread = machine__findnew_thread(machine, event->mmap2.pid, + event->mmap2.pid); + if (thread == NULL) + goto out_problem; + + if (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) + type = MAP__VARIABLE; + else + type = MAP__FUNCTION; + + map = map__new(&machine->user_dsos, event->mmap2.start, + event->mmap2.len, event->mmap2.pgoff, + event->mmap2.pid, event->mmap2.maj, + event->mmap2.min, event->mmap2.ino, + event->mmap2.ino_generation, + event->mmap2.filename, type); + + if (map == NULL) + goto out_problem; + + thread__insert_map(thread, map); + return 0; + +out_problem: + dump_printf("problem processing PERF_RECORD_MMAP2, skipping event.\n"); + return 0; +} + int machine__process_mmap_event(struct machine *machine, union perf_event *event) { u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; @@ -1028,7 +1076,8 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event map = map__new(&machine->user_dsos, event->mmap.start, event->mmap.len, event->mmap.pgoff, - event->mmap.pid, event->mmap.filename, + event->mmap.pid, 0, 0, 0, 0, + event->mmap.filename, type); if (map == NULL) @@ -1101,6 +1150,8 @@ int machine__process_event(struct machine *machine, union perf_event *event) ret = machine__process_comm_event(machine, event); break; case PERF_RECORD_MMAP: ret = machine__process_mmap_event(machine, event); break; + case PERF_RECORD_MMAP2: + ret = machine__process_mmap2_event(machine, event); break; case PERF_RECORD_FORK: ret = machine__process_fork_event(machine, event); break; case PERF_RECORD_EXIT: diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 0df925ba6a4..58a6be1fc73 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -45,6 +45,7 @@ int machine__process_exit_event(struct machine *machine, union perf_event *event int machine__process_fork_event(struct machine *machine, union perf_event *event); int machine__process_lost_event(struct machine *machine, union perf_event *event); int machine__process_mmap_event(struct machine *machine, union perf_event *event); +int machine__process_mmap2_event(struct machine *machine, union perf_event *event); int machine__process_event(struct machine *machine, union perf_event *event); typedef void (*machine__process_t)(struct machine *machine, void *data); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 9e8304ca343..4f6680d2043 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -48,7 +48,8 @@ void map__init(struct map *map, enum map_type type, } struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, - u64 pgoff, u32 pid, char *filename, + u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino, + u64 ino_gen, char *filename, enum map_type type) { struct map *map = malloc(sizeof(*map)); @@ -62,6 +63,11 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, vdso = is_vdso_map(filename); no_dso = is_no_dso_memory(filename); + map->maj = d_maj; + map->min = d_min; + map->ino = ino; + map->ino_generation = ino_gen; + if (anon) { snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid); filename = newfilename; diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 2cc93cbf0e1..4886ca28053 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -36,6 +36,9 @@ struct map { bool erange_warned; u32 priv; u64 pgoff; + u32 maj, min; /* only valid for MMAP2 record */ + u64 ino; /* only valid for MMAP2 record */ + u64 ino_generation;/* only valid for MMAP2 record */ /* ip -> dso rip */ u64 (*map_ip)(struct map *, u64); @@ -88,8 +91,9 @@ typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); void map__init(struct map *map, enum map_type type, u64 start, u64 end, u64 pgoff, struct dso *dso); struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, - u64 pgoff, u32 pid, char *filename, - enum map_type type); + u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino, + u64 ino_gen, + char *filename, enum map_type type); struct map *map__new2(u64 start, struct dso *dso, enum map_type type); void map__delete(struct map *map); struct map *map__clone(struct map *map); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 0308d9ee7a7..51f5edf2a6d 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -351,6 +351,25 @@ static void perf_event__mmap_swap(union perf_event *event, } } +static void perf_event__mmap2_swap(union perf_event *event, + bool sample_id_all) +{ + event->mmap2.pid = bswap_32(event->mmap2.pid); + event->mmap2.tid = bswap_32(event->mmap2.tid); + event->mmap2.start = bswap_64(event->mmap2.start); + event->mmap2.len = bswap_64(event->mmap2.len); + event->mmap2.pgoff = bswap_64(event->mmap2.pgoff); + event->mmap2.maj = bswap_32(event->mmap2.maj); + event->mmap2.min = bswap_32(event->mmap2.min); + event->mmap2.ino = bswap_64(event->mmap2.ino); + + if (sample_id_all) { + void *data = &event->mmap2.filename; + + data += PERF_ALIGN(strlen(data) + 1, sizeof(u64)); + swap_sample_id_all(event, data); + } +} static void perf_event__task_swap(union perf_event *event, bool sample_id_all) { event->fork.pid = bswap_32(event->fork.pid); @@ -455,6 +474,7 @@ typedef void (*perf_event__swap_op)(union perf_event *event, static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_MMAP] = perf_event__mmap_swap, + [PERF_RECORD_MMAP2] = perf_event__mmap2_swap, [PERF_RECORD_COMM] = perf_event__comm_swap, [PERF_RECORD_FORK] = perf_event__task_swap, [PERF_RECORD_EXIT] = perf_event__task_swap, @@ -851,7 +871,8 @@ static struct machine * (cpumode == PERF_RECORD_MISC_GUEST_USER))) { u32 pid; - if (event->header.type == PERF_RECORD_MMAP) + if (event->header.type == PERF_RECORD_MMAP + || event->header.type == PERF_RECORD_MMAP2) pid = event->mmap.pid; else pid = sample->pid; @@ -978,6 +999,8 @@ static int perf_session_deliver_event(struct perf_session *session, sample, evsel, machine); case PERF_RECORD_MMAP: return tool->mmap(tool, event, sample, machine); + case PERF_RECORD_MMAP2: + return tool->mmap2(tool, event, sample, machine); case PERF_RECORD_COMM: return tool->comm(tool, event, sample, machine); case PERF_RECORD_FORK: diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index 62b16b6165b..4385816d3d4 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -29,6 +29,7 @@ struct perf_tool { event_sample sample, read; event_op mmap, + mmap2, comm, fork, exit, -- cgit v1.2.3-70-g09d2 From 33e940a25daaea71be054e8a4bdb61730cc9ebbc Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 17 Sep 2013 16:34:28 -0300 Subject: perf session: Check for SIGINT in more loops When processing big files we were not checking if session_done was set by the SIGINT signal handler, for instance in 'perf report'. Fix it. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-pyad42lgrtq7xhg2dpsoauq7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 2 -- tools/perf/builtin-report.c | 5 +++-- tools/perf/builtin-script.c | 2 -- tools/perf/util/hist.c | 2 ++ tools/perf/util/session.c | 9 +++++++-- tools/perf/util/session.h | 4 ++++ 6 files changed, 16 insertions(+), 8 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 423875c999b..afe377b2884 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -321,8 +321,6 @@ found: return perf_event__repipe(tool, event_sw, &sample_sw, machine); } -extern volatile int session_done; - static void sig_handler(int sig __maybe_unused) { session_done = 1; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 8e50d8d7741..72eae7498c0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -401,8 +401,6 @@ static int perf_report__setup_sample_type(struct perf_report *rep) return 0; } -extern volatile int session_done; - static void sig_handler(int sig __maybe_unused) { session_done = 1; @@ -568,6 +566,9 @@ static int __cmd_report(struct perf_report *rep) } } + if (session_done()) + return 0; + if (nr_samples == 0) { ui__error("The %s file has no samples!\n", session->filename); return 0; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 7f31a3ded1b..9c333ff3dfe 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -553,8 +553,6 @@ static struct perf_tool perf_script = { .ordering_requires_timestamps = true, }; -extern volatile int session_done; - static void sig_handler(int sig __maybe_unused) { session_done = 1; diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 46a0d35a05e..9ff6cf3e9a9 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -611,6 +611,8 @@ void hists__collapse_resort(struct hists *hists) next = rb_first(root); while (next) { + if (session_done()) + break; n = rb_entry(next, struct hist_entry, rb_node_in); next = rb_next(&n->rb_node_in); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 51f5edf2a6d..70ffa41518f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -531,6 +531,9 @@ static int flush_sample_queue(struct perf_session *s, return 0; list_for_each_entry_safe(iter, tmp, head, list) { + if (session_done()) + return 0; + if (iter->timestamp > limit) break; @@ -1160,7 +1163,6 @@ static void perf_session__warn_about_errors(const struct perf_session *session, } } -#define session_done() (*(volatile int *)(&session_done)) volatile int session_done; static int __perf_session__process_pipe_events(struct perf_session *self, @@ -1372,10 +1374,13 @@ more: "Processing events..."); } + err = 0; + if (session_done()) + goto out_err; + if (file_pos < file_size) goto more; - err = 0; /* do the final flush for ordered samples */ session->ordered_samples.next_flush = ULLONG_MAX; err = flush_sample_queue(session, tool); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 3aa75fb2225..04bf7373a7e 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -124,4 +124,8 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session, #define perf_session__set_tracepoints_handlers(session, array) \ __perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(array)) + +extern volatile int session_done; + +#define session_done() (*(volatile int *)(&session_done)) #endif /* __PERF_SESSION_H */ -- cgit v1.2.3-70-g09d2