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.gr...@gmail.com>
> Signed-off-by: Namhyung Kim <namhy...@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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to