mirror of
https://github.com/torvalds/linux.git
synced 2024-11-07 04:32:03 +00:00
perf hists browser: Fix percent display in callchains
When there's only a single callchain, perf doesn't print its percentage in front of the symbols. This is because it assumes that the percentage is same as parents. But if a percent limit is applied, it's possible that there are actually a couple of child nodes but only one of them is shown. In this case it should display the percent to prevent misunderstanding of its percentage is same as the parent's. For example, let's see the following callchain. $ perf report --no-children --percent-limit 0.01 --tui ... - 0.06% sleep [kernel.vmlinux] [k] kmem_cache_alloc_trace kmem_cache_alloc_trace - perf_event_mmap - 0.04% mmap_region do_mmap_pgoff - vm_mmap_pgoff + 0.02% sys_mmap_pgoff + 0.02% vm_mmap + 0.02% mprotect_fixup Current code omits the percent if 'mmap_region' becomes the only node when percent limit is set to 0.03%, its percent is not 0.06% but users will assume it incorrectly. Before: $ perf report --no-children --percent-limit 0.03 --tui ... 0.06% sleep [kernel.vmlinux] [k] kmem_cache_alloc_trace kmem_cache_alloc_trace - perf_event_mmap - mmap_region do_mmap_pgoff vm_mmap_pgoff After: $ perf report --no-children --percent-limit 0.03 --tui ... 0.06% sleep [kernel.vmlinux] [k] kmem_cache_alloc_trace kmem_cache_alloc_trace - perf_event_mmap - 0.04% mmap_region do_mmap_pgoff vm_mmap_pgoff Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Andi Kleen <andi@firstfloor.org> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/r/1453909257-26015-10-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
5eca104eee
commit
59c624e239
@ -657,10 +657,24 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool check_percent_display(struct rb_node *node, u64 parent_total)
|
||||||
|
{
|
||||||
|
struct callchain_node *child;
|
||||||
|
|
||||||
|
if (node == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (rb_next(node))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
child = rb_entry(node, struct callchain_node, rb_node);
|
||||||
|
return callchain_cumul_hits(child) != parent_total;
|
||||||
|
}
|
||||||
|
|
||||||
static int hist_browser__show_callchain_flat(struct hist_browser *browser,
|
static int hist_browser__show_callchain_flat(struct hist_browser *browser,
|
||||||
struct rb_root *root,
|
struct rb_root *root,
|
||||||
unsigned short row, u64 total,
|
unsigned short row, u64 total,
|
||||||
u64 parent_total __maybe_unused,
|
u64 parent_total,
|
||||||
print_callchain_entry_fn print,
|
print_callchain_entry_fn print,
|
||||||
struct callchain_print_arg *arg,
|
struct callchain_print_arg *arg,
|
||||||
check_output_full_fn is_output_full)
|
check_output_full_fn is_output_full)
|
||||||
@ -670,7 +684,7 @@ static int hist_browser__show_callchain_flat(struct hist_browser *browser,
|
|||||||
bool need_percent;
|
bool need_percent;
|
||||||
|
|
||||||
node = rb_first(root);
|
node = rb_first(root);
|
||||||
need_percent = node && rb_next(node);
|
need_percent = check_percent_display(node, parent_total);
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
|
struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
|
||||||
@ -764,7 +778,7 @@ static char *hist_browser__folded_callchain_str(struct hist_browser *browser,
|
|||||||
static int hist_browser__show_callchain_folded(struct hist_browser *browser,
|
static int hist_browser__show_callchain_folded(struct hist_browser *browser,
|
||||||
struct rb_root *root,
|
struct rb_root *root,
|
||||||
unsigned short row, u64 total,
|
unsigned short row, u64 total,
|
||||||
u64 parent_total __maybe_unused,
|
u64 parent_total,
|
||||||
print_callchain_entry_fn print,
|
print_callchain_entry_fn print,
|
||||||
struct callchain_print_arg *arg,
|
struct callchain_print_arg *arg,
|
||||||
check_output_full_fn is_output_full)
|
check_output_full_fn is_output_full)
|
||||||
@ -774,7 +788,7 @@ static int hist_browser__show_callchain_folded(struct hist_browser *browser,
|
|||||||
bool need_percent;
|
bool need_percent;
|
||||||
|
|
||||||
node = rb_first(root);
|
node = rb_first(root);
|
||||||
need_percent = node && rb_next(node);
|
need_percent = check_percent_display(node, parent_total);
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
|
struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
|
||||||
@ -863,7 +877,7 @@ static int hist_browser__show_callchain_graph(struct hist_browser *browser,
|
|||||||
percent_total = parent_total;
|
percent_total = parent_total;
|
||||||
|
|
||||||
node = rb_first(root);
|
node = rb_first(root);
|
||||||
need_percent = node && rb_next(node);
|
need_percent = check_percent_display(node, parent_total);
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
|
struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
|
||||||
|
Loading…
Reference in New Issue
Block a user