Commit b2fef076 authored by Ingo Molnar's avatar Ingo Molnar

perf_counter tools: Sample and display frequency adjustment changes

To allow the debugging of frequency-adjusting counters, sample
those adjustments and display them in perf report -D.
Acked-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 6a24ed6c
...@@ -347,7 +347,7 @@ static void create_counter(int counter, int cpu, pid_t pid) ...@@ -347,7 +347,7 @@ static void create_counter(int counter, int cpu, pid_t pid)
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
attr.config = event_id[counter]; attr.config = event_id[counter];
attr.sample_period = event_count[counter]; attr.sample_period = event_count[counter];
attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_PERIOD;
attr.freq = freq; attr.freq = freq;
attr.mmap = track; attr.mmap = track;
attr.comm = track; attr.comm = track;
......
...@@ -69,12 +69,20 @@ struct fork_event { ...@@ -69,12 +69,20 @@ struct fork_event {
__u32 pid, ppid; __u32 pid, ppid;
}; };
typedef union event_union { struct period_event {
struct perf_event_header header; struct perf_event_header header;
struct ip_event ip; __u64 time;
struct mmap_event mmap; __u64 id;
struct comm_event comm; __u64 sample_period;
struct fork_event fork; };
typedef union event_union {
struct perf_event_header header;
struct ip_event ip;
struct mmap_event mmap;
struct comm_event comm;
struct fork_event fork;
struct period_event period;
} event_t; } event_t;
static LIST_HEAD(dsos); static LIST_HEAD(dsos);
...@@ -1052,6 +1060,19 @@ process_fork_event(event_t *event, unsigned long offset, unsigned long head) ...@@ -1052,6 +1060,19 @@ process_fork_event(event_t *event, unsigned long offset, unsigned long head)
return 0; return 0;
} }
static int
process_period_event(event_t *event, unsigned long offset, unsigned long head)
{
dprintf("%p [%p]: PERF_EVENT_PERIOD: time:%Ld, id:%Ld: period:%Ld\n",
(void *)(offset + head),
(void *)(long)(event->header.size),
event->period.time,
event->period.id,
event->period.sample_period);
return 0;
}
static int static int
process_event(event_t *event, unsigned long offset, unsigned long head) process_event(event_t *event, unsigned long offset, unsigned long head)
{ {
...@@ -1068,11 +1089,12 @@ process_event(event_t *event, unsigned long offset, unsigned long head) ...@@ -1068,11 +1089,12 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
case PERF_EVENT_FORK: case PERF_EVENT_FORK:
return process_fork_event(event, offset, head); return process_fork_event(event, offset, head);
case PERF_EVENT_PERIOD:
return process_period_event(event, offset, head);
/* /*
* We dont process them right now but they are fine: * We dont process them right now but they are fine:
*/ */
case PERF_EVENT_PERIOD:
case PERF_EVENT_THROTTLE: case PERF_EVENT_THROTTLE:
case PERF_EVENT_UNTHROTTLE: case PERF_EVENT_UNTHROTTLE:
return 0; return 0;
...@@ -1157,6 +1179,11 @@ static int __cmd_report(void) ...@@ -1157,6 +1179,11 @@ static int __cmd_report(void)
size = event->header.size; size = event->header.size;
dprintf("%p [%p]: event: %d\n",
(void *)(offset + head),
(void *)(long)event->header.size,
event->header.type);
if (!size || process_event(event, offset, head) < 0) { if (!size || process_event(event, offset, head) < 0) {
dprintf("%p [%p]: skipping unknown header type: %d\n", dprintf("%p [%p]: skipping unknown header type: %d\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment