aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-report.c4
-rw-r--r--tools/perf/util/callchain.c27
-rw-r--r--tools/perf/util/callchain.h7
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
277cumul: 284inc_children_hit:
278 root->cumul_hit++; 285 root->children_hit++;
279} 286}
280 287
281static int 288static 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
27struct callchain_param; 27struct 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
51static inline u64 cumul_hits(struct callchain_node *node)
52{
53 return node->hit + node->children_hit;
54}
55
51int register_callchain_param(struct callchain_param *param); 56int register_callchain_param(struct callchain_param *param);
52void append_chain(struct callchain_node *root, struct ip_callchain *chain, 57void append_chain(struct callchain_node *root, struct ip_callchain *chain,
53 struct symbol **syms); 58 struct symbol **syms);