Skip to content

Commit

Permalink
perf tools: Release thread resources on PERF_RECORD_EXIT
Browse files Browse the repository at this point in the history
For long running sessions with many threads with short lifetimes the
amount of memory that the buildid process takes is too much.

Since we don't have hist_entries that may be pointing to them, we can
just release the resources associated with each thread when the exit
(PERF_RECORD_EXIT) event is received.

For normal processing we need to annotate maps with hits, and thus
hist_entries pointing to it and drop the ones that had none. Will be
done in a followup patch.

Cc: David S. Miller <davem@davemloft.net>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Arnaldo Carvalho de Melo committed Jul 30, 2010
1 parent 0e60836 commit 591765f
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 0 deletions.
18 changes: 18 additions & 0 deletions tools/perf/util/build-id.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "event.h"
#include "symbol.h"
#include <linux/kernel.h>
#include "debug.h"

static int build_id__mark_dso_hit(event_t *event, struct perf_session *session)
{
Expand All @@ -34,10 +35,27 @@ static int build_id__mark_dso_hit(event_t *event, struct perf_session *session)
return 0;
}

static int event__exit_del_thread(event_t *self, struct perf_session *session)
{
struct thread *thread = perf_session__findnew(session, self->fork.tid);

dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid,
self->fork.ppid, self->fork.ptid);

if (thread) {
rb_erase(&thread->rb_node, &session->threads);
session->last_match = NULL;
thread__delete(thread);
}

return 0;
}

struct perf_event_ops build_id__mark_dso_hit_ops = {
.sample = build_id__mark_dso_hit,
.mmap = event__process_mmap,
.fork = event__process_task,
.exit = event__exit_del_thread,
};

char *dso__build_id_filename(struct dso *self, char *bf, size_t size)
Expand Down
33 changes: 33 additions & 0 deletions tools/perf/util/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,39 @@ void map_groups__init(struct map_groups *self)
self->machine = NULL;
}

static void maps__delete(struct rb_root *self)
{
struct rb_node *next = rb_first(self);

while (next) {
struct map *pos = rb_entry(next, struct map, rb_node);

next = rb_next(&pos->rb_node);
rb_erase(&pos->rb_node, self);
map__delete(pos);
}
}

static void maps__delete_removed(struct list_head *self)
{
struct map *pos, *n;

list_for_each_entry_safe(pos, n, self, node) {
list_del(&pos->node);
map__delete(pos);
}
}

void map_groups__exit(struct map_groups *self)
{
int i;

for (i = 0; i < MAP__NR_TYPES; ++i) {
maps__delete(&self->maps[i]);
maps__delete_removed(&self->removed_maps[i]);
}
}

void map_groups__flush(struct map_groups *self)
{
int type;
Expand Down
1 change: 1 addition & 0 deletions tools/perf/util/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ size_t __map_groups__fprintf_maps(struct map_groups *self,
void maps__insert(struct rb_root *maps, struct map *map);
struct map *maps__find(struct rb_root *maps, u64 addr);
void map_groups__init(struct map_groups *self);
void map_groups__exit(struct map_groups *self);
int map_groups__clone(struct map_groups *self,
struct map_groups *parent, enum map_type type);
size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp);
Expand Down
7 changes: 7 additions & 0 deletions tools/perf/util/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ static struct thread *thread__new(pid_t pid)
return self;
}

void thread__delete(struct thread *self)
{
map_groups__exit(&self->mg);
free(self->comm);
free(self);
}

int thread__set_comm(struct thread *self, const char *comm)
{
int err;
Expand Down
2 changes: 2 additions & 0 deletions tools/perf/util/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ struct thread {

struct perf_session;

void thread__delete(struct thread *self);

int find_all_tid(int pid, pid_t ** all_tid);
int thread__set_comm(struct thread *self, const char *comm);
int thread__comm_len(struct thread *self);
Expand Down

0 comments on commit 591765f

Please sign in to comment.