Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934254AbbKSN70 (ORCPT ); Thu, 19 Nov 2015 08:59:26 -0500 Received: from mail.kernel.org ([198.145.29.136]:52726 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934055AbbKSN7U (ORCPT ); Thu, 19 Nov 2015 08:59:20 -0500 Date: Thu, 19 Nov 2015 10:59:14 -0300 From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Peter Zijlstra , Jiri Olsa , LKML , Brendan Gregg , David Ahern , Frederic Weisbecker , Andi Kleen , Kan Liang Subject: Re: [PATCH v5 4/9] perf report: Add callchain value option Message-ID: <20151119135914.GB29361@kernel.org> References: <1447047946-1691-1-git-send-email-namhyung@kernel.org> <1447047946-1691-6-git-send-email-namhyung@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447047946-1691-6-git-send-email-namhyung@kernel.org> X-Url: http://acmel.wordpress.com User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 11452 Lines: 323 Em Mon, Nov 09, 2015 at 02:45:41PM +0900, Namhyung Kim escreveu: > Now -g/--call-graph option supports how to display callchain values. > Possible values are 'percent', 'period' and 'count'. The percent is > same as before and it's the default behavior. The period displays the > raw period value rather than the percentage. The count displays the > number of occurrences. > > $ perf report --no-children --stdio -g percent > ... > 39.93% swapper [kernel.vmlinux] [k] intel_idel > | > ---intel_idle > cpuidle_enter_state > cpuidle_enter > call_cpuidle > cpu_startup_entry > | > |--28.63%-- start_secondary > | > --11.30%-- rest_init So, if I try to do: perf report --no-children --stdio -g percent,count It shows just 'count', i.e. the last of these options, is this an intended limitation? I'm applying it as-is, but I can see no reason why we wouldn't want to lift this limitation. - Arnaldo > $ perf report --no-children --show-total-period --stdio -g period > ... > 39.93% 13018705 swapper [kernel.vmlinux] [k] intel_idel > | > ---intel_idle > cpuidle_enter_state > cpuidle_enter > call_cpuidle > cpu_startup_entry > | > |--9334403-- start_secondary > | > --3684302-- rest_init > > $ perf report --no-children --show-nr-samples --stdio -g count > ... > 39.93% 80 swapper [kernel.vmlinux] [k] intel_idel > | > ---intel_idle > cpuidle_enter_state > cpuidle_enter > call_cpuidle > cpu_startup_entry > | > |--57-- start_secondary > | > --23-- rest_init > > Acked-by: Brendan Gregg > Signed-off-by: Namhyung Kim > --- > tools/perf/Documentation/perf-report.txt | 13 ++++--- > tools/perf/builtin-report.c | 4 +-- > tools/perf/ui/stdio/hist.c | 10 +++++- > tools/perf/util/callchain.c | 62 +++++++++++++++++++++++++++----- > tools/perf/util/callchain.h | 10 +++++- > tools/perf/util/util.c | 3 +- > 6 files changed, 84 insertions(+), 18 deletions(-) > > diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt > index f7d81aac9188..dab99ed2b339 100644 > --- a/tools/perf/Documentation/perf-report.txt > +++ b/tools/perf/Documentation/perf-report.txt > @@ -170,11 +170,11 @@ OPTIONS > Dump raw trace in ASCII. > > -g:: > ---call-graph=:: > +--call-graph=:: > Display call chains using type, min percent threshold, print limit, > - call order, sort key and branch. Note that ordering of parameters is not > - fixed so any parement can be given in an arbitraty order. One exception > - is the print_limit which should be preceded by threshold. > + call order, sort key, optional branch and value. Note that ordering of > + parameters is not fixed so any parement can be given in an arbitraty order. > + One exception is the print_limit which should be preceded by threshold. > > print_type can be either: > - flat: single column, linear exposure of call chains. > @@ -205,6 +205,11 @@ OPTIONS > - branch: include last branch information in callgraph when available. > Usually more convenient to use --branch-history for this. > > + value can be: > + - percent: diplay overhead percent (default) > + - period: display event period > + - count: display event count > + > --children:: > Accumulate callchain of children to parent entry so that then can > show up in the output. The output will have a new "Children" column > diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c > index 2853ad2bd435..3dd4bb4ded1a 100644 > --- a/tools/perf/builtin-report.c > +++ b/tools/perf/builtin-report.c > @@ -625,7 +625,7 @@ parse_percent_limit(const struct option *opt, const char *str, > return 0; > } > > -#define CALLCHAIN_DEFAULT_OPT "graph,0.5,caller,function" > +#define CALLCHAIN_DEFAULT_OPT "graph,0.5,caller,function,percent" > > const char report_callchain_help[] = "Display call graph (stack chain/backtrace):\n\n" > CALLCHAIN_REPORT_HELP > @@ -708,7 +708,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) > OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other, > "Only display entries with parent-match"), > OPT_CALLBACK_DEFAULT('g', "call-graph", &report, > - "print_type,threshold[,print_limit],order,sort_key[,branch]", > + "print_type,threshold[,print_limit],order,sort_key[,branch],value", > report_callchain_help, &report_parse_callchain_opt, > callchain_default_opt), > OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, > diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c > index f4de055cab9b..7ebc661be267 100644 > --- a/tools/perf/ui/stdio/hist.c > +++ b/tools/perf/ui/stdio/hist.c > @@ -81,13 +81,14 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root, > int depth_mask, int left_margin) > { > struct rb_node *node, *next; > - struct callchain_node *child; > + struct callchain_node *child = NULL; > struct callchain_list *chain; > int new_depth_mask = depth_mask; > u64 remaining; > size_t ret = 0; > int i; > uint entries_printed = 0; > + int cumul_count = 0; > > remaining = total_samples; > > @@ -99,6 +100,7 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root, > child = rb_entry(node, struct callchain_node, rb_node); > cumul = callchain_cumul_hits(child); > remaining -= cumul; > + cumul_count += callchain_cumul_counts(child); > > /* > * The depth mask manages the output of pipes that show > @@ -148,6 +150,12 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root, > if (!rem_sq_bracket) > return ret; > > + if (callchain_param.value == CCVAL_COUNT && child && child->parent) { > + rem_node.count = child->parent->children_count - cumul_count; > + if (rem_node.count <= 0) > + return ret; > + } > + > new_depth_mask &= ~(1 << (depth - 1)); > ret += ipchain__fprintf_graph(fp, &rem_node, &rem_hits, depth, > new_depth_mask, 0, total_samples, > diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c > index 60754de700d4..f3f1b95b808e 100644 > --- a/tools/perf/util/callchain.c > +++ b/tools/perf/util/callchain.c > @@ -83,6 +83,23 @@ static int parse_callchain_sort_key(const char *value) > return -1; > } > > +static int parse_callchain_value(const char *value) > +{ > + if (!strncmp(value, "percent", strlen(value))) { > + callchain_param.value = CCVAL_PERCENT; > + return 0; > + } > + if (!strncmp(value, "period", strlen(value))) { > + callchain_param.value = CCVAL_PERIOD; > + return 0; > + } > + if (!strncmp(value, "count", strlen(value))) { > + callchain_param.value = CCVAL_COUNT; > + return 0; > + } > + return -1; > +} > + > static int > __parse_callchain_report_opt(const char *arg, bool allow_record_opt) > { > @@ -106,7 +123,8 @@ __parse_callchain_report_opt(const char *arg, bool allow_record_opt) > > if (!parse_callchain_mode(tok) || > !parse_callchain_order(tok) || > - !parse_callchain_sort_key(tok)) { > + !parse_callchain_sort_key(tok) || > + !parse_callchain_value(tok)) { > /* parsing ok - move on to the next */ > try_stack_size = false; > goto next; > @@ -820,13 +838,27 @@ char *callchain_node__sprintf_value(struct callchain_node *node, > { > double percent = 0.0; > u64 period = callchain_cumul_hits(node); > + unsigned count = callchain_cumul_counts(node); > > - if (callchain_param.mode == CHAIN_FOLDED) > + if (callchain_param.mode == CHAIN_FOLDED) { > period = node->hit; > - if (total) > - percent = period * 100.0 / total; > + count = node->count; > + } > > - scnprintf(bf, bfsize, "%.2f%%", percent); > + switch (callchain_param.value) { > + case CCVAL_PERIOD: > + scnprintf(bf, bfsize, "%"PRIu64, period); > + break; > + case CCVAL_COUNT: > + scnprintf(bf, bfsize, "%u", count); > + break; > + case CCVAL_PERCENT: > + default: > + if (total) > + percent = period * 100.0 / total; > + scnprintf(bf, bfsize, "%.2f%%", percent); > + break; > + } > return bf; > } > > @@ -835,13 +867,25 @@ int callchain_node__fprintf_value(struct callchain_node *node, > { > double percent = 0.0; > u64 period = callchain_cumul_hits(node); > + unsigned count = callchain_cumul_counts(node); > > - if (callchain_param.mode == CHAIN_FOLDED) > + if (callchain_param.mode == CHAIN_FOLDED) { > period = node->hit; > - if (total) > - percent = period * 100.0 / total; > + count = node->count; > + } > > - return percent_color_fprintf(fp, "%.2f%%", percent); > + switch (callchain_param.value) { > + case CCVAL_PERIOD: > + return fprintf(fp, "%"PRIu64, period); > + case CCVAL_COUNT: > + return fprintf(fp, "%u", count); > + case CCVAL_PERCENT: > + default: > + if (total) > + percent = period * 100.0 / total; > + return percent_color_fprintf(fp, "%.2f%%", percent); > + } > + return 0; > } > > static void free_callchain_node(struct callchain_node *node) > diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h > index 0e6cc83f1a46..b14d760fc4e3 100644 > --- a/tools/perf/util/callchain.h > +++ b/tools/perf/util/callchain.h > @@ -29,7 +29,8 @@ > HELP_PAD "print_limit:\tmaximum number of call graph entry ()\n" \ > HELP_PAD "order:\t\tcall graph order (caller|callee)\n" \ > HELP_PAD "sort_key:\tcall graph sort key (function|address)\n" \ > - HELP_PAD "branch:\t\tinclude last branch info to call graph (branch)\n" > + HELP_PAD "branch:\t\tinclude last branch info to call graph (branch)\n" \ > + HELP_PAD "value:\t\tcall graph value (percent|period|count)\n" > > enum perf_call_graph_mode { > CALLCHAIN_NONE, > @@ -81,6 +82,12 @@ enum chain_key { > CCKEY_ADDRESS > }; > > +enum chain_value { > + CCVAL_PERCENT, > + CCVAL_PERIOD, > + CCVAL_COUNT, > +}; > + > struct callchain_param { > bool enabled; > enum perf_call_graph_mode record_mode; > @@ -93,6 +100,7 @@ struct callchain_param { > bool order_set; > enum chain_key key; > bool branch_callstack; > + enum chain_value value; > }; > > extern struct callchain_param callchain_param; > diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c > index 47b1e36c7ea0..75759aebc7b8 100644 > --- a/tools/perf/util/util.c > +++ b/tools/perf/util/util.c > @@ -21,7 +21,8 @@ struct callchain_param callchain_param = { > .mode = CHAIN_GRAPH_ABS, > .min_percent = 0.5, > .order = ORDER_CALLEE, > - .key = CCKEY_FUNCTION > + .key = CCKEY_FUNCTION, > + .value = CCVAL_PERCENT, > }; > > /* > -- > 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/