aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c163
1 files changed, 82 insertions, 81 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index be33606386b..7d159088c4a 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -10,6 +10,7 @@
10#include "evlist.h" 10#include "evlist.h"
11#include "evsel.h" 11#include "evsel.h"
12#include "session.h" 12#include "session.h"
13#include "tool.h"
13#include "sort.h" 14#include "sort.h"
14#include "util.h" 15#include "util.h"
15#include "cpumap.h" 16#include "cpumap.h"
@@ -104,7 +105,7 @@ static void perf_session__destroy_kernel_maps(struct perf_session *self)
104 105
105struct perf_session *perf_session__new(const char *filename, int mode, 106struct perf_session *perf_session__new(const char *filename, int mode,
106 bool force, bool repipe, 107 bool force, bool repipe,
107 struct perf_event_ops *ops) 108 struct perf_tool *tool)
108{ 109{
109 size_t len = filename ? strlen(filename) + 1 : 0; 110 size_t len = filename ? strlen(filename) + 1 : 0;
110 struct perf_session *self = zalloc(sizeof(*self) + len); 111 struct perf_session *self = zalloc(sizeof(*self) + len);
@@ -142,10 +143,10 @@ struct perf_session *perf_session__new(const char *filename, int mode,
142 goto out_delete; 143 goto out_delete;
143 } 144 }
144 145
145 if (ops && ops->ordering_requires_timestamps && 146 if (tool && tool->ordering_requires_timestamps &&
146 ops->ordered_samples && !self->sample_id_all) { 147 tool->ordered_samples && !self->sample_id_all) {
147 dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); 148 dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
148 ops->ordered_samples = false; 149 tool->ordered_samples = false;
149 } 150 }
150 151
151out: 152out:
@@ -285,7 +286,7 @@ static int process_event_synth_attr_stub(union perf_event *event __used,
285 return 0; 286 return 0;
286} 287}
287 288
288static int process_event_sample_stub(struct perf_event_ops *ops __used, 289static int process_event_sample_stub(struct perf_tool *tool __used,
289 union perf_event *event __used, 290 union perf_event *event __used,
290 struct perf_sample *sample __used, 291 struct perf_sample *sample __used,
291 struct perf_evsel *evsel __used, 292 struct perf_evsel *evsel __used,
@@ -295,7 +296,7 @@ static int process_event_sample_stub(struct perf_event_ops *ops __used,
295 return 0; 296 return 0;
296} 297}
297 298
298static int process_event_stub(struct perf_event_ops *ops __used, 299static int process_event_stub(struct perf_tool *tool __used,
299 union perf_event *event __used, 300 union perf_event *event __used,
300 struct perf_sample *sample __used, 301 struct perf_sample *sample __used,
301 struct machine *machine __used) 302 struct machine *machine __used)
@@ -304,7 +305,7 @@ static int process_event_stub(struct perf_event_ops *ops __used,
304 return 0; 305 return 0;
305} 306}
306 307
307static int process_finished_round_stub(struct perf_event_ops *ops __used, 308static int process_finished_round_stub(struct perf_tool *tool __used,
308 union perf_event *event __used, 309 union perf_event *event __used,
309 struct perf_session *perf_session __used) 310 struct perf_session *perf_session __used)
310{ 311{
@@ -312,50 +313,50 @@ static int process_finished_round_stub(struct perf_event_ops *ops __used,
312 return 0; 313 return 0;
313} 314}
314 315
315static int process_event_type_stub(struct perf_event_ops *ops __used, 316static int process_event_type_stub(struct perf_tool *tool __used,
316 union perf_event *event __used) 317 union perf_event *event __used)
317{ 318{
318 dump_printf(": unhandled!\n"); 319 dump_printf(": unhandled!\n");
319 return 0; 320 return 0;
320} 321}
321 322
322static int process_finished_round(struct perf_event_ops *ops, 323static int process_finished_round(struct perf_tool *tool,
323 union perf_event *event, 324 union perf_event *event,
324 struct perf_session *session); 325 struct perf_session *session);
325 326
326static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) 327static void perf_tool__fill_defaults(struct perf_tool *tool)
327{ 328{
328 if (handler->sample == NULL) 329 if (tool->sample == NULL)
329 handler->sample = process_event_sample_stub; 330 tool->sample = process_event_sample_stub;
330 if (handler->mmap == NULL) 331 if (tool->mmap == NULL)
331 handler->mmap = process_event_stub; 332 tool->mmap = process_event_stub;
332 if (handler->comm == NULL) 333 if (tool->comm == NULL)
333 handler->comm = process_event_stub; 334 tool->comm = process_event_stub;
334 if (handler->fork == NULL) 335 if (tool->fork == NULL)
335 handler->fork = process_event_stub; 336 tool->fork = process_event_stub;
336 if (handler->exit == NULL) 337 if (tool->exit == NULL)
337 handler->exit = process_event_stub; 338 tool->exit = process_event_stub;
338 if (handler->lost == NULL) 339 if (tool->lost == NULL)
339 handler->lost = perf_event__process_lost; 340 tool->lost = perf_event__process_lost;
340 if (handler->read == NULL) 341 if (tool->read == NULL)
341 handler->read = process_event_sample_stub; 342 tool->read = process_event_sample_stub;
342 if (handler->throttle == NULL) 343 if (tool->throttle == NULL)
343 handler->throttle = process_event_stub; 344 tool->throttle = process_event_stub;
344 if (handler->unthrottle == NULL) 345 if (tool->unthrottle == NULL)
345 handler->unthrottle = process_event_stub; 346 tool->unthrottle = process_event_stub;
346 if (handler->attr == NULL) 347 if (tool->attr == NULL)
347 handler->attr = process_event_synth_attr_stub; 348 tool->attr = process_event_synth_attr_stub;
348 if (handler->event_type == NULL) 349 if (tool->event_type == NULL)
349 handler->event_type = process_event_type_stub; 350 tool->event_type = process_event_type_stub;
350 if (handler->tracing_data == NULL) 351 if (tool->tracing_data == NULL)
351 handler->tracing_data = process_event_synth_tracing_data_stub; 352 tool->tracing_data = process_event_synth_tracing_data_stub;
352 if (handler->build_id == NULL) 353 if (tool->build_id == NULL)
353 handler->build_id = process_finished_round_stub; 354 tool->build_id = process_finished_round_stub;
354 if (handler->finished_round == NULL) { 355 if (tool->finished_round == NULL) {
355 if (handler->ordered_samples) 356 if (tool->ordered_samples)
356 handler->finished_round = process_finished_round; 357 tool->finished_round = process_finished_round;
357 else 358 else
358 handler->finished_round = process_finished_round_stub; 359 tool->finished_round = process_finished_round_stub;
359 } 360 }
360} 361}
361 362
@@ -487,11 +488,11 @@ static void perf_session_free_sample_buffers(struct perf_session *session)
487static int perf_session_deliver_event(struct perf_session *session, 488static int perf_session_deliver_event(struct perf_session *session,
488 union perf_event *event, 489 union perf_event *event,
489 struct perf_sample *sample, 490 struct perf_sample *sample,
490 struct perf_event_ops *ops, 491 struct perf_tool *tool,
491 u64 file_offset); 492 u64 file_offset);
492 493
493static void flush_sample_queue(struct perf_session *s, 494static void flush_sample_queue(struct perf_session *s,
494 struct perf_event_ops *ops) 495 struct perf_tool *tool)
495{ 496{
496 struct ordered_samples *os = &s->ordered_samples; 497 struct ordered_samples *os = &s->ordered_samples;
497 struct list_head *head = &os->samples; 498 struct list_head *head = &os->samples;
@@ -502,7 +503,7 @@ static void flush_sample_queue(struct perf_session *s,
502 unsigned idx = 0, progress_next = os->nr_samples / 16; 503 unsigned idx = 0, progress_next = os->nr_samples / 16;
503 int ret; 504 int ret;
504 505
505 if (!ops->ordered_samples || !limit) 506 if (!tool->ordered_samples || !limit)
506 return; 507 return;
507 508
508 list_for_each_entry_safe(iter, tmp, head, list) { 509 list_for_each_entry_safe(iter, tmp, head, list) {
@@ -513,7 +514,7 @@ static void flush_sample_queue(struct perf_session *s,
513 if (ret) 514 if (ret)
514 pr_err("Can't parse sample, err = %d\n", ret); 515 pr_err("Can't parse sample, err = %d\n", ret);
515 else 516 else
516 perf_session_deliver_event(s, iter->event, &sample, ops, 517 perf_session_deliver_event(s, iter->event, &sample, tool,
517 iter->file_offset); 518 iter->file_offset);
518 519
519 os->last_flush = iter->timestamp; 520 os->last_flush = iter->timestamp;
@@ -575,11 +576,11 @@ static void flush_sample_queue(struct perf_session *s,
575 * Flush every events below timestamp 7 576 * Flush every events below timestamp 7
576 * etc... 577 * etc...
577 */ 578 */
578static int process_finished_round(struct perf_event_ops *ops, 579static int process_finished_round(struct perf_tool *tool,
579 union perf_event *event __used, 580 union perf_event *event __used,
580 struct perf_session *session) 581 struct perf_session *session)
581{ 582{
582 flush_sample_queue(session, ops); 583 flush_sample_queue(session, tool);
583 session->ordered_samples.next_flush = session->ordered_samples.max_timestamp; 584 session->ordered_samples.next_flush = session->ordered_samples.max_timestamp;
584 585
585 return 0; 586 return 0;
@@ -749,7 +750,7 @@ static struct machine *
749static int perf_session_deliver_event(struct perf_session *session, 750static int perf_session_deliver_event(struct perf_session *session,
750 union perf_event *event, 751 union perf_event *event,
751 struct perf_sample *sample, 752 struct perf_sample *sample,
752 struct perf_event_ops *ops, 753 struct perf_tool *tool,
753 u64 file_offset) 754 u64 file_offset)
754{ 755{
755 struct perf_evsel *evsel; 756 struct perf_evsel *evsel;
@@ -784,25 +785,25 @@ static int perf_session_deliver_event(struct perf_session *session,
784 ++session->hists.stats.nr_unknown_id; 785 ++session->hists.stats.nr_unknown_id;
785 return -1; 786 return -1;
786 } 787 }
787 return ops->sample(ops, event, sample, evsel, machine); 788 return tool->sample(tool, event, sample, evsel, machine);
788 case PERF_RECORD_MMAP: 789 case PERF_RECORD_MMAP:
789 return ops->mmap(ops, event, sample, machine); 790 return tool->mmap(tool, event, sample, machine);
790 case PERF_RECORD_COMM: 791 case PERF_RECORD_COMM:
791 return ops->comm(ops, event, sample, machine); 792 return tool->comm(tool, event, sample, machine);
792 case PERF_RECORD_FORK: 793 case PERF_RECORD_FORK:
793 return ops->fork(ops, event, sample, machine); 794 return tool->fork(tool, event, sample, machine);
794 case PERF_RECORD_EXIT: 795 case PERF_RECORD_EXIT:
795 return ops->exit(ops, event, sample, machine); 796 return tool->exit(tool, event, sample, machine);
796 case PERF_RECORD_LOST: 797 case PERF_RECORD_LOST:
797 if (ops->lost == perf_event__process_lost) 798 if (tool->lost == perf_event__process_lost)
798 session->hists.stats.total_lost += event->lost.lost; 799 session->hists.stats.total_lost += event->lost.lost;
799 return ops->lost(ops, event, sample, machine); 800 return tool->lost(tool, event, sample, machine);
800 case PERF_RECORD_READ: 801 case PERF_RECORD_READ:
801 return ops->read(ops, event, sample, evsel, machine); 802 return tool->read(tool, event, sample, evsel, machine);
802 case PERF_RECORD_THROTTLE: 803 case PERF_RECORD_THROTTLE:
803 return ops->throttle(ops, event, sample, machine); 804 return tool->throttle(tool, event, sample, machine);
804 case PERF_RECORD_UNTHROTTLE: 805 case PERF_RECORD_UNTHROTTLE:
805 return ops->unthrottle(ops, event, sample, machine); 806 return tool->unthrottle(tool, event, sample, machine);
806 default: 807 default:
807 ++session->hists.stats.nr_unknown_events; 808 ++session->hists.stats.nr_unknown_events;
808 return -1; 809 return -1;
@@ -826,7 +827,7 @@ static int perf_session__preprocess_sample(struct perf_session *session,
826} 827}
827 828
828static int perf_session__process_user_event(struct perf_session *session, union perf_event *event, 829static int perf_session__process_user_event(struct perf_session *session, union perf_event *event,
829 struct perf_event_ops *ops, u64 file_offset) 830 struct perf_tool *tool, u64 file_offset)
830{ 831{
831 int err; 832 int err;
832 833
@@ -835,20 +836,20 @@ static int perf_session__process_user_event(struct perf_session *session, union
835 /* These events are processed right away */ 836 /* These events are processed right away */
836 switch (event->header.type) { 837 switch (event->header.type) {
837 case PERF_RECORD_HEADER_ATTR: 838 case PERF_RECORD_HEADER_ATTR:
838 err = ops->attr(event, &session->evlist); 839 err = tool->attr(event, &session->evlist);
839 if (err == 0) 840 if (err == 0)
840 perf_session__update_sample_type(session); 841 perf_session__update_sample_type(session);
841 return err; 842 return err;
842 case PERF_RECORD_HEADER_EVENT_TYPE: 843 case PERF_RECORD_HEADER_EVENT_TYPE:
843 return ops->event_type(ops, event); 844 return tool->event_type(tool, event);
844 case PERF_RECORD_HEADER_TRACING_DATA: 845 case PERF_RECORD_HEADER_TRACING_DATA:
845 /* setup for reading amidst mmap */ 846 /* setup for reading amidst mmap */
846 lseek(session->fd, file_offset, SEEK_SET); 847 lseek(session->fd, file_offset, SEEK_SET);
847 return ops->tracing_data(event, session); 848 return tool->tracing_data(event, session);
848 case PERF_RECORD_HEADER_BUILD_ID: 849 case PERF_RECORD_HEADER_BUILD_ID:
849 return ops->build_id(ops, event, session); 850 return tool->build_id(tool, event, session);
850 case PERF_RECORD_FINISHED_ROUND: 851 case PERF_RECORD_FINISHED_ROUND:
851 return ops->finished_round(ops, event, session); 852 return tool->finished_round(tool, event, session);
852 default: 853 default:
853 return -EINVAL; 854 return -EINVAL;
854 } 855 }
@@ -856,7 +857,7 @@ static int perf_session__process_user_event(struct perf_session *session, union
856 857
857static int perf_session__process_event(struct perf_session *session, 858static int perf_session__process_event(struct perf_session *session,
858 union perf_event *event, 859 union perf_event *event,
859 struct perf_event_ops *ops, 860 struct perf_tool *tool,
860 u64 file_offset) 861 u64 file_offset)
861{ 862{
862 struct perf_sample sample; 863 struct perf_sample sample;
@@ -872,7 +873,7 @@ static int perf_session__process_event(struct perf_session *session,
872 hists__inc_nr_events(&session->hists, event->header.type); 873 hists__inc_nr_events(&session->hists, event->header.type);
873 874
874 if (event->header.type >= PERF_RECORD_USER_TYPE_START) 875 if (event->header.type >= PERF_RECORD_USER_TYPE_START)
875 return perf_session__process_user_event(session, event, ops, file_offset); 876 return perf_session__process_user_event(session, event, tool, file_offset);
876 877
877 /* 878 /*
878 * For all kernel events we get the sample data 879 * For all kernel events we get the sample data
@@ -885,14 +886,14 @@ static int perf_session__process_event(struct perf_session *session,
885 if (perf_session__preprocess_sample(session, event, &sample)) 886 if (perf_session__preprocess_sample(session, event, &sample))
886 return 0; 887 return 0;
887 888
888 if (ops->ordered_samples) { 889 if (tool->ordered_samples) {
889 ret = perf_session_queue_event(session, event, &sample, 890 ret = perf_session_queue_event(session, event, &sample,
890 file_offset); 891 file_offset);
891 if (ret != -ETIME) 892 if (ret != -ETIME)
892 return ret; 893 return ret;
893 } 894 }
894 895
895 return perf_session_deliver_event(session, event, &sample, ops, 896 return perf_session_deliver_event(session, event, &sample, tool,
896 file_offset); 897 file_offset);
897} 898}
898 899
@@ -921,9 +922,9 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se
921} 922}
922 923
923static void perf_session__warn_about_errors(const struct perf_session *session, 924static void perf_session__warn_about_errors(const struct perf_session *session,
924 const struct perf_event_ops *ops) 925 const struct perf_tool *tool)
925{ 926{
926 if (ops->lost == perf_event__process_lost && 927 if (tool->lost == perf_event__process_lost &&
927 session->hists.stats.nr_events[PERF_RECORD_LOST] != 0) { 928 session->hists.stats.nr_events[PERF_RECORD_LOST] != 0) {
928 ui__warning("Processed %d events and lost %d chunks!\n\n" 929 ui__warning("Processed %d events and lost %d chunks!\n\n"
929 "Check IO/CPU overload!\n\n", 930 "Check IO/CPU overload!\n\n",
@@ -958,7 +959,7 @@ static void perf_session__warn_about_errors(const struct perf_session *session,
958volatile int session_done; 959volatile int session_done;
959 960
960static int __perf_session__process_pipe_events(struct perf_session *self, 961static int __perf_session__process_pipe_events(struct perf_session *self,
961 struct perf_event_ops *ops) 962 struct perf_tool *tool)
962{ 963{
963 union perf_event event; 964 union perf_event event;
964 uint32_t size; 965 uint32_t size;
@@ -967,7 +968,7 @@ static int __perf_session__process_pipe_events(struct perf_session *self,
967 int err; 968 int err;
968 void *p; 969 void *p;
969 970
970 perf_event_ops__fill_defaults(ops); 971 perf_tool__fill_defaults(tool);
971 972
972 head = 0; 973 head = 0;
973more: 974more:
@@ -1004,7 +1005,7 @@ more:
1004 } 1005 }
1005 1006
1006 if (size == 0 || 1007 if (size == 0 ||
1007 (skip = perf_session__process_event(self, &event, ops, head)) < 0) { 1008 (skip = perf_session__process_event(self, &event, tool, head)) < 0) {
1008 dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n", 1009 dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n",
1009 head, event.header.size, event.header.type); 1010 head, event.header.size, event.header.type);
1010 /* 1011 /*
@@ -1027,7 +1028,7 @@ more:
1027done: 1028done:
1028 err = 0; 1029 err = 0;
1029out_err: 1030out_err:
1030 perf_session__warn_about_errors(self, ops); 1031 perf_session__warn_about_errors(self, tool);
1031 perf_session_free_sample_buffers(self); 1032 perf_session_free_sample_buffers(self);
1032 return err; 1033 return err;
1033} 1034}
@@ -1058,7 +1059,7 @@ fetch_mmaped_event(struct perf_session *session,
1058 1059
1059int __perf_session__process_events(struct perf_session *session, 1060int __perf_session__process_events(struct perf_session *session,
1060 u64 data_offset, u64 data_size, 1061 u64 data_offset, u64 data_size,
1061 u64 file_size, struct perf_event_ops *ops) 1062 u64 file_size, struct perf_tool *tool)
1062{ 1063{
1063 u64 head, page_offset, file_offset, file_pos, progress_next; 1064 u64 head, page_offset, file_offset, file_pos, progress_next;
1064 int err, mmap_prot, mmap_flags, map_idx = 0; 1065 int err, mmap_prot, mmap_flags, map_idx = 0;
@@ -1067,7 +1068,7 @@ int __perf_session__process_events(struct perf_session *session,
1067 union perf_event *event; 1068 union perf_event *event;
1068 uint32_t size; 1069 uint32_t size;
1069 1070
1070 perf_event_ops__fill_defaults(ops); 1071 perf_tool__fill_defaults(tool);
1071 1072
1072 page_size = sysconf(_SC_PAGESIZE); 1073 page_size = sysconf(_SC_PAGESIZE);
1073 1074
@@ -1122,7 +1123,7 @@ more:
1122 size = event->header.size; 1123 size = event->header.size;
1123 1124
1124 if (size == 0 || 1125 if (size == 0 ||
1125 perf_session__process_event(session, event, ops, file_pos) < 0) { 1126 perf_session__process_event(session, event, tool, file_pos) < 0) {
1126 dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n", 1127 dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n",
1127 file_offset + head, event->header.size, 1128 file_offset + head, event->header.size,
1128 event->header.type); 1129 event->header.type);
@@ -1151,15 +1152,15 @@ more:
1151 err = 0; 1152 err = 0;
1152 /* do the final flush for ordered samples */ 1153 /* do the final flush for ordered samples */
1153 session->ordered_samples.next_flush = ULLONG_MAX; 1154 session->ordered_samples.next_flush = ULLONG_MAX;
1154 flush_sample_queue(session, ops); 1155 flush_sample_queue(session, tool);
1155out_err: 1156out_err:
1156 perf_session__warn_about_errors(session, ops); 1157 perf_session__warn_about_errors(session, tool);
1157 perf_session_free_sample_buffers(session); 1158 perf_session_free_sample_buffers(session);
1158 return err; 1159 return err;
1159} 1160}
1160 1161
1161int perf_session__process_events(struct perf_session *self, 1162int perf_session__process_events(struct perf_session *self,
1162 struct perf_event_ops *ops) 1163 struct perf_tool *tool)
1163{ 1164{
1164 int err; 1165 int err;
1165 1166
@@ -1170,9 +1171,9 @@ int perf_session__process_events(struct perf_session *self,
1170 err = __perf_session__process_events(self, 1171 err = __perf_session__process_events(self,
1171 self->header.data_offset, 1172 self->header.data_offset,
1172 self->header.data_size, 1173 self->header.data_size,
1173 self->size, ops); 1174 self->size, tool);
1174 else 1175 else
1175 err = __perf_session__process_pipe_events(self, ops); 1176 err = __perf_session__process_pipe_events(self, tool);
1176 1177
1177 return err; 1178 return err;
1178} 1179}