From d2009c5130b627d3efccae8ed36cd43450c8486d Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 22 Aug 2010 20:05:22 +0200 Subject: perf: Keep track of the max depth of a callchain In order to implement callchains collapsing, we need to keep track of the maximum depth in a histogram tree of callchains. This way we'll avoid allocating an arbitrary temporary buffer size on callchain merge time. Signed-off-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Christoph Hellwig --- tools/perf/util/callchain.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'tools/perf/util/callchain.h') diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 624a96c..9b93a38 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -26,9 +26,14 @@ struct callchain_node { u64 children_hit; }; +struct callchain_root { + u64 max_depth; + struct callchain_node node; +}; + struct callchain_param; -typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *, +typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_root *, u64, struct callchain_param *); struct callchain_param { @@ -44,14 +49,15 @@ struct callchain_list { struct list_head list; }; -static inline void callchain_init(struct callchain_node *node) +static inline void callchain_init(struct callchain_root *root) { - INIT_LIST_HEAD(&node->brothers); - INIT_LIST_HEAD(&node->children); - INIT_LIST_HEAD(&node->val); + INIT_LIST_HEAD(&root->node.brothers); + INIT_LIST_HEAD(&root->node.children); + INIT_LIST_HEAD(&root->node.val); - node->parent = NULL; - node->hit = 0; + root->node.parent = NULL; + root->node.hit = 0; + root->max_depth = 0; } static inline u64 cumul_hits(struct callchain_node *node) @@ -60,7 +66,7 @@ static inline u64 cumul_hits(struct callchain_node *node) } int register_callchain_param(struct callchain_param *param); -int append_chain(struct callchain_node *root, struct ip_callchain *chain, +int append_chain(struct callchain_root *root, struct ip_callchain *chain, struct map_symbol *syms, u64 period); bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event); -- cgit v1.1 From 6cb8e56161c4103af9178ea45ba61ddbde02969a Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 22 Aug 2010 20:18:01 +0200 Subject: perf: Rename append_callchain into callchain_append Do that to start a consistant callchain API namespace. Signed-off-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Christoph Hellwig --- tools/perf/util/callchain.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/perf/util/callchain.h') diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 9b93a38..85b50fb 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -66,8 +66,8 @@ static inline u64 cumul_hits(struct callchain_node *node) } int register_callchain_param(struct callchain_param *param); -int append_chain(struct callchain_root *root, struct ip_callchain *chain, - struct map_symbol *syms, u64 period); +int callchain_append(struct callchain_root *root, struct ip_callchain *chain, + struct map_symbol *syms, u64 period); bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event); #endif /* __PERF_CALLCHAIN_H */ -- cgit v1.1 From 612d4fd7d0c4a866a531099d4cdd0424c1058321 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 22 Aug 2010 21:10:35 +0200 Subject: perf: Support for callchains merge If we sort the histograms by comm, which is the default, we need to merge some of them, typically different thread histograms of a same process, or just same comm. But during this merge, we forgot to merge callchains. So imagine we have three threads (tids: 1000, 1001, 1002) that belong to comm "foo". tid 1000 got 100 events tid 1001 got 10 events tid 1002 got 3 events Once we merge these histograms to get a per comm result, we'll finally get: "foo" got 113 events The problem is if we merge 1000 and 1001 histograms into 1002, then the end merge result, wrt callchains, will be only callchains that belong to 1002. This is because we haven't handled callchains in the merge. Only those from one of the threads inside a common comm survive. It means during this merge, we can lose a lot of callchains. Fix this by implementing callchains merge and apply it on histograms that collapse. Reported-by: Christoph Hellwig Signed-off-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras --- tools/perf/util/callchain.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/perf/util/callchain.h') diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 85b50fb..51a8f2b 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -68,6 +68,7 @@ static inline u64 cumul_hits(struct callchain_node *node) int register_callchain_param(struct callchain_param *param); int callchain_append(struct callchain_root *root, struct ip_callchain *chain, struct map_symbol *syms, u64 period); +int callchain_merge(struct callchain_root *dst, struct callchain_root *src); bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event); #endif /* __PERF_CALLCHAIN_H */ -- cgit v1.1