Skip to content

Commit

Permalink
perf_counter tools: Use fork and remove munmap events
Browse files Browse the repository at this point in the history
Use fork events to clone comm and map data and remove everything
munmap related

Signed-off-by: Peter 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: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Jun 4, 2009
1 parent d99e944 commit 62fc445
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 31 deletions.
103 changes: 93 additions & 10 deletions Documentation/perf_counter/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,6 @@ static int full_paths;
static unsigned long page_size;
static unsigned long mmap_window = 32;

const char *perf_event_names[] = {
[PERF_EVENT_MMAP] = " PERF_EVENT_MMAP",
[PERF_EVENT_MUNMAP] = " PERF_EVENT_MUNMAP",
[PERF_EVENT_COMM] = " PERF_EVENT_COMM",
};

struct ip_event {
struct perf_event_header header;
__u64 ip;
Expand All @@ -70,11 +64,17 @@ struct comm_event {
char comm[16];
};

struct fork_event {
struct perf_event_header header;
__u32 pid, ppid;
};

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;
} event_t;

static LIST_HEAD(dsos);
Expand Down Expand Up @@ -208,7 +208,31 @@ static struct map *map__new(struct mmap_event *event)
return NULL;
}

struct thread;
static struct map *map__clone(struct map *self)
{
struct map *map = malloc(sizeof(*self));

if (!map)
return NULL;

memcpy(map, self, sizeof(*self));

return map;
}

static int map__overlap(struct map *l, struct map *r)
{
if (l->start > r->start) {
struct map *t = l;
l = r;
r = t;
}

if (l->end > r->start)
return 1;

return 0;
}

struct thread {
struct rb_node rb_node;
Expand Down Expand Up @@ -284,9 +308,39 @@ static struct thread *threads__findnew(pid_t pid)

static void thread__insert_map(struct thread *self, struct map *map)
{
struct map *pos, *tmp;

list_for_each_entry_safe(pos, tmp, &self->maps, node) {
if (map__overlap(pos, map)) {
list_del_init(&pos->node);
/* XXX leaks dsos */
free(pos);
}
}

list_add_tail(&map->node, &self->maps);
}

static int thread__fork(struct thread *self, struct thread *parent)
{
struct map *map;

if (self->comm)
free(self->comm);
self->comm = strdup(parent->comm);
if (!self->comm)
return -ENOMEM;

list_for_each_entry(map, &parent->maps, node) {
struct map *new = map__clone(map);
if (!new)
return -ENOMEM;
thread__insert_map(self, new);
}

return 0;
}

static struct map *thread__find_map(struct thread *self, uint64_t ip)
{
struct map *pos;
Expand Down Expand Up @@ -784,7 +838,11 @@ static void register_idle_thread(void)
}
}

static unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0;
static unsigned long total = 0,
total_mmap = 0,
total_comm = 0,
total_fork = 0,
total_unknown = 0;

static int
process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
Expand Down Expand Up @@ -866,9 +924,10 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
struct thread *thread = threads__findnew(event->mmap.pid);
struct map *map = map__new(&event->mmap);

dprintf("%p [%p]: PERF_EVENT_MMAP: [%p(%p) @ %p]: %s\n",
dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
(void *)(offset + head),
(void *)(long)(event->header.size),
event->mmap.pid,
(void *)(long)event->mmap.start,
(void *)(long)event->mmap.len,
(void *)(long)event->mmap.pgoff,
Expand Down Expand Up @@ -905,6 +964,26 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head)
return 0;
}

static int
process_fork_event(event_t *event, unsigned long offset, unsigned long head)
{
struct thread *thread = threads__findnew(event->fork.pid);
struct thread *parent = threads__findnew(event->fork.ppid);

dprintf("%p [%p]: PERF_EVENT_FORK: %d:%d\n",
(void *)(offset + head),
(void *)(long)(event->header.size),
event->fork.pid, event->fork.ppid);

if (!thread || !parent || thread__fork(thread, parent)) {
dprintf("problem processing PERF_EVENT_FORK, skipping event.\n");
return -1;
}
total_fork++;

return 0;
}

static int
process_event(event_t *event, unsigned long offset, unsigned long head)
{
Expand All @@ -918,10 +997,13 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
case PERF_EVENT_COMM:
return process_comm_event(event, offset, head);

case PERF_EVENT_FORK:
return process_fork_event(event, offset, head);

/*
* We dont process them right now but they are fine:
*/
case PERF_EVENT_MUNMAP:

case PERF_EVENT_PERIOD:
case PERF_EVENT_THROTTLE:
case PERF_EVENT_UNTHROTTLE:
Expand Down Expand Up @@ -1038,6 +1120,7 @@ static int __cmd_report(void)
dprintf(" IP events: %10ld\n", total);
dprintf(" mmap events: %10ld\n", total_mmap);
dprintf(" comm events: %10ld\n", total_comm);
dprintf(" fork events: %10ld\n", total_fork);
dprintf(" unknown events: %10ld\n", total_unknown);

if (dump_trace)
Expand Down
21 changes: 0 additions & 21 deletions Documentation/perf_counter/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ static unsigned int realtime_prio = 0;
static int group = 0;
static unsigned int page_size;
static unsigned int mmap_pages = 16;
static int use_mmap = 0;
static int use_munmap = 0;
static int freq = 0;

static char *sym_filter;
Expand Down Expand Up @@ -527,19 +525,6 @@ static void mmap_read(struct mmap_data *md)
if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) {
if (event->header.type & PERF_SAMPLE_IP)
process_event(event->ip.ip, md->counter);
} else {
switch (event->header.type) {
case PERF_EVENT_MMAP:
case PERF_EVENT_MUNMAP:
printf("%s: %Lu %Lu %Lu %s\n",
event->header.type == PERF_EVENT_MMAP
? "mmap" : "munmap",
event->mmap.start,
event->mmap.len,
event->mmap.pgoff,
event->mmap.filename);
break;
}
}
}

Expand Down Expand Up @@ -569,8 +554,6 @@ static int __cmd_top(void)
attr.config = event_id[counter];
attr.sample_period = event_count[counter];
attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
attr.mmap = use_mmap;
attr.munmap = use_munmap;
attr.freq = freq;

fd[i][counter] = sys_perf_counter_open(&attr, target_pid, cpu, group_fd, 0);
Expand Down Expand Up @@ -670,10 +653,6 @@ static const struct option options[] = {
"only display symbols matchig this pattern"),
OPT_BOOLEAN('z', "zero", &group,
"zero history across updates"),
OPT_BOOLEAN('M', "use-mmap", &use_mmap,
"track mmap events"),
OPT_BOOLEAN('U', "use-munmap", &use_munmap,
"track munmap events"),
OPT_INTEGER('F', "freq", &freq,
"profile at this frequency"),
OPT_INTEGER('E', "entries", &print_entries,
Expand Down

0 comments on commit 62fc445

Please sign in to comment.