aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-test.c11
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/util/event.c125
-rw-r--r--tools/perf/util/event.h5
-rw-r--r--tools/perf/util/evsel.c118
-rw-r--r--tools/perf/util/session.c4
-rw-r--r--tools/perf/util/session.h9
7 files changed, 134 insertions, 140 deletions
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index dc91ee06a37c..231e3e21810c 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -10,7 +10,6 @@
10#include "util/evlist.h" 10#include "util/evlist.h"
11#include "util/parse-options.h" 11#include "util/parse-options.h"
12#include "util/parse-events.h" 12#include "util/parse-events.h"
13#include "util/session.h"
14#include "util/symbol.h" 13#include "util/symbol.h"
15#include "util/thread_map.h" 14#include "util/thread_map.h"
16 15
@@ -457,7 +456,6 @@ static int test__basic_mmap(void)
457 int err = -1; 456 int err = -1;
458 event_t *event; 457 event_t *event;
459 struct thread_map *threads; 458 struct thread_map *threads;
460 struct perf_session session;
461 struct cpu_map *cpus; 459 struct cpu_map *cpus;
462 struct perf_evlist *evlist; 460 struct perf_evlist *evlist;
463 struct perf_event_attr attr = { 461 struct perf_event_attr attr = {
@@ -521,13 +519,6 @@ static int test__basic_mmap(void)
521 attr.wakeup_events = 1; 519 attr.wakeup_events = 1;
522 attr.sample_period = 1; 520 attr.sample_period = 1;
523 521
524 /*
525 * FIXME: use evsel->attr.sample_type in event__parse_sample.
526 * This will nicely remove the requirement that we have
527 * all the events with the same sample_type.
528 */
529 session.sample_type = attr.sample_type;
530
531 for (i = 0; i < nsyscalls; ++i) { 522 for (i = 0; i < nsyscalls; ++i) {
532 attr.config = ids[i]; 523 attr.config = ids[i];
533 evsels[i] = perf_evsel__new(&attr, i); 524 evsels[i] = perf_evsel__new(&attr, i);
@@ -567,7 +558,7 @@ static int test__basic_mmap(void)
567 goto out_munmap; 558 goto out_munmap;
568 } 559 }
569 560
570 event__parse_sample(event, &session, &sample); 561 event__parse_sample(event, attr.sample_type, false, &sample);
571 evsel = perf_evlist__id2evsel(evlist, sample.id); 562 evsel = perf_evlist__id2evsel(evlist, sample.id);
572 if (evsel == NULL) { 563 if (evsel == NULL) {
573 pr_debug("event with id %" PRIu64 564 pr_debug("event with id %" PRIu64
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index d0b16d905405..ce2e50c891c7 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1106,7 +1106,7 @@ static void perf_session__mmap_read_cpu(struct perf_session *self, int cpu)
1106 event_t *event; 1106 event_t *event;
1107 1107
1108 while ((event = perf_evlist__read_on_cpu(evsel_list, cpu)) != NULL) { 1108 while ((event = perf_evlist__read_on_cpu(evsel_list, cpu)) != NULL) {
1109 event__parse_sample(event, self, &sample); 1109 perf_session__parse_sample(self, event, &sample);
1110 1110
1111 if (event->header.type == PERF_RECORD_SAMPLE) 1111 if (event->header.type == PERF_RECORD_SAMPLE)
1112 event__process_sample(event, &sample, self); 1112 event__process_sample(event, &sample, self);
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 1478ab4ee222..e4db8b888546 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -826,128 +826,3 @@ out_filtered:
826 al->filtered = true; 826 al->filtered = true;
827 return 0; 827 return 0;
828} 828}
829
830static int event__parse_id_sample(const event_t *event,
831 struct perf_session *session,
832 struct sample_data *sample)
833{
834 const u64 *array;
835 u64 type;
836
837 sample->cpu = sample->pid = sample->tid = -1;
838 sample->stream_id = sample->id = sample->time = -1ULL;
839
840 if (!session->sample_id_all)
841 return 0;
842
843 array = event->sample.array;
844 array += ((event->header.size -
845 sizeof(event->header)) / sizeof(u64)) - 1;
846 type = session->sample_type;
847
848 if (type & PERF_SAMPLE_CPU) {
849 u32 *p = (u32 *)array;
850 sample->cpu = *p;
851 array--;
852 }
853
854 if (type & PERF_SAMPLE_STREAM_ID) {
855 sample->stream_id = *array;
856 array--;
857 }
858
859 if (type & PERF_SAMPLE_ID) {
860 sample->id = *array;
861 array--;
862 }
863
864 if (type & PERF_SAMPLE_TIME) {
865 sample->time = *array;
866 array--;
867 }
868
869 if (type & PERF_SAMPLE_TID) {
870 u32 *p = (u32 *)array;
871 sample->pid = p[0];
872 sample->tid = p[1];
873 }
874
875 return 0;
876}
877
878int event__parse_sample(const event_t *event, struct perf_session *session,
879 struct sample_data *data)
880{
881 const u64 *array;
882 u64 type;
883
884 if (event->header.type != PERF_RECORD_SAMPLE)
885 return event__parse_id_sample(event, session, data);
886
887 array = event->sample.array;
888 type = session->sample_type;
889
890 if (type & PERF_SAMPLE_IP) {
891 data->ip = event->ip.ip;
892 array++;
893 }
894
895 if (type & PERF_SAMPLE_TID) {
896 u32 *p = (u32 *)array;
897 data->pid = p[0];
898 data->tid = p[1];
899 array++;
900 }
901
902 if (type & PERF_SAMPLE_TIME) {
903 data->time = *array;
904 array++;
905 }
906
907 if (type & PERF_SAMPLE_ADDR) {
908 data->addr = *array;
909 array++;
910 }
911
912 data->id = -1ULL;
913 if (type & PERF_SAMPLE_ID) {
914 data->id = *array;
915 array++;
916 }
917
918 if (type & PERF_SAMPLE_STREAM_ID) {
919 data->stream_id = *array;
920 array++;
921 }
922
923 if (type & PERF_SAMPLE_CPU) {
924 u32 *p = (u32 *)array;
925 data->cpu = *p;
926 array++;
927 } else
928 data->cpu = -1;
929
930 if (type & PERF_SAMPLE_PERIOD) {
931 data->period = *array;
932 array++;
933 }
934
935 if (type & PERF_SAMPLE_READ) {
936 pr_debug("PERF_SAMPLE_READ is unsuported for now\n");
937 return -1;
938 }
939
940 if (type & PERF_SAMPLE_CALLCHAIN) {
941 data->callchain = (struct ip_callchain *)array;
942 array += 1 + data->callchain->nr;
943 }
944
945 if (type & PERF_SAMPLE_RAW) {
946 u32 *p = (u32 *)array;
947 data->raw_size = *p;
948 p++;
949 data->raw_data = p;
950 }
951
952 return 0;
953}
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 2b7e91902f10..d79e4edd82f9 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -169,9 +169,10 @@ struct addr_location;
169int event__preprocess_sample(const event_t *self, struct perf_session *session, 169int event__preprocess_sample(const event_t *self, struct perf_session *session,
170 struct addr_location *al, struct sample_data *data, 170 struct addr_location *al, struct sample_data *data,
171 symbol_filter_t filter); 171 symbol_filter_t filter);
172int event__parse_sample(const event_t *event, struct perf_session *session,
173 struct sample_data *sample);
174 172
175const char *event__get_event_name(unsigned int id); 173const char *event__get_event_name(unsigned int id);
176 174
175int event__parse_sample(const event_t *event, u64 type, bool sample_id_all,
176 struct sample_data *sample);
177
177#endif /* __PERF_RECORD_H */ 178#endif /* __PERF_RECORD_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 9a6d94299ab8..a85ae12845ea 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -355,3 +355,121 @@ out_unmap:
355 } 355 }
356 return -1; 356 return -1;
357} 357}
358
359static int event__parse_id_sample(const event_t *event, u64 type,
360 struct sample_data *sample)
361{
362 const u64 *array = event->sample.array;
363
364 array += ((event->header.size -
365 sizeof(event->header)) / sizeof(u64)) - 1;
366
367 if (type & PERF_SAMPLE_CPU) {
368 u32 *p = (u32 *)array;
369 sample->cpu = *p;
370 array--;
371 }
372
373 if (type & PERF_SAMPLE_STREAM_ID) {
374 sample->stream_id = *array;
375 array--;
376 }
377
378 if (type & PERF_SAMPLE_ID) {
379 sample->id = *array;
380 array--;
381 }
382
383 if (type & PERF_SAMPLE_TIME) {
384 sample->time = *array;
385 array--;
386 }
387
388 if (type & PERF_SAMPLE_TID) {
389 u32 *p = (u32 *)array;
390 sample->pid = p[0];
391 sample->tid = p[1];
392 }
393
394 return 0;
395}
396
397int event__parse_sample(const event_t *event, u64 type, bool sample_id_all,
398 struct sample_data *data)
399{
400 const u64 *array;
401
402 data->cpu = data->pid = data->tid = -1;
403 data->stream_id = data->id = data->time = -1ULL;
404
405 if (event->header.type != PERF_RECORD_SAMPLE) {
406 if (!sample_id_all)
407 return 0;
408 return event__parse_id_sample(event, type, data);
409 }
410
411 array = event->sample.array;
412
413 if (type & PERF_SAMPLE_IP) {
414 data->ip = event->ip.ip;
415 array++;
416 }
417
418 if (type & PERF_SAMPLE_TID) {
419 u32 *p = (u32 *)array;
420 data->pid = p[0];
421 data->tid = p[1];
422 array++;
423 }
424
425 if (type & PERF_SAMPLE_TIME) {
426 data->time = *array;
427 array++;
428 }
429
430 if (type & PERF_SAMPLE_ADDR) {
431 data->addr = *array;
432 array++;
433 }
434
435 data->id = -1ULL;
436 if (type & PERF_SAMPLE_ID) {
437 data->id = *array;
438 array++;
439 }
440
441 if (type & PERF_SAMPLE_STREAM_ID) {
442 data->stream_id = *array;
443 array++;
444 }
445
446 if (type & PERF_SAMPLE_CPU) {
447 u32 *p = (u32 *)array;
448 data->cpu = *p;
449 array++;
450 }
451
452 if (type & PERF_SAMPLE_PERIOD) {
453 data->period = *array;
454 array++;
455 }
456
457 if (type & PERF_SAMPLE_READ) {
458 fprintf(stderr, "PERF_SAMPLE_READ is unsuported for now\n");
459 return -1;
460 }
461
462 if (type & PERF_SAMPLE_CALLCHAIN) {
463 data->callchain = (struct ip_callchain *)array;
464 array += 1 + data->callchain->nr;
465 }
466
467 if (type & PERF_SAMPLE_RAW) {
468 u32 *p = (u32 *)array;
469 data->raw_size = *p;
470 p++;
471 data->raw_data = p;
472 }
473
474 return 0;
475}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index b58a48a5e5a9..e6a07408669e 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -496,7 +496,7 @@ static void flush_sample_queue(struct perf_session *s,
496 if (iter->timestamp > limit) 496 if (iter->timestamp > limit)
497 break; 497 break;
498 498
499 event__parse_sample(iter->event, s, &sample); 499 perf_session__parse_sample(s, iter->event, &sample);
500 perf_session_deliver_event(s, iter->event, &sample, ops, 500 perf_session_deliver_event(s, iter->event, &sample, ops,
501 iter->file_offset); 501 iter->file_offset);
502 502
@@ -806,7 +806,7 @@ static int perf_session__process_event(struct perf_session *session,
806 /* 806 /*
807 * For all kernel events we get the sample data 807 * For all kernel events we get the sample data
808 */ 808 */
809 event__parse_sample(event, session, &sample); 809 perf_session__parse_sample(session, event, &sample);
810 810
811 /* Preprocess sample records - precheck callchains */ 811 /* Preprocess sample records - precheck callchains */
812 if (perf_session__preprocess_sample(session, event, &sample)) 812 if (perf_session__preprocess_sample(session, event, &sample))
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index e815468eb888..78239767011e 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -155,4 +155,13 @@ size_t perf_session__fprintf_nr_events(struct perf_session *self, FILE *fp)
155{ 155{
156 return hists__fprintf_nr_events(&self->hists, fp); 156 return hists__fprintf_nr_events(&self->hists, fp);
157} 157}
158
159static inline int perf_session__parse_sample(struct perf_session *session,
160 const event_t *event,
161 struct sample_data *sample)
162{
163 return event__parse_sample(event, session->sample_type,
164 session->sample_id_all, sample);
165}
166
158#endif /* __PERF_SESSION_H */ 167#endif /* __PERF_SESSION_H */