diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-11-28 04:56:39 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-11-28 07:39:12 -0500 |
commit | 743eb868657bdb1b26c7b24077ca21c67c82c777 (patch) | |
tree | 4803b557725213043ccd5d3f83d2eec796a49f69 /tools/perf/util/session.c | |
parent | d20deb64e0490ee9442b5181bc08a62d2cadcb90 (diff) |
perf tools: Resolve machine earlier and pass it to perf_event_ops
Reducing the exposure of perf_session further, so that we can use the
classes in cases where no perf.data file is created.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-stua66dcscsezzrcdugvbmvd@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r-- | tools/perf/util/session.c | 91 |
1 files changed, 53 insertions, 38 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index a36023a6677..be33606386b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -84,6 +84,7 @@ void perf_session__update_sample_type(struct perf_session *self) | |||
84 | self->sample_size = __perf_evsel__sample_size(self->sample_type); | 84 | self->sample_size = __perf_evsel__sample_size(self->sample_type); |
85 | self->sample_id_all = perf_evlist__sample_id_all(self->evlist); | 85 | self->sample_id_all = perf_evlist__sample_id_all(self->evlist); |
86 | self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist); | 86 | self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist); |
87 | self->host_machine.id_hdr_size = self->id_hdr_size; | ||
87 | } | 88 | } |
88 | 89 | ||
89 | int perf_session__create_kernel_maps(struct perf_session *self) | 90 | int perf_session__create_kernel_maps(struct perf_session *self) |
@@ -216,10 +217,10 @@ static bool symbol__match_parent_regex(struct symbol *sym) | |||
216 | return 0; | 217 | return 0; |
217 | } | 218 | } |
218 | 219 | ||
219 | int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel *evsel, | 220 | int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, |
220 | struct thread *thread, | 221 | struct thread *thread, |
221 | struct ip_callchain *chain, | 222 | struct ip_callchain *chain, |
222 | struct symbol **parent) | 223 | struct symbol **parent) |
223 | { | 224 | { |
224 | u8 cpumode = PERF_RECORD_MISC_USER; | 225 | u8 cpumode = PERF_RECORD_MISC_USER; |
225 | unsigned int i; | 226 | unsigned int i; |
@@ -252,7 +253,7 @@ int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel | |||
252 | 253 | ||
253 | al.filtered = false; | 254 | al.filtered = false; |
254 | thread__find_addr_location(thread, self, cpumode, | 255 | thread__find_addr_location(thread, self, cpumode, |
255 | MAP__FUNCTION, thread->pid, ip, &al, NULL); | 256 | MAP__FUNCTION, ip, &al, NULL); |
256 | if (al.sym != NULL) { | 257 | if (al.sym != NULL) { |
257 | if (sort__has_parent && !*parent && | 258 | if (sort__has_parent && !*parent && |
258 | symbol__match_parent_regex(al.sym)) | 259 | symbol__match_parent_regex(al.sym)) |
@@ -270,14 +271,6 @@ int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel | |||
270 | return 0; | 271 | return 0; |
271 | } | 272 | } |
272 | 273 | ||
273 | static int process_event_synth_stub(struct perf_event_ops *ops __used, | ||
274 | union perf_event *event __used, | ||
275 | struct perf_session *session __used) | ||
276 | { | ||
277 | dump_printf(": unhandled!\n"); | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int process_event_synth_tracing_data_stub(union perf_event *event __used, | 274 | static int process_event_synth_tracing_data_stub(union perf_event *event __used, |
282 | struct perf_session *session __used) | 275 | struct perf_session *session __used) |
283 | { | 276 | { |
@@ -296,7 +289,7 @@ static int process_event_sample_stub(struct perf_event_ops *ops __used, | |||
296 | union perf_event *event __used, | 289 | union perf_event *event __used, |
297 | struct perf_sample *sample __used, | 290 | struct perf_sample *sample __used, |
298 | struct perf_evsel *evsel __used, | 291 | struct perf_evsel *evsel __used, |
299 | struct perf_session *session __used) | 292 | struct machine *machine __used) |
300 | { | 293 | { |
301 | dump_printf(": unhandled!\n"); | 294 | dump_printf(": unhandled!\n"); |
302 | return 0; | 295 | return 0; |
@@ -305,7 +298,7 @@ static int process_event_sample_stub(struct perf_event_ops *ops __used, | |||
305 | static int process_event_stub(struct perf_event_ops *ops __used, | 298 | static int process_event_stub(struct perf_event_ops *ops __used, |
306 | union perf_event *event __used, | 299 | union perf_event *event __used, |
307 | struct perf_sample *sample __used, | 300 | struct perf_sample *sample __used, |
308 | struct perf_session *session __used) | 301 | struct machine *machine __used) |
309 | { | 302 | { |
310 | dump_printf(": unhandled!\n"); | 303 | dump_printf(": unhandled!\n"); |
311 | return 0; | 304 | return 0; |
@@ -313,7 +306,14 @@ static int process_event_stub(struct perf_event_ops *ops __used, | |||
313 | 306 | ||
314 | static int process_finished_round_stub(struct perf_event_ops *ops __used, | 307 | static int process_finished_round_stub(struct perf_event_ops *ops __used, |
315 | union perf_event *event __used, | 308 | union perf_event *event __used, |
316 | struct perf_session *session __used) | 309 | struct perf_session *perf_session __used) |
310 | { | ||
311 | dump_printf(": unhandled!\n"); | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static int process_event_type_stub(struct perf_event_ops *ops __used, | ||
316 | union perf_event *event __used) | ||
317 | { | 317 | { |
318 | dump_printf(": unhandled!\n"); | 318 | dump_printf(": unhandled!\n"); |
319 | return 0; | 319 | return 0; |
@@ -338,7 +338,7 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) | |||
338 | if (handler->lost == NULL) | 338 | if (handler->lost == NULL) |
339 | handler->lost = perf_event__process_lost; | 339 | handler->lost = perf_event__process_lost; |
340 | if (handler->read == NULL) | 340 | if (handler->read == NULL) |
341 | handler->read = process_event_stub; | 341 | handler->read = process_event_sample_stub; |
342 | if (handler->throttle == NULL) | 342 | if (handler->throttle == NULL) |
343 | handler->throttle = process_event_stub; | 343 | handler->throttle = process_event_stub; |
344 | if (handler->unthrottle == NULL) | 344 | if (handler->unthrottle == NULL) |
@@ -346,11 +346,11 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) | |||
346 | if (handler->attr == NULL) | 346 | if (handler->attr == NULL) |
347 | handler->attr = process_event_synth_attr_stub; | 347 | handler->attr = process_event_synth_attr_stub; |
348 | if (handler->event_type == NULL) | 348 | if (handler->event_type == NULL) |
349 | handler->event_type = process_event_synth_stub; | 349 | handler->event_type = process_event_type_stub; |
350 | if (handler->tracing_data == NULL) | 350 | if (handler->tracing_data == NULL) |
351 | handler->tracing_data = process_event_synth_tracing_data_stub; | 351 | handler->tracing_data = process_event_synth_tracing_data_stub; |
352 | if (handler->build_id == NULL) | 352 | if (handler->build_id == NULL) |
353 | handler->build_id = process_event_synth_stub; | 353 | handler->build_id = process_finished_round_stub; |
354 | if (handler->finished_round == NULL) { | 354 | if (handler->finished_round == NULL) { |
355 | if (handler->ordered_samples) | 355 | if (handler->ordered_samples) |
356 | handler->finished_round = process_finished_round; | 356 | handler->finished_round = process_finished_round; |
@@ -734,6 +734,18 @@ static void dump_sample(struct perf_session *session, union perf_event *event, | |||
734 | callchain__printf(sample); | 734 | callchain__printf(sample); |
735 | } | 735 | } |
736 | 736 | ||
737 | static struct machine * | ||
738 | perf_session__find_machine_for_cpumode(struct perf_session *session, | ||
739 | union perf_event *event) | ||
740 | { | ||
741 | const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | ||
742 | |||
743 | if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) | ||
744 | return perf_session__find_machine(session, event->ip.pid); | ||
745 | |||
746 | return perf_session__find_host_machine(session); | ||
747 | } | ||
748 | |||
737 | static int perf_session_deliver_event(struct perf_session *session, | 749 | static int perf_session_deliver_event(struct perf_session *session, |
738 | union perf_event *event, | 750 | union perf_event *event, |
739 | struct perf_sample *sample, | 751 | struct perf_sample *sample, |
@@ -741,6 +753,7 @@ static int perf_session_deliver_event(struct perf_session *session, | |||
741 | u64 file_offset) | 753 | u64 file_offset) |
742 | { | 754 | { |
743 | struct perf_evsel *evsel; | 755 | struct perf_evsel *evsel; |
756 | struct machine *machine; | ||
744 | 757 | ||
745 | dump_event(session, event, file_offset, sample); | 758 | dump_event(session, event, file_offset, sample); |
746 | 759 | ||
@@ -762,6 +775,8 @@ static int perf_session_deliver_event(struct perf_session *session, | |||
762 | hists__inc_nr_events(&evsel->hists, event->header.type); | 775 | hists__inc_nr_events(&evsel->hists, event->header.type); |
763 | } | 776 | } |
764 | 777 | ||
778 | machine = perf_session__find_machine_for_cpumode(session, event); | ||
779 | |||
765 | switch (event->header.type) { | 780 | switch (event->header.type) { |
766 | case PERF_RECORD_SAMPLE: | 781 | case PERF_RECORD_SAMPLE: |
767 | dump_sample(session, event, sample); | 782 | dump_sample(session, event, sample); |
@@ -769,23 +784,25 @@ static int perf_session_deliver_event(struct perf_session *session, | |||
769 | ++session->hists.stats.nr_unknown_id; | 784 | ++session->hists.stats.nr_unknown_id; |
770 | return -1; | 785 | return -1; |
771 | } | 786 | } |
772 | return ops->sample(ops, event, sample, evsel, session); | 787 | return ops->sample(ops, event, sample, evsel, machine); |
773 | case PERF_RECORD_MMAP: | 788 | case PERF_RECORD_MMAP: |
774 | return ops->mmap(ops, event, sample, session); | 789 | return ops->mmap(ops, event, sample, machine); |
775 | case PERF_RECORD_COMM: | 790 | case PERF_RECORD_COMM: |
776 | return ops->comm(ops, event, sample, session); | 791 | return ops->comm(ops, event, sample, machine); |
777 | case PERF_RECORD_FORK: | 792 | case PERF_RECORD_FORK: |
778 | return ops->fork(ops, event, sample, session); | 793 | return ops->fork(ops, event, sample, machine); |
779 | case PERF_RECORD_EXIT: | 794 | case PERF_RECORD_EXIT: |
780 | return ops->exit(ops, event, sample, session); | 795 | return ops->exit(ops, event, sample, machine); |
781 | case PERF_RECORD_LOST: | 796 | case PERF_RECORD_LOST: |
782 | return ops->lost(ops, event, sample, session); | 797 | if (ops->lost == perf_event__process_lost) |
798 | session->hists.stats.total_lost += event->lost.lost; | ||
799 | return ops->lost(ops, event, sample, machine); | ||
783 | case PERF_RECORD_READ: | 800 | case PERF_RECORD_READ: |
784 | return ops->read(ops, event, sample, session); | 801 | return ops->read(ops, event, sample, evsel, machine); |
785 | case PERF_RECORD_THROTTLE: | 802 | case PERF_RECORD_THROTTLE: |
786 | return ops->throttle(ops, event, sample, session); | 803 | return ops->throttle(ops, event, sample, machine); |
787 | case PERF_RECORD_UNTHROTTLE: | 804 | case PERF_RECORD_UNTHROTTLE: |
788 | return ops->unthrottle(ops, event, sample, session); | 805 | return ops->unthrottle(ops, event, sample, machine); |
789 | default: | 806 | default: |
790 | ++session->hists.stats.nr_unknown_events; | 807 | ++session->hists.stats.nr_unknown_events; |
791 | return -1; | 808 | return -1; |
@@ -823,7 +840,7 @@ static int perf_session__process_user_event(struct perf_session *session, union | |||
823 | perf_session__update_sample_type(session); | 840 | perf_session__update_sample_type(session); |
824 | return err; | 841 | return err; |
825 | case PERF_RECORD_HEADER_EVENT_TYPE: | 842 | case PERF_RECORD_HEADER_EVENT_TYPE: |
826 | return ops->event_type(ops, event, session); | 843 | return ops->event_type(ops, event); |
827 | case PERF_RECORD_HEADER_TRACING_DATA: | 844 | case PERF_RECORD_HEADER_TRACING_DATA: |
828 | /* setup for reading amidst mmap */ | 845 | /* setup for reading amidst mmap */ |
829 | lseek(session->fd, file_offset, SEEK_SET); | 846 | lseek(session->fd, file_offset, SEEK_SET); |
@@ -1170,9 +1187,8 @@ bool perf_session__has_traces(struct perf_session *self, const char *msg) | |||
1170 | return true; | 1187 | return true; |
1171 | } | 1188 | } |
1172 | 1189 | ||
1173 | int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps, | 1190 | int maps__set_kallsyms_ref_reloc_sym(struct map **maps, |
1174 | const char *symbol_name, | 1191 | const char *symbol_name, u64 addr) |
1175 | u64 addr) | ||
1176 | { | 1192 | { |
1177 | char *bracket; | 1193 | char *bracket; |
1178 | enum map_type i; | 1194 | enum map_type i; |
@@ -1264,17 +1280,16 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | |||
1264 | return NULL; | 1280 | return NULL; |
1265 | } | 1281 | } |
1266 | 1282 | ||
1267 | void perf_session__print_ip(union perf_event *event, struct perf_evsel *evsel, | 1283 | void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, |
1268 | struct perf_sample *sample, | 1284 | struct machine *machine, struct perf_evsel *evsel, |
1269 | struct perf_session *session, | 1285 | int print_sym, int print_dso) |
1270 | int print_sym, int print_dso) | ||
1271 | { | 1286 | { |
1272 | struct addr_location al; | 1287 | struct addr_location al; |
1273 | const char *symname, *dsoname; | 1288 | const char *symname, *dsoname; |
1274 | struct callchain_cursor *cursor = &evsel->hists.callchain_cursor; | 1289 | struct callchain_cursor *cursor = &evsel->hists.callchain_cursor; |
1275 | struct callchain_cursor_node *node; | 1290 | struct callchain_cursor_node *node; |
1276 | 1291 | ||
1277 | if (perf_event__preprocess_sample(event, session, &al, sample, | 1292 | if (perf_event__preprocess_sample(event, machine, &al, sample, |
1278 | NULL) < 0) { | 1293 | NULL) < 0) { |
1279 | error("problem processing %d event, skipping it.\n", | 1294 | error("problem processing %d event, skipping it.\n", |
1280 | event->header.type); | 1295 | event->header.type); |
@@ -1283,7 +1298,7 @@ void perf_session__print_ip(union perf_event *event, struct perf_evsel *evsel, | |||
1283 | 1298 | ||
1284 | if (symbol_conf.use_callchain && sample->callchain) { | 1299 | if (symbol_conf.use_callchain && sample->callchain) { |
1285 | 1300 | ||
1286 | if (perf_session__resolve_callchain(session, evsel, al.thread, | 1301 | if (machine__resolve_callchain(machine, evsel, al.thread, |
1287 | sample->callchain, NULL) != 0) { | 1302 | sample->callchain, NULL) != 0) { |
1288 | if (verbose) | 1303 | if (verbose) |
1289 | error("Failed to resolve callchain. Skipping\n"); | 1304 | error("Failed to resolve callchain. Skipping\n"); |