diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 07:55:37 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 07:55:37 +0300 |
commit | 5706ffd045c3810912c4982357d7daa721af3464 (patch) | |
tree | e238193fc65030fb2287af23b584d772ae9f79e8 /tools/perf/ui/browsers/hists.c | |
parent | c30110608cfba7efff3a5e71914aee7c816115c5 (diff) | |
parent | cfa0bd52d0ba9b852f76c7b3f1055edd5e5c7846 (diff) | |
download | linux-5706ffd045c3810912c4982357d7daa721af3464.tar.xz |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf events update from Ingo Molnar:
"On the kernel side there's few changes, the one that stands out is
PEBS machine state sampling support on x86, by Stephane Eranian.
On the tooling side:
User visible tooling changes:
- Don't open the DWARF info multiple times, keeping instead a dwfl
handle in struct dso, greatly speeding up 'perf report' on powerpc.
(Sukadev Bhattiprolu)
- Introduce PARSE_OPT_DISABLED option flag and use it to avoid
showing undersired options in tools that provides frontends to
'perf record', like sched, kvm, etc (Namhyung Kim)
- Fallback to kallsyms when using the minimal 'ELF' loader (Arnaldo
Carvalho de Melo)
- Fix annotation with kcore (Adrian Hunter)
- Support source line numbers in annotate using a hotkey (Andi Kleen)
- Callchain improvements including:
* Enable printing the srcline in the history
* Make get_srcline fall back to sym+offset (Andi Kleen)
- TUI hist_entry browser fixes, including showing missing overhead
value for first level callchain. Detected comparing the output of
--stdio/--gui (that matched) with --tui, that had this problem.
(Namhyung Kim)
- Support handling complete branch stacks as histograms (Andi Kleen)
Tooling infrastructure changes:
- Prep work for supporting per-pkg and snapshot counters in 'perf
stat' (Jiri Olsa)
- 'perf stat' refactorings, moving stuff from it to evsel.c to use in
per-pkg/snapshot format changes (Jiri Olsa)
- Add per-pkg format file parsing (Matt Fleming)
- Clean up libelf feature support code (Namhyung Kim)
- Add gzip decompression support for kernel modules (Namhyung Kim)
- More prep patches for Intel PT, including a a thread stack and more
stuff made available via the database export mechanism (Adrian
Hunter)
- More Intel PT work, including a facility to export sample data
(comms, threads, symbol names, etc) in a database friendly way,
with an script to use this to create a postgresql database.
(Adrian Hunter)
- Make sure that thread->mg->machine points to the machine where the
thread exists (it was being set only for the kmaps kernel modules
case, do it as well for the mmaps) and use it to shorten function
signatures (Arnaldo Carvalho de Melo)
... and lots of other fixes and smaller improvements"
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (91 commits)
perf report: In branch stack mode use address history sorting
perf report: Add --branch-history option
perf callchain: Support handling complete branch stacks as histograms
perf stat: Add support for snapshot counters
perf stat: Add support for per-pkg counters
perf tools: Remove perf_evsel__read interface
perf stat: Use read_counter in read_counter_aggr
perf stat: Make read_counter work over the thread dimension
perf stat: Use perf_evsel__read_cb in read_counter
perf tools: Add snapshot format file parsing
perf tools: Add per-pkg format file parsing
perf evsel: Introduce perf_evsel__read_cb function
perf evsel: Introduce perf_counts_values__scale function
perf evsel: Introduce perf_evsel__compute_deltas function
perf tools: Allow to force redirect pr_debug to stderr.
perf tools: Fix segfault due to invalid kernel dso access
perf callchain: Make get_srcline fall back to sym+offset
perf symbols: Move bfd_demangle stubbing to its only user
perf callchain: Enable printing the srcline in the history
perf tools: Collapse first level callchain entry if it has sibling
...
Diffstat (limited to 'tools/perf/ui/browsers/hists.c')
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index cfb976b3de3a..502daff76ceb 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -227,10 +227,14 @@ static void callchain_node__init_have_children_rb_tree(struct callchain_node *no } } -static void callchain_node__init_have_children(struct callchain_node *node) +static void callchain_node__init_have_children(struct callchain_node *node, + bool has_sibling) { struct callchain_list *chain; + chain = list_entry(node->val.next, struct callchain_list, list); + chain->ms.has_children = has_sibling; + if (!list_empty(&node->val)) { chain = list_entry(node->val.prev, struct callchain_list, list); chain->ms.has_children = !RB_EMPTY_ROOT(&node->rb_root); @@ -241,11 +245,12 @@ static void callchain_node__init_have_children(struct callchain_node *node) static void callchain__init_have_children(struct rb_root *root) { - struct rb_node *nd; + struct rb_node *nd = rb_first(root); + bool has_sibling = nd && rb_next(nd); for (nd = rb_first(root); nd; nd = rb_next(nd)) { struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); - callchain_node__init_have_children(node); + callchain_node__init_have_children(node, has_sibling); } } @@ -463,23 +468,6 @@ out: return key; } -static char *callchain_list__sym_name(struct callchain_list *cl, - char *bf, size_t bfsize, bool show_dso) -{ - int printed; - - if (cl->ms.sym) - printed = scnprintf(bf, bfsize, "%s", cl->ms.sym->name); - else - printed = scnprintf(bf, bfsize, "%#" PRIx64, cl->ip); - - if (show_dso) - scnprintf(bf + printed, bfsize - printed, " %s", - cl->ms.map ? cl->ms.map->dso->short_name : "unknown"); - - return bf; -} - struct callchain_print_arg { /* for hists browser */ off_t row_offset; @@ -559,8 +547,11 @@ static int hist_browser__show_callchain(struct hist_browser *browser, struct rb_node *node; int first_row = row, offset = level * LEVEL_OFFSET_STEP; u64 new_total; + bool need_percent; node = rb_first(root); + need_percent = !!rb_next(node); + while (node) { struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); struct rb_node *next = rb_next(node); @@ -577,7 +568,7 @@ static int hist_browser__show_callchain(struct hist_browser *browser, if (first) first = false; - else if (level > 1) + else if (need_percent) extra_offset = LEVEL_OFFSET_STEP; folded_sign = callchain_list__folded(chain); @@ -590,7 +581,7 @@ static int hist_browser__show_callchain(struct hist_browser *browser, str = callchain_list__sym_name(chain, bf, sizeof(bf), browser->show_dso); - if (was_first && level > 1) { + if (was_first && need_percent) { double percent = cumul * 100.0 / total; if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0) @@ -807,6 +798,13 @@ static int hist_browser__show_entry(struct hist_browser *browser, .is_current_entry = current_entry, }; + if (callchain_param.mode == CHAIN_GRAPH_REL) { + if (symbol_conf.cumulate_callchain) + total = entry->stat_acc->period; + else + total = entry->stat.period; + } + printed += hist_browser__show_callchain(browser, &entry->sorted_chain, 1, row, total, hist_browser__show_callchain_entry, &arg, |