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:	Mon, 31 Aug 2015 18:02:23 -0300
From:	Arnaldo Carvalho de Melo <acme@...hat.com>
To:	Stephane Eranian <eranian@...gle.com>
Cc:	linux-kernel@...r.kernel.org, peterz@...radead.org, mingo@...e.hu,
	ak@...ux.intel.com, jolsa@...hat.com, namhyung@...nel.org,
	kan.liang@...el.com, dsahern@...il.com, adrian.hunter@...el.com
Subject: Re: [PATCH v2 3/4] perf record: add ability to name registers to
 record

Em Mon, Aug 31, 2015 at 06:41:12PM +0200, Stephane Eranian escreveu:
> This patch modifies the -I/--int-regs option to enablepassing the name
> of the registers to sample on interrupt. Registers can be specified
> by their symbolic names. For instance on x86, --intr-regs=ax,si.
> 
> The motivation is to reduce the size of the perf.data file and the
> overhead of sampling by only collecting the registers useful to
> a specific analysis. For instance, for value profiling, sampling
> only the registers used to passed arguements to functions.
> 
> With no parameter, the --intr-regs still records all possible
> registers based on the architecture.

Applied and tested up to this one, waiting for the discussion with Andi
to proceed to the last one.

- Arnaldo
 
> To name registers, it is necessary to use the long form of the
> option, i.e., --intr-regs:
> 
>   $ perf record --intr-regs=si,di,r8,r9 .....
> 
> To record any possible registers:
>   $ perf record -I .....
>   $ perf report --intr-regs ...
> 
> To display the register, one can use perf report -D
> 
> To list the available registers:
>   $ perf record --intr-regs=\?
>   available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10 R11 R12 R13 R14 R15
> 
> Signed-off-by: Stephane Eranian <eranian@...gle.com>
> ---
>  tools/perf/Documentation/perf-record.txt |  6 ++-
>  tools/perf/builtin-record.c              |  7 +++-
>  tools/perf/perf.h                        |  2 +-
>  tools/perf/util/Build                    |  1 +
>  tools/perf/util/evsel.c                  |  2 +-
>  tools/perf/util/parse-regs-options.c     | 71 ++++++++++++++++++++++++++++++++
>  tools/perf/util/parse-regs-options.h     |  5 +++
>  7 files changed, 89 insertions(+), 5 deletions(-)
>  create mode 100644 tools/perf/util/parse-regs-options.c
>  create mode 100644 tools/perf/util/parse-regs-options.h
> 
> diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
> index 347a273..2e9ce77 100644
> --- a/tools/perf/Documentation/perf-record.txt
> +++ b/tools/perf/Documentation/perf-record.txt
> @@ -276,7 +276,11 @@ filter out the startup phase of the program, which is often very different.
>  --intr-regs::
>  Capture machine state (registers) at interrupt, i.e., on counter overflows for
>  each sample. List of captured registers depends on the architecture. This option
> -is off by default.
> +is off by default. It is possible to select the registers to sample using their
> +symbolic names, e.g. on x86, ax, si. To list the available registers use
> +--intr-regs=\?. To name registers, pass a comma separated list such as
> +--intr-regs=ax,bx. The list of register is architecture dependent.
> +
>  
>  --running-time::
>  Record running and enabled time for read events (:S)
> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> index a660022..d3a5d91 100644
> --- a/tools/perf/builtin-record.c
> +++ b/tools/perf/builtin-record.c
> @@ -27,8 +27,10 @@
>  #include "util/cpumap.h"
>  #include "util/thread_map.h"
>  #include "util/data.h"
> +#include "util/perf_regs.h"
>  #include "util/auxtrace.h"
>  #include "util/parse-branch-options.h"
> +#include "util/parse-regs-options.h"
>  
>  #include <unistd.h>
>  #include <sched.h>
> @@ -1080,8 +1082,9 @@ struct option __record_options[] = {
>  		    "sample transaction flags (special events only)"),
>  	OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
>  		    "use per-thread mmaps"),
> -	OPT_BOOLEAN('I', "intr-regs", &record.opts.sample_intr_regs,
> -		    "Sample machine registers on interrupt"),
> +	OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
> +		    "sample selected machine registers on interrupt,"
> +		    " use -I ? to list register names", parse_regs),
>  	OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
>  		    "Record running/enabled time of read (:S) events"),
>  	OPT_CALLBACK('k', "clockid", &record.opts,
> diff --git a/tools/perf/perf.h b/tools/perf/perf.h
> index cccb4cf..90129ac 100644
> --- a/tools/perf/perf.h
> +++ b/tools/perf/perf.h
> @@ -54,7 +54,6 @@ struct record_opts {
>  	bool	     sample_time_set;
>  	bool	     callgraph_set;
>  	bool	     period;
> -	bool	     sample_intr_regs;
>  	bool	     running_time;
>  	bool	     full_auxtrace;
>  	bool	     auxtrace_snapshot_mode;
> @@ -64,6 +63,7 @@ struct record_opts {
>  	unsigned int auxtrace_mmap_pages;
>  	unsigned int user_freq;
>  	u64          branch_stack;
> +	u64	     sample_intr_regs;
>  	u64	     default_interval;
>  	u64	     user_interval;
>  	size_t	     auxtrace_snapshot_size;
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index e912856..7df4937 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -82,6 +82,7 @@ libperf-$(CONFIG_AUXTRACE) += intel-pt-decoder/
>  libperf-$(CONFIG_AUXTRACE) += intel-pt.o
>  libperf-$(CONFIG_AUXTRACE) += intel-bts.o
>  libperf-y += parse-branch-options.o
> +libperf-y += parse-regs-options.o
>  
>  libperf-$(CONFIG_LIBELF) += symbol-elf.o
>  libperf-$(CONFIG_LIBELF) += probe-file.o
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index fd53cc2..b049633 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -787,7 +787,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
>  		perf_evsel__config_callgraph(evsel, opts, &callchain_param);
>  
>  	if (opts->sample_intr_regs) {
> -		attr->sample_regs_intr = PERF_REGS_MASK;
> +		attr->sample_regs_intr = opts->sample_intr_regs;
>  		perf_evsel__set_sample_bit(evsel, REGS_INTR);
>  	}
>  
> diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c
> new file mode 100644
> index 0000000..4f2c1c2
> --- /dev/null
> +++ b/tools/perf/util/parse-regs-options.c
> @@ -0,0 +1,71 @@
> +#include "perf.h"
> +#include "util/util.h"
> +#include "util/debug.h"
> +#include "util/parse-options.h"
> +#include "util/parse-regs-options.h"
> +
> +int
> +parse_regs(const struct option *opt, const char *str, int unset)
> +{
> +	uint64_t *mode = (uint64_t *)opt->value;
> +	const struct sample_reg *r;
> +	char *s, *os = NULL, *p;
> +	int ret = -1;
> +
> +	if (unset)
> +		return 0;
> +
> +	/*
> +	 * cannot set it twice
> +	 */
> +	if (*mode)
> +		return -1;
> +
> +	/* str may be NULL in case no arg is passed to -I */
> +	if (str) {
> +		/* because str is read-only */
> +		s = os = strdup(str);
> +		if (!s)
> +			return -1;
> +
> +		for (;;) {
> +			p = strchr(s, ',');
> +			if (p)
> +				*p = '\0';
> +
> +			if (!strcmp(s, "?")) {
> +				fprintf(stderr, "available registers: ");
> +				for (r = sample_reg_masks; r->name; r++) {
> +					fprintf(stderr, "%s ", r->name);
> +				}
> +				fputc('\n', stderr);
> +				/* just printing available regs */
> +				return -1;
> +			}
> +			for (r = sample_reg_masks; r->name; r++) {
> +				if (!strcasecmp(s, r->name))
> +					break;
> +			}
> +			if (!r->name) {
> +				ui__warning("unknown register %s,"
> +					    " check man page\n", s);
> +				goto error;
> +			}
> +
> +			*mode |= r->mask;
> +
> +			if (!p)
> +				break;
> +
> +			s = p + 1;
> +		}
> +	}
> +	ret = 0;
> +
> +	/* default to all possible regs */
> +	if (*mode == 0)
> +		*mode = PERF_REGS_MASK;
> +error:
> +	free(os);
> +	return ret;
> +}
> diff --git a/tools/perf/util/parse-regs-options.h b/tools/perf/util/parse-regs-options.h
> new file mode 100644
> index 0000000..7d762b1
> --- /dev/null
> +++ b/tools/perf/util/parse-regs-options.h
> @@ -0,0 +1,5 @@
> +#ifndef _PERF_PARSE_REGS_OPTIONS_H
> +#define _PERF_PARSE_REGS_OPTIONS_H 1
> +struct option;
> +int parse_regs(const struct option *opt, const char *str, int unset);
> +#endif /* _PERF_PARSE_REGS_OPTIONS_H */
> -- 
> 1.9.1
--
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