diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-06-25 05:27:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-25 15:39:08 -0400 |
commit | e6e18ec79b023d5fe84226cef533cf0e3770ce93 (patch) | |
tree | 6fc1bd9afd21454864abe2aec6a0e35e17d47f04 /tools/perf/builtin-report.c | |
parent | bfbd3381e63aa2a14c6706afb50ce4630aa0d9a2 (diff) |
perf_counter: Rework the sample ABI
The PERF_EVENT_READ implementation made me realize we don't
actually need the sample_type int the output sample, since
we already have that in the perf_counter_attr information.
Therefore, remove the PERF_EVENT_MISC_OVERFLOW bit and the
event->type overloading, and imply put counter overflow
samples in a PERF_EVENT_SAMPLE type.
This also fixes the issue that event->type was only 32-bit
and sample_type had 64 usable bits.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r-- | tools/perf/builtin-report.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index e575f3039766..ec5361c67bf5 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -53,6 +53,8 @@ static regex_t parent_regex; | |||
53 | 53 | ||
54 | static int exclude_other = 1; | 54 | static int exclude_other = 1; |
55 | 55 | ||
56 | static u64 sample_type; | ||
57 | |||
56 | struct ip_event { | 58 | struct ip_event { |
57 | struct perf_event_header header; | 59 | struct perf_event_header header; |
58 | u64 ip; | 60 | u64 ip; |
@@ -1135,7 +1137,7 @@ static int validate_chain(struct ip_callchain *chain, event_t *event) | |||
1135 | } | 1137 | } |
1136 | 1138 | ||
1137 | static int | 1139 | static int |
1138 | process_overflow_event(event_t *event, unsigned long offset, unsigned long head) | 1140 | process_sample_event(event_t *event, unsigned long offset, unsigned long head) |
1139 | { | 1141 | { |
1140 | char level; | 1142 | char level; |
1141 | int show = 0; | 1143 | int show = 0; |
@@ -1147,12 +1149,12 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head) | |||
1147 | void *more_data = event->ip.__more_data; | 1149 | void *more_data = event->ip.__more_data; |
1148 | struct ip_callchain *chain = NULL; | 1150 | struct ip_callchain *chain = NULL; |
1149 | 1151 | ||
1150 | if (event->header.type & PERF_SAMPLE_PERIOD) { | 1152 | if (sample_type & PERF_SAMPLE_PERIOD) { |
1151 | period = *(u64 *)more_data; | 1153 | period = *(u64 *)more_data; |
1152 | more_data += sizeof(u64); | 1154 | more_data += sizeof(u64); |
1153 | } | 1155 | } |
1154 | 1156 | ||
1155 | dprintf("%p [%p]: PERF_EVENT (IP, %d): %d: %p period: %Ld\n", | 1157 | dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d: %p period: %Ld\n", |
1156 | (void *)(offset + head), | 1158 | (void *)(offset + head), |
1157 | (void *)(long)(event->header.size), | 1159 | (void *)(long)(event->header.size), |
1158 | event->header.misc, | 1160 | event->header.misc, |
@@ -1160,7 +1162,7 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head) | |||
1160 | (void *)(long)ip, | 1162 | (void *)(long)ip, |
1161 | (long long)period); | 1163 | (long long)period); |
1162 | 1164 | ||
1163 | if (event->header.type & PERF_SAMPLE_CALLCHAIN) { | 1165 | if (sample_type & PERF_SAMPLE_CALLCHAIN) { |
1164 | int i; | 1166 | int i; |
1165 | 1167 | ||
1166 | chain = (void *)more_data; | 1168 | chain = (void *)more_data; |
@@ -1352,10 +1354,10 @@ process_event(event_t *event, unsigned long offset, unsigned long head) | |||
1352 | { | 1354 | { |
1353 | trace_event(event); | 1355 | trace_event(event); |
1354 | 1356 | ||
1355 | if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) | ||
1356 | return process_overflow_event(event, offset, head); | ||
1357 | |||
1358 | switch (event->header.type) { | 1357 | switch (event->header.type) { |
1358 | case PERF_EVENT_SAMPLE: | ||
1359 | return process_sample_event(event, offset, head); | ||
1360 | |||
1359 | case PERF_EVENT_MMAP: | 1361 | case PERF_EVENT_MMAP: |
1360 | return process_mmap_event(event, offset, head); | 1362 | return process_mmap_event(event, offset, head); |
1361 | 1363 | ||
@@ -1388,18 +1390,21 @@ process_event(event_t *event, unsigned long offset, unsigned long head) | |||
1388 | 1390 | ||
1389 | static struct perf_header *header; | 1391 | static struct perf_header *header; |
1390 | 1392 | ||
1391 | static int perf_header__has_sample(u64 sample_mask) | 1393 | static u64 perf_header__sample_type(void) |
1392 | { | 1394 | { |
1395 | u64 sample_type = 0; | ||
1393 | int i; | 1396 | int i; |
1394 | 1397 | ||
1395 | for (i = 0; i < header->attrs; i++) { | 1398 | for (i = 0; i < header->attrs; i++) { |
1396 | struct perf_header_attr *attr = header->attr[i]; | 1399 | struct perf_header_attr *attr = header->attr[i]; |
1397 | 1400 | ||
1398 | if (!(attr->attr.sample_type & sample_mask)) | 1401 | if (!sample_type) |
1399 | return 0; | 1402 | sample_type = attr->attr.sample_type; |
1403 | else if (sample_type != attr->attr.sample_type) | ||
1404 | die("non matching sample_type"); | ||
1400 | } | 1405 | } |
1401 | 1406 | ||
1402 | return 1; | 1407 | return sample_type; |
1403 | } | 1408 | } |
1404 | 1409 | ||
1405 | static int __cmd_report(void) | 1410 | static int __cmd_report(void) |
@@ -1437,8 +1442,9 @@ static int __cmd_report(void) | |||
1437 | header = perf_header__read(input); | 1442 | header = perf_header__read(input); |
1438 | head = header->data_offset; | 1443 | head = header->data_offset; |
1439 | 1444 | ||
1440 | if (sort__has_parent && | 1445 | sample_type = perf_header__sample_type(); |
1441 | !perf_header__has_sample(PERF_SAMPLE_CALLCHAIN)) { | 1446 | |
1447 | if (sort__has_parent && !(sample_type & PERF_SAMPLE_CALLCHAIN)) { | ||
1442 | fprintf(stderr, "selected --sort parent, but no callchain data\n"); | 1448 | fprintf(stderr, "selected --sort parent, but no callchain data\n"); |
1443 | exit(-1); | 1449 | exit(-1); |
1444 | } | 1450 | } |