lkml.org 
[lkml]   [2015]   [Nov]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v5 4/9] perf report: Add callchain value option
    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 <brendan.d.gregg@gmail.com>
    > Signed-off-by: Namhyung Kim <namhyung@kernel.org>
    > ---
    > 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=<print_type,threshold[,print_limit],order,sort_key,branch>::
    > +--call-graph=<print_type,threshold[,print_limit],order,sort_key[,branch],value>::
    > 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 (<number>)\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


    \
     
     \ /
      Last update: 2015-11-19 15:21    [W:3.762 / U:0.264 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site