Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: callchain: Fix bad rounding of minimum rate

Sometimes we get callchain branches that have a rate under the
limit given by the user.

Say you launched:

perf record -f -g -a ./hackbench 10
perf report -g fractal,10.0

And you got:

2.33% hackbench [kernel] [k] _spin_lock_irqsave
|
|--78.57%-- remove_wait_queue
| poll_freewait
| do_sys_poll
| sys_poll
| sysenter_dispatch
| 0xf7ffa430
| 0x1ffadea3c
|
|--7.14%-- __up_read
| up_read
| do_page_fault
| page_fault
| 0xf7ffa430
| 0xa0df710000000a
...

It is abnormal to get a 7.14% branch whereas we passed a 10%
filter.

The problem is that we round down the minimum threshold. This
happens mostly when we have very low number of events. If the
total amount of your branch is 4 and you have a subranch of 3
events, filtering to 90% will be computed like follows:

limit = 4 * 0.9;

The result is about 3.6, but the cast to integer will round
down to 3. It means that our filter is actually of 75%

We must then explicitly round up the minimum threshold.

Reported-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: acme@redhat.com
Cc: peterz@infradead.org
Cc: efault@gmx.de
LKML-Reference: <20090809024235.GA10146@nowhere>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

authored by

Frederic Weisbecker and committed by
Ingo Molnar
c0a8865e 183f3b08

+3 -2
+3 -2
tools/perf/util/callchain.c
··· 13 13 #include <stdio.h> 14 14 #include <stdbool.h> 15 15 #include <errno.h> 16 + #include <math.h> 16 17 17 18 #include "callchain.h" 18 19 ··· 113 112 u64 min_hit; 114 113 115 114 node->rb_root = RB_ROOT; 116 - min_hit = node->children_hit * min_percent / 100.0; 115 + min_hit = ceil(node->children_hit * min_percent); 117 116 118 117 chain_for_each_child(child, node) { 119 118 __sort_chain_graph_rel(child, min_percent); ··· 127 126 sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_node *chain_root, 128 127 u64 min_hit __used, struct callchain_param *param) 129 128 { 130 - __sort_chain_graph_rel(chain_root, param->min_percent); 129 + __sort_chain_graph_rel(chain_root, param->min_percent / 100.0); 131 130 rb_root->rb_node = chain_root->rb_root.rb_node; 132 131 } 133 132