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>
This commit is contained in:
Peter Zijlstra
2009-06-25 11:27:12 +02:00
committed by Ingo Molnar
parent bfbd3381e6
commit e6e18ec79b
5 changed files with 49 additions and 48 deletions

View File

@@ -53,6 +53,8 @@ static regex_t parent_regex;
static int exclude_other = 1;
static u64 sample_type;
struct ip_event {
struct perf_event_header header;
u64 ip;
@@ -1135,7 +1137,7 @@ static int validate_chain(struct ip_callchain *chain, event_t *event)
}
static int
process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
process_sample_event(event_t *event, unsigned long offset, unsigned long head)
{
char level;
int show = 0;
@@ -1147,12 +1149,12 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
void *more_data = event->ip.__more_data;
struct ip_callchain *chain = NULL;
if (event->header.type & PERF_SAMPLE_PERIOD) {
if (sample_type & PERF_SAMPLE_PERIOD) {
period = *(u64 *)more_data;
more_data += sizeof(u64);
}
dprintf("%p [%p]: PERF_EVENT (IP, %d): %d: %p period: %Ld\n",
dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d: %p period: %Ld\n",
(void *)(offset + head),
(void *)(long)(event->header.size),
event->header.misc,
@@ -1160,7 +1162,7 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
(void *)(long)ip,
(long long)period);
if (event->header.type & PERF_SAMPLE_CALLCHAIN) {
if (sample_type & PERF_SAMPLE_CALLCHAIN) {
int i;
chain = (void *)more_data;
@@ -1352,10 +1354,10 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
{
trace_event(event);
if (event->header.misc & PERF_EVENT_MISC_OVERFLOW)
return process_overflow_event(event, offset, head);
switch (event->header.type) {
case PERF_EVENT_SAMPLE:
return process_sample_event(event, offset, head);
case PERF_EVENT_MMAP:
return process_mmap_event(event, offset, head);
@@ -1388,18 +1390,21 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
static struct perf_header *header;
static int perf_header__has_sample(u64 sample_mask)
static u64 perf_header__sample_type(void)
{
u64 sample_type = 0;
int i;
for (i = 0; i < header->attrs; i++) {
struct perf_header_attr *attr = header->attr[i];
if (!(attr->attr.sample_type & sample_mask))
return 0;
if (!sample_type)
sample_type = attr->attr.sample_type;
else if (sample_type != attr->attr.sample_type)
die("non matching sample_type");
}
return 1;
return sample_type;
}
static int __cmd_report(void)
@@ -1437,8 +1442,9 @@ static int __cmd_report(void)
header = perf_header__read(input);
head = header->data_offset;
if (sort__has_parent &&
!perf_header__has_sample(PERF_SAMPLE_CALLCHAIN)) {
sample_type = perf_header__sample_type();
if (sort__has_parent && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
fprintf(stderr, "selected --sort parent, but no callchain data\n");
exit(-1);
}