aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2012-10-10 11:38:13 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-08-07 16:35:20 -0400
commit9ede473cc9f655f8a10cfc8ebbf04c48d84db7ee (patch)
tree7a05d71c33eaab621009296d5964534c6c31088c
parente2b5abe0c82b45980b95ead22678861a2013c0df (diff)
perf tools: Add support for parsing PERF_SAMPLE_READ sample type
Adding support to parse out the PERF_SAMPLE_READ sample bits. The code contains both single and group format specification. This code parse out and prepare PERF_SAMPLE_READ data into the perf_sample struct. It will be used for group leader sampling feature comming in shortly. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/n/tip-0tgdoln5rwk3wocshb442cl3@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/event.h18
-rw-r--r--tools/perf/util/evlist.c26
-rw-r--r--tools/perf/util/evlist.h2
-rw-r--r--tools/perf/util/evsel.c30
-rw-r--r--tools/perf/util/session.c38
5 files changed, 112 insertions, 2 deletions
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 1ebb8fb0178c..6119a649d861 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -80,6 +80,23 @@ struct stack_dump {
80 char *data; 80 char *data;
81}; 81};
82 82
83struct sample_read_value {
84 u64 value;
85 u64 id;
86};
87
88struct sample_read {
89 u64 time_enabled;
90 u64 time_running;
91 union {
92 struct {
93 u64 nr;
94 struct sample_read_value *values;
95 } group;
96 struct sample_read_value one;
97 };
98};
99
83struct perf_sample { 100struct perf_sample {
84 u64 ip; 101 u64 ip;
85 u32 pid, tid; 102 u32 pid, tid;
@@ -97,6 +114,7 @@ struct perf_sample {
97 struct branch_stack *branch_stack; 114 struct branch_stack *branch_stack;
98 struct regs_dump user_regs; 115 struct regs_dump user_regs;
99 struct stack_dump user_stack; 116 struct stack_dump user_stack;
117 struct sample_read read;
100}; 118};
101 119
102#define PERF_MEM_DATA_SRC_NONE \ 120#define PERF_MEM_DATA_SRC_NONE \
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 0d3b73996255..df77a44fe276 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -676,6 +676,32 @@ u64 perf_evlist__sample_type(struct perf_evlist *evlist)
676 return first->attr.sample_type; 676 return first->attr.sample_type;
677} 677}
678 678
679bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
680{
681 struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
682 u64 read_format = first->attr.read_format;
683 u64 sample_type = first->attr.sample_type;
684
685 list_for_each_entry_continue(pos, &evlist->entries, node) {
686 if (read_format != pos->attr.read_format)
687 return false;
688 }
689
690 /* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */
691 if ((sample_type & PERF_SAMPLE_READ) &&
692 !(read_format & PERF_FORMAT_ID)) {
693 return false;
694 }
695
696 return true;
697}
698
699u64 perf_evlist__read_format(struct perf_evlist *evlist)
700{
701 struct perf_evsel *first = perf_evlist__first(evlist);
702 return first->attr.read_format;
703}
704
679u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist) 705u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist)
680{ 706{
681 struct perf_evsel *first = perf_evlist__first(evlist); 707 struct perf_evsel *first = perf_evlist__first(evlist);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 0583d36252be..c7178b7b9951 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -118,6 +118,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist);
118void __perf_evlist__set_leader(struct list_head *list); 118void __perf_evlist__set_leader(struct list_head *list);
119void perf_evlist__set_leader(struct perf_evlist *evlist); 119void perf_evlist__set_leader(struct perf_evlist *evlist);
120 120
121u64 perf_evlist__read_format(struct perf_evlist *evlist);
121u64 perf_evlist__sample_type(struct perf_evlist *evlist); 122u64 perf_evlist__sample_type(struct perf_evlist *evlist);
122bool perf_evlist__sample_id_all(struct perf_evlist *evlist); 123bool perf_evlist__sample_id_all(struct perf_evlist *evlist);
123u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist); 124u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist);
@@ -127,6 +128,7 @@ int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *even
127 128
128bool perf_evlist__valid_sample_type(struct perf_evlist *evlist); 129bool perf_evlist__valid_sample_type(struct perf_evlist *evlist);
129bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist); 130bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist);
131bool perf_evlist__valid_read_format(struct perf_evlist *evlist);
130 132
131void perf_evlist__splice_list_tail(struct perf_evlist *evlist, 133void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
132 struct list_head *list, 134 struct list_head *list,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 8bed0c1a1399..9ab8fff74e30 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1096,8 +1096,34 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
1096 } 1096 }
1097 1097
1098 if (type & PERF_SAMPLE_READ) { 1098 if (type & PERF_SAMPLE_READ) {
1099 fprintf(stderr, "PERF_SAMPLE_READ is unsupported for now\n"); 1099 u64 read_format = evsel->attr.read_format;
1100 return -1; 1100
1101 if (read_format & PERF_FORMAT_GROUP)
1102 data->read.group.nr = *array;
1103 else
1104 data->read.one.value = *array;
1105
1106 array++;
1107
1108 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
1109 data->read.time_enabled = *array;
1110 array++;
1111 }
1112
1113 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
1114 data->read.time_running = *array;
1115 array++;
1116 }
1117
1118 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
1119 if (read_format & PERF_FORMAT_GROUP) {
1120 data->read.group.values = (struct sample_read_value *) array;
1121 array = (void *) array + data->read.group.nr *
1122 sizeof(struct sample_read_value);
1123 } else {
1124 data->read.one.id = *array;
1125 array++;
1126 }
1101 } 1127 }
1102 1128
1103 if (type & PERF_SAMPLE_CALLCHAIN) { 1129 if (type & PERF_SAMPLE_CALLCHAIN) {
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 272c9cf57122..f082921a062d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -71,6 +71,11 @@ static int perf_session__open(struct perf_session *self, bool force)
71 goto out_close; 71 goto out_close;
72 } 72 }
73 73
74 if (!perf_evlist__valid_read_format(self->evlist)) {
75 pr_err("non matching read_format");
76 goto out_close;
77 }
78
74 self->size = input_stat.st_size; 79 self->size = input_stat.st_size;
75 return 0; 80 return 0;
76 81
@@ -749,6 +754,36 @@ static void perf_session__print_tstamp(struct perf_session *session,
749 printf("%" PRIu64 " ", sample->time); 754 printf("%" PRIu64 " ", sample->time);
750} 755}
751 756
757static void sample_read__printf(struct perf_sample *sample, u64 read_format)
758{
759 printf("... sample_read:\n");
760
761 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
762 printf("...... time enabled %016" PRIx64 "\n",
763 sample->read.time_enabled);
764
765 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
766 printf("...... time running %016" PRIx64 "\n",
767 sample->read.time_running);
768
769 if (read_format & PERF_FORMAT_GROUP) {
770 u64 i;
771
772 printf(".... group nr %" PRIu64 "\n", sample->read.group.nr);
773
774 for (i = 0; i < sample->read.group.nr; i++) {
775 struct sample_read_value *value;
776
777 value = &sample->read.group.values[i];
778 printf("..... id %016" PRIx64
779 ", value %016" PRIx64 "\n",
780 value->id, value->value);
781 }
782 } else
783 printf("..... id %016" PRIx64 ", value %016" PRIx64 "\n",
784 sample->read.one.id, sample->read.one.value);
785}
786
752static void dump_event(struct perf_session *session, union perf_event *event, 787static void dump_event(struct perf_session *session, union perf_event *event,
753 u64 file_offset, struct perf_sample *sample) 788 u64 file_offset, struct perf_sample *sample)
754{ 789{
@@ -798,6 +833,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
798 833
799 if (sample_type & PERF_SAMPLE_DATA_SRC) 834 if (sample_type & PERF_SAMPLE_DATA_SRC)
800 printf(" . data_src: 0x%"PRIx64"\n", sample->data_src); 835 printf(" . data_src: 0x%"PRIx64"\n", sample->data_src);
836
837 if (sample_type & PERF_SAMPLE_READ)
838 sample_read__printf(sample, evsel->attr.read_format);
801} 839}
802 840
803static struct machine * 841static struct machine *