lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 19 Nov 2015 10:59:14 -0300
From:	Arnaldo Carvalho de Melo <acme@...nel.org>
To:	Namhyung Kim <namhyung@...nel.org>
Cc:	Ingo Molnar <mingo@...nel.org>,
	Peter Zijlstra <a.p.zijlstra@...llo.nl>,
	Jiri Olsa <jolsa@...hat.com>,
	LKML <linux-kernel@...r.kernel.org>,
	Brendan Gregg <brendan.d.gregg@...il.com>,
	David Ahern <dsahern@...il.com>,
	Frederic Weisbecker <fweisbec@...il.com>,
	Andi Kleen <andi@...stfloor.org>,
	Kan Liang <kan.liang@...el.com>
Subject: Re: [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@...il.com>
> Signed-off-by: Namhyung Kim <namhyung@...nel.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 majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ