Skip to content

Commit

Permalink
perf tools: Flush maps on COMM events
Browse files Browse the repository at this point in the history
Even though we don't register the counters until the child is right about
to exec(), we're still going to get at least a few events while the
fork()'d child is still executing 'perf' and in particular we're going to
get the MMAP events.

We can't distinguish the ones in the newly executed process because the
PID will be the same.

One way to solve this would be to have a PERF_RECORD_EXEC event, and when
this is seen 'perf' can flush it's map cache.  We can't use
PERF_RECORD_COMM since that's generated by other things, not just exec().

Actually, thinking about it some more, using PERF_RECORD_COMM might be a
good enough approximation.

Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1267196914-16238-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
David S. Miller authored and Ingo Molnar committed Feb 26, 2010
1 parent f22f54f commit 4385d58
Showing 1 changed file with 30 additions and 4 deletions.
34 changes: 30 additions & 4 deletions tools/perf/util/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,41 @@ static struct thread *thread__new(pid_t pid)
return self;
}

static void map_groups__flush(struct map_groups *self)
{
int type;

for (type = 0; type < MAP__NR_TYPES; type++) {
struct rb_root *root = &self->maps[type];
struct rb_node *next = rb_first(root);

while (next) {
struct map *pos = rb_entry(next, struct map, rb_node);
next = rb_next(&pos->rb_node);
rb_erase(&pos->rb_node, root);
/*
* We may have references to this map, for
* instance in some hist_entry instances, so
* just move them to a separate list.
*/
list_add_tail(&pos->node, &self->removed_maps[pos->type]);
}
}
}

int thread__set_comm(struct thread *self, const char *comm)
{
int err;

if (self->comm)
free(self->comm);
self->comm = strdup(comm);
if (self->comm == NULL)
return -ENOMEM;
self->comm_set = true;
return 0;
err = self->comm == NULL ? -ENOMEM : 0;
if (!err) {
self->comm_set = true;
map_groups__flush(&self->mg);
}
return err;
}

int thread__comm_len(struct thread *self)
Expand Down

0 comments on commit 4385d58

Please sign in to comment.