|
@@ -26,10 +26,14 @@ rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
|
|
struct rb_node **p = &root->rb_node;
|
|
struct rb_node **p = &root->rb_node;
|
|
struct rb_node *parent = NULL;
|
|
struct rb_node *parent = NULL;
|
|
struct callchain_node *rnode;
|
|
struct callchain_node *rnode;
|
|
|
|
+ u64 chain_cumul = cumul_hits(chain);
|
|
|
|
|
|
while (*p) {
|
|
while (*p) {
|
|
|
|
+ u64 rnode_cumul;
|
|
|
|
+
|
|
parent = *p;
|
|
parent = *p;
|
|
rnode = rb_entry(parent, struct callchain_node, rb_node);
|
|
rnode = rb_entry(parent, struct callchain_node, rb_node);
|
|
|
|
+ rnode_cumul = cumul_hits(rnode);
|
|
|
|
|
|
switch (mode) {
|
|
switch (mode) {
|
|
case CHAIN_FLAT:
|
|
case CHAIN_FLAT:
|
|
@@ -40,7 +44,7 @@ rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
|
|
break;
|
|
break;
|
|
case CHAIN_GRAPH_ABS: /* Falldown */
|
|
case CHAIN_GRAPH_ABS: /* Falldown */
|
|
case CHAIN_GRAPH_REL:
|
|
case CHAIN_GRAPH_REL:
|
|
- if (rnode->cumul_hit < chain->cumul_hit)
|
|
|
|
|
|
+ if (rnode_cumul < chain_cumul)
|
|
p = &(*p)->rb_left;
|
|
p = &(*p)->rb_left;
|
|
else
|
|
else
|
|
p = &(*p)->rb_right;
|
|
p = &(*p)->rb_right;
|
|
@@ -87,7 +91,7 @@ static void __sort_chain_graph_abs(struct callchain_node *node,
|
|
|
|
|
|
chain_for_each_child(child, node) {
|
|
chain_for_each_child(child, node) {
|
|
__sort_chain_graph_abs(child, min_hit);
|
|
__sort_chain_graph_abs(child, min_hit);
|
|
- if (child->cumul_hit >= min_hit)
|
|
|
|
|
|
+ if (cumul_hits(child) >= min_hit)
|
|
rb_insert_callchain(&node->rb_root, child,
|
|
rb_insert_callchain(&node->rb_root, child,
|
|
CHAIN_GRAPH_ABS);
|
|
CHAIN_GRAPH_ABS);
|
|
}
|
|
}
|
|
@@ -108,11 +112,11 @@ static void __sort_chain_graph_rel(struct callchain_node *node,
|
|
u64 min_hit;
|
|
u64 min_hit;
|
|
|
|
|
|
node->rb_root = RB_ROOT;
|
|
node->rb_root = RB_ROOT;
|
|
- min_hit = node->cumul_hit * min_percent / 100.0;
|
|
|
|
|
|
+ min_hit = node->children_hit * min_percent / 100.0;
|
|
|
|
|
|
chain_for_each_child(child, node) {
|
|
chain_for_each_child(child, node) {
|
|
__sort_chain_graph_rel(child, min_percent);
|
|
__sort_chain_graph_rel(child, min_percent);
|
|
- if (child->cumul_hit >= min_hit)
|
|
|
|
|
|
+ if (cumul_hits(child) >= min_hit)
|
|
rb_insert_callchain(&node->rb_root, child,
|
|
rb_insert_callchain(&node->rb_root, child,
|
|
CHAIN_GRAPH_REL);
|
|
CHAIN_GRAPH_REL);
|
|
}
|
|
}
|
|
@@ -211,7 +215,8 @@ add_child(struct callchain_node *parent, struct ip_callchain *chain,
|
|
new = create_child(parent, false);
|
|
new = create_child(parent, false);
|
|
fill_node(new, chain, start, syms);
|
|
fill_node(new, chain, start, syms);
|
|
|
|
|
|
- new->cumul_hit = new->hit = 1;
|
|
|
|
|
|
+ new->children_hit = 0;
|
|
|
|
+ new->hit = 1;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -241,7 +246,8 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain,
|
|
|
|
|
|
/* split the hits */
|
|
/* split the hits */
|
|
new->hit = parent->hit;
|
|
new->hit = parent->hit;
|
|
- new->cumul_hit = parent->cumul_hit;
|
|
|
|
|
|
+ new->children_hit = parent->children_hit;
|
|
|
|
+ parent->children_hit = cumul_hits(new);
|
|
new->val_nr = parent->val_nr - idx_local;
|
|
new->val_nr = parent->val_nr - idx_local;
|
|
parent->val_nr = idx_local;
|
|
parent->val_nr = idx_local;
|
|
|
|
|
|
@@ -249,6 +255,7 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain,
|
|
if (idx_total < chain->nr) {
|
|
if (idx_total < chain->nr) {
|
|
parent->hit = 0;
|
|
parent->hit = 0;
|
|
add_child(parent, chain, idx_total, syms);
|
|
add_child(parent, chain, idx_total, syms);
|
|
|
|
+ parent->children_hit++;
|
|
} else {
|
|
} else {
|
|
parent->hit = 1;
|
|
parent->hit = 1;
|
|
}
|
|
}
|
|
@@ -269,13 +276,13 @@ __append_chain_children(struct callchain_node *root, struct ip_callchain *chain,
|
|
unsigned int ret = __append_chain(rnode, chain, start, syms);
|
|
unsigned int ret = __append_chain(rnode, chain, start, syms);
|
|
|
|
|
|
if (!ret)
|
|
if (!ret)
|
|
- goto cumul;
|
|
|
|
|
|
+ goto inc_children_hit;
|
|
}
|
|
}
|
|
/* nothing in children, add to the current node */
|
|
/* nothing in children, add to the current node */
|
|
add_child(root, chain, start, syms);
|
|
add_child(root, chain, start, syms);
|
|
|
|
|
|
-cumul:
|
|
|
|
- root->cumul_hit++;
|
|
|
|
|
|
+inc_children_hit:
|
|
|
|
+ root->children_hit++;
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
static int
|
|
@@ -317,8 +324,6 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain,
|
|
/* we match 100% of the path, increment the hit */
|
|
/* we match 100% of the path, increment the hit */
|
|
if (i - start == root->val_nr && i == chain->nr) {
|
|
if (i - start == root->val_nr && i == chain->nr) {
|
|
root->hit++;
|
|
root->hit++;
|
|
- root->cumul_hit++;
|
|
|
|
-
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|