Commit d114960c authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo

perf callchain: Free callchains when hist entries are deleted

Markus reported that "perf top -g" can leak ~300MB per second on his
machine.  This is partly because it missed to free callchains when hist
entries are deleted.  Fix it.
Reported-by: default avatarMarkus Trippelsdorf <markus@trippelsdorf.de>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Markus Trippelsdorf <markus@trippelsdorf.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20141230053813.GD6081@sejongSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 5ca82710
...@@ -841,3 +841,33 @@ char *callchain_list__sym_name(struct callchain_list *cl, ...@@ -841,3 +841,33 @@ char *callchain_list__sym_name(struct callchain_list *cl,
return bf; return bf;
} }
static void free_callchain_node(struct callchain_node *node)
{
struct callchain_list *list, *tmp;
struct callchain_node *child;
struct rb_node *n;
list_for_each_entry_safe(list, tmp, &node->val, list) {
list_del(&list->list);
free(list);
}
n = rb_first(&node->rb_root_in);
while (n) {
child = container_of(n, struct callchain_node, rb_node_in);
n = rb_next(n);
rb_erase(&child->rb_node_in, &node->rb_root_in);
free_callchain_node(child);
free(child);
}
}
void free_callchain(struct callchain_root *root)
{
if (!symbol_conf.use_callchain)
return;
free_callchain_node(&root->node);
}
...@@ -198,4 +198,6 @@ static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused, ...@@ -198,4 +198,6 @@ static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused,
char *callchain_list__sym_name(struct callchain_list *cl, char *callchain_list__sym_name(struct callchain_list *cl,
char *bf, size_t bfsize, bool show_dso); char *bf, size_t bfsize, bool show_dso);
void free_callchain(struct callchain_root *root);
#endif /* __PERF_CALLCHAIN_H */ #endif /* __PERF_CALLCHAIN_H */
...@@ -947,6 +947,7 @@ void hist_entry__free(struct hist_entry *he) ...@@ -947,6 +947,7 @@ void hist_entry__free(struct hist_entry *he)
zfree(&he->mem_info); zfree(&he->mem_info);
zfree(&he->stat_acc); zfree(&he->stat_acc);
free_srcline(he->srcline); free_srcline(he->srcline);
free_callchain(he->callchain);
free(he); free(he);
} }
......
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