diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-report.c | 4 | ||||
-rw-r--r-- | tools/perf/util/callchain.c | 27 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 7 |
3 files changed, 24 insertions, 14 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 8cb58d68a006..da402e186561 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -901,7 +901,7 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | |||
901 | int i; | 901 | int i; |
902 | 902 | ||
903 | if (callchain_param.mode == CHAIN_GRAPH_REL) | 903 | if (callchain_param.mode == CHAIN_GRAPH_REL) |
904 | new_total = self->cumul_hit; | 904 | new_total = self->children_hit; |
905 | else | 905 | else |
906 | new_total = total_samples; | 906 | new_total = total_samples; |
907 | 907 | ||
@@ -930,7 +930,7 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | |||
930 | ret += ipchain__fprintf_graph(fp, chain, depth, | 930 | ret += ipchain__fprintf_graph(fp, chain, depth, |
931 | new_depth_mask, i++, | 931 | new_depth_mask, i++, |
932 | new_total, | 932 | new_total, |
933 | child->cumul_hit); | 933 | cumul_hits(child)); |
934 | } | 934 | } |
935 | ret += callchain__fprintf_graph(fp, child, new_total, | 935 | ret += callchain__fprintf_graph(fp, child, new_total, |
936 | depth + 1, | 936 | depth + 1, |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 9d3c8141b8c1..98c5627f327b 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -26,10 +26,14 @@ rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, | |||
26 | struct rb_node **p = &root->rb_node; | 26 | struct rb_node **p = &root->rb_node; |
27 | struct rb_node *parent = NULL; | 27 | struct rb_node *parent = NULL; |
28 | struct callchain_node *rnode; | 28 | struct callchain_node *rnode; |
29 | u64 chain_cumul = cumul_hits(chain); | ||
29 | 30 | ||
30 | while (*p) { | 31 | while (*p) { |
32 | u64 rnode_cumul; | ||
33 | |||
31 | parent = *p; | 34 | parent = *p; |
32 | rnode = rb_entry(parent, struct callchain_node, rb_node); | 35 | rnode = rb_entry(parent, struct callchain_node, rb_node); |
36 | rnode_cumul = cumul_hits(rnode); | ||
33 | 37 | ||
34 | switch (mode) { | 38 | switch (mode) { |
35 | case CHAIN_FLAT: | 39 | case CHAIN_FLAT: |
@@ -40,7 +44,7 @@ rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, | |||
40 | break; | 44 | break; |
41 | case CHAIN_GRAPH_ABS: /* Falldown */ | 45 | case CHAIN_GRAPH_ABS: /* Falldown */ |
42 | case CHAIN_GRAPH_REL: | 46 | case CHAIN_GRAPH_REL: |
43 | if (rnode->cumul_hit < chain->cumul_hit) | 47 | if (rnode_cumul < chain_cumul) |
44 | p = &(*p)->rb_left; | 48 | p = &(*p)->rb_left; |
45 | else | 49 | else |
46 | p = &(*p)->rb_right; | 50 | p = &(*p)->rb_right; |
@@ -87,7 +91,7 @@ static void __sort_chain_graph_abs(struct callchain_node *node, | |||
87 | 91 | ||
88 | chain_for_each_child(child, node) { | 92 | chain_for_each_child(child, node) { |
89 | __sort_chain_graph_abs(child, min_hit); | 93 | __sort_chain_graph_abs(child, min_hit); |
90 | if (child->cumul_hit >= min_hit) | 94 | if (cumul_hits(child) >= min_hit) |
91 | rb_insert_callchain(&node->rb_root, child, | 95 | rb_insert_callchain(&node->rb_root, child, |
92 | CHAIN_GRAPH_ABS); | 96 | CHAIN_GRAPH_ABS); |
93 | } | 97 | } |
@@ -108,11 +112,11 @@ static void __sort_chain_graph_rel(struct callchain_node *node, | |||
108 | u64 min_hit; | 112 | u64 min_hit; |
109 | 113 | ||
110 | node->rb_root = RB_ROOT; | 114 | node->rb_root = RB_ROOT; |
111 | min_hit = node->cumul_hit * min_percent / 100.0; | 115 | min_hit = node->children_hit * min_percent / 100.0; |
112 | 116 | ||
113 | chain_for_each_child(child, node) { | 117 | chain_for_each_child(child, node) { |
114 | __sort_chain_graph_rel(child, min_percent); | 118 | __sort_chain_graph_rel(child, min_percent); |
115 | if (child->cumul_hit >= min_hit) | 119 | if (cumul_hits(child) >= min_hit) |
116 | rb_insert_callchain(&node->rb_root, child, | 120 | rb_insert_callchain(&node->rb_root, child, |
117 | CHAIN_GRAPH_REL); | 121 | CHAIN_GRAPH_REL); |
118 | } | 122 | } |
@@ -211,7 +215,8 @@ add_child(struct callchain_node *parent, struct ip_callchain *chain, | |||
211 | new = create_child(parent, false); | 215 | new = create_child(parent, false); |
212 | fill_node(new, chain, start, syms); | 216 | fill_node(new, chain, start, syms); |
213 | 217 | ||
214 | new->cumul_hit = new->hit = 1; | 218 | new->children_hit = 0; |
219 | new->hit = 1; | ||
215 | } | 220 | } |
216 | 221 | ||
217 | /* | 222 | /* |
@@ -241,7 +246,8 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain, | |||
241 | 246 | ||
242 | /* split the hits */ | 247 | /* split the hits */ |
243 | new->hit = parent->hit; | 248 | new->hit = parent->hit; |
244 | new->cumul_hit = parent->cumul_hit; | 249 | new->children_hit = parent->children_hit; |
250 | parent->children_hit = cumul_hits(new); | ||
245 | new->val_nr = parent->val_nr - idx_local; | 251 | new->val_nr = parent->val_nr - idx_local; |
246 | parent->val_nr = idx_local; | 252 | parent->val_nr = idx_local; |
247 | 253 | ||
@@ -249,6 +255,7 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain, | |||
249 | if (idx_total < chain->nr) { | 255 | if (idx_total < chain->nr) { |
250 | parent->hit = 0; | 256 | parent->hit = 0; |
251 | add_child(parent, chain, idx_total, syms); | 257 | add_child(parent, chain, idx_total, syms); |
258 | parent->children_hit++; | ||
252 | } else { | 259 | } else { |
253 | parent->hit = 1; | 260 | parent->hit = 1; |
254 | } | 261 | } |
@@ -269,13 +276,13 @@ __append_chain_children(struct callchain_node *root, struct ip_callchain *chain, | |||
269 | unsigned int ret = __append_chain(rnode, chain, start, syms); | 276 | unsigned int ret = __append_chain(rnode, chain, start, syms); |
270 | 277 | ||
271 | if (!ret) | 278 | if (!ret) |
272 | goto cumul; | 279 | goto inc_children_hit; |
273 | } | 280 | } |
274 | /* nothing in children, add to the current node */ | 281 | /* nothing in children, add to the current node */ |
275 | add_child(root, chain, start, syms); | 282 | add_child(root, chain, start, syms); |
276 | 283 | ||
277 | cumul: | 284 | inc_children_hit: |
278 | root->cumul_hit++; | 285 | root->children_hit++; |
279 | } | 286 | } |
280 | 287 | ||
281 | static int | 288 | static int |
@@ -317,8 +324,6 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain, | |||
317 | /* we match 100% of the path, increment the hit */ | 324 | /* we match 100% of the path, increment the hit */ |
318 | if (i - start == root->val_nr && i == chain->nr) { | 325 | if (i - start == root->val_nr && i == chain->nr) { |
319 | root->hit++; | 326 | root->hit++; |
320 | root->cumul_hit++; | ||
321 | |||
322 | return 0; | 327 | return 0; |
323 | } | 328 | } |
324 | 329 | ||
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 7812122bea1d..b2d128e07c88 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -21,7 +21,7 @@ struct callchain_node { | |||
21 | struct rb_root rb_root; /* sorted tree of children */ | 21 | struct rb_root rb_root; /* sorted tree of children */ |
22 | unsigned int val_nr; | 22 | unsigned int val_nr; |
23 | u64 hit; | 23 | u64 hit; |
24 | u64 cumul_hit; /* hit + hits of children */ | 24 | u64 children_hit; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | struct callchain_param; | 27 | struct callchain_param; |
@@ -48,6 +48,11 @@ static inline void callchain_init(struct callchain_node *node) | |||
48 | INIT_LIST_HEAD(&node->val); | 48 | INIT_LIST_HEAD(&node->val); |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline u64 cumul_hits(struct callchain_node *node) | ||
52 | { | ||
53 | return node->hit + node->children_hit; | ||
54 | } | ||
55 | |||
51 | int register_callchain_param(struct callchain_param *param); | 56 | int register_callchain_param(struct callchain_param *param); |
52 | void append_chain(struct callchain_node *root, struct ip_callchain *chain, | 57 | void append_chain(struct callchain_node *root, struct ip_callchain *chain, |
53 | struct symbol **syms); | 58 | struct symbol **syms); |