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]
Message-ID: <551D3C0A.7050403@intel.com>
Date:	Thu, 02 Apr 2015 15:54:34 +0300
From:	Adrian Hunter <adrian.hunter@...el.com>
To:	Peter Zijlstra <peterz@...radead.org>
CC:	Jiri Olsa <jolsa@...hat.com>, David Ahern <dsahern@...il.com>,
	Stephane Eranian <eranian@...gle.com>,
	Arnaldo Carvalho de Melo <acme@...hat.com>,
	Thomas Gleixner <tglx@...utronix.de>,
	Linus Torvalds <torvalds@...ux-foundation.org>,
	LKML <linux-kernel@...r.kernel.org>,
	John Stultz <john.stultz@...aro.org>,
	"H. Peter Anvin" <hpa@...or.com>,
	Andrew Morton <akpm@...ux-foundation.org>,
	Ingo Molnar <mingo@...nel.org>
Subject: Re: [RFC][PATCH] perf tools: unify perf_event_attr printing

On 02/04/15 14:59, Peter Zijlstra wrote:
> On Thu, Apr 02, 2015 at 12:01:53PM +0300, Adrian Hunter wrote:
>> But personally I think the "include" approach is too ugly. I would just
>> add a function instead. Something like:
> 
> You've not stared at the kernel tracepoint code long enough ;-)

I will try some day when I feel too sane :-)

> 
> Something like so then?

Looks fine. Didn't test it, but

Acked-by: Adrian Hunter <adrian.hunter@...el.com>

> 
> ---
> Subject: perf, tools: Merge all perf_event_attr print functions
> From: Peter Zijlstra <peterz@...radead.org>
> Date: Thu Apr 2 11:49:23 CEST 2015
> 
> Currently there's 3 (that I found) different and incomplete
> implementations of printing perf_event_attr.
> 
> This is quite silly. Merge the lot.
> 
> While this patch does not retain the exact form all printing that I
> found is debug output and thus it should not be critical.
> 
> Also, I cannot find a single print_event_desc() caller.
> 
> Pre:
> 
> $ perf record -vv -e cycles -- sleep 1
> ------------------------------------------------------------
> perf_event_attr:
>   type                0
>   size                104
>   config              0
>   sample_period       4000
>   sample_freq         4000
>   sample_type         0x107
>   read_format         0
>   disabled            1    inherit             1
>   pinned              0    exclusive           0
>   exclude_user        0    exclude_kernel      0
>   exclude_hv          0    exclude_idle        0
>   mmap                1    comm                1
>   mmap2               1    comm_exec           1
>   freq                1    inherit_stat        0
>   enable_on_exec      1    task                1
>   watermark           0    precise_ip          0
>   mmap_data           0    sample_id_all       1
>   exclude_host        0    exclude_guest       1
>   excl.callchain_kern 0    excl.callchain_user 0
>   wakeup_events       0
>   wakeup_watermark    0
>   bp_type             0
>   bp_addr             0
>   config1             0
>   bp_len              0
>   config2             0
>   branch_sample_type  0
>   sample_regs_user    0
>   sample_stack_user   0
>   sample_regs_intr    0
> ------------------------------------------------------------
> 
> $ perf evlist  -vv
> cycles: sample_freq=4000, size: 104, sample_type: IP|TID|TIME|PERIOD,
> disabled: 1, inherit: 1, mmap: 1, mmap2: 1, comm: 1, comm_exec: 1,
> freq: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest:
> 1
> 
> Post:
> 
> $ ./perf record -vv -e cycles -- sleep 1 
> ------------------------------------------------------------
> perf_event_attr:
>   size                             112
>   { sample_period, sample_freq }   4000
>   sample_type                      IP|TID|TIME|PERIOD
>   disabled                         1
>   inherit                          1
>   mmap                             1
>   comm                             1
>   freq                             1
>   enable_on_exec                   1
>   task                             1
>   sample_id_all                    1
>   exclude_guest                    1
>   mmap2                            1
>   comm_exec                        1
> ------------------------------------------------------------
> 
> $ ./perf evlist  -vv
> cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type:
> IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq:
> 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1,
> mmap2: 1, comm_exec: 1
> 
> Cc: acme@...hat.com
> Cc: jolsa@...hat.com
> Signed-off-by: Peter Zijlstra (Intel) <peterz@...radead.org>
> ---
>  tools/perf/util/evsel.c  |  284 ++++++++++++++++++++---------------------------
>  tools/perf/util/evsel.h  |    6 
>  tools/perf/util/header.c |   29 +---
>  3 files changed, 139 insertions(+), 180 deletions(-)
> 
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -1011,70 +1011,126 @@ static int get_group_fd(struct perf_evse
>  	return fd;
>  }
>  
> -#define __PRINT_ATTR(fmt, cast, field)  \
> -	fprintf(fp, "  %-19s "fmt"\n", #field, cast attr->field)
> +struct bit_names {
> +	int bit;
> +	const char *name;
> +};
> +
> +static void __p_bits(char *buf, size_t size, u64 value, struct bit_names *bits)
> +{
> +	bool first_bit = true;
> +	int i = 0;
> +
> +	do {
> +		if (value & bits[i].bit) {
> +			buf += scnprintf(buf, size, "%s%s", first_bit ? "" : "|", bits[i].name);
> +			first_bit = false;
> +		}
> +	} while (bits[++i].name != NULL);
> +}
> +
> +static void __p_sample_type(char *buf, size_t size, u64 value)
> +{
> +#define bit_name(n) { PERF_SAMPLE_##n, #n }
> +	struct bit_names bits[] = {
> +		bit_name(IP), bit_name(TID), bit_name(TIME), bit_name(ADDR),
> +		bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU),
> +		bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW),
> +		bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER),
> +		bit_name(IDENTIFIER), bit_name(REGS_INTR),
> +		{ .name = NULL, }
> +	};
> +#undef bit_name
> +	__p_bits(buf, size, value, bits);
> +}
>  
> -#define PRINT_ATTR_U32(field)  __PRINT_ATTR("%u" , , field)
> -#define PRINT_ATTR_X32(field)  __PRINT_ATTR("%#x", , field)
> -#define PRINT_ATTR_U64(field)  __PRINT_ATTR("%" PRIu64, (uint64_t), field)
> -#define PRINT_ATTR_X64(field)  __PRINT_ATTR("%#"PRIx64, (uint64_t), field)
> -
> -#define PRINT_ATTR2N(name1, field1, name2, field2)	\
> -	fprintf(fp, "  %-19s %u    %-19s %u\n",		\
> -	name1, attr->field1, name2, attr->field2)
> -
> -#define PRINT_ATTR2(field1, field2) \
> -	PRINT_ATTR2N(#field1, field1, #field2, field2)
> -
> -static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
> -{
> -	size_t ret = 0;
> -
> -	ret += fprintf(fp, "%.60s\n", graph_dotted_line);
> -	ret += fprintf(fp, "perf_event_attr:\n");
> -
> -	ret += PRINT_ATTR_U32(type);
> -	ret += PRINT_ATTR_U32(size);
> -	ret += PRINT_ATTR_X64(config);
> -	ret += PRINT_ATTR_U64(sample_period);
> -	ret += PRINT_ATTR_U64(sample_freq);
> -	ret += PRINT_ATTR_X64(sample_type);
> -	ret += PRINT_ATTR_X64(read_format);
> -
> -	ret += PRINT_ATTR2(disabled, inherit);
> -	ret += PRINT_ATTR2(pinned, exclusive);
> -	ret += PRINT_ATTR2(exclude_user, exclude_kernel);
> -	ret += PRINT_ATTR2(exclude_hv, exclude_idle);
> -	ret += PRINT_ATTR2(mmap, comm);
> -	ret += PRINT_ATTR2(freq, inherit_stat);
> -	ret += PRINT_ATTR2(enable_on_exec, task);
> -	ret += PRINT_ATTR2(watermark, precise_ip);
> -	ret += PRINT_ATTR2(mmap_data, sample_id_all);
> -	ret += PRINT_ATTR2(exclude_host, exclude_guest);
> -	ret += PRINT_ATTR2N("excl.callchain_kern", exclude_callchain_kernel,
> -			    "excl.callchain_user", exclude_callchain_user);
> -	ret += PRINT_ATTR2(mmap2, comm_exec);
> -	ret += __PRINT_ATTR("%u",,use_clockid);
> -
> -
> -	ret += PRINT_ATTR_U32(wakeup_events);
> -	ret += PRINT_ATTR_U32(wakeup_watermark);
> -	ret += PRINT_ATTR_X32(bp_type);
> -	ret += PRINT_ATTR_X64(bp_addr);
> -	ret += PRINT_ATTR_X64(config1);
> -	ret += PRINT_ATTR_U64(bp_len);
> -	ret += PRINT_ATTR_X64(config2);
> -	ret += PRINT_ATTR_X64(branch_sample_type);
> -	ret += PRINT_ATTR_X64(sample_regs_user);
> -	ret += PRINT_ATTR_U32(sample_stack_user);
> -	ret += PRINT_ATTR_U32(clockid);
> -	ret += PRINT_ATTR_X64(sample_regs_intr);
> +static void __p_read_format(char *buf, size_t size, u64 value)
> +{
> +#define bit_name(n) { PERF_FORMAT_##n, #n }
> +	struct bit_names bits[] = {
> +		bit_name(TOTAL_TIME_ENABLED), bit_name(TOTAL_TIME_RUNNING),
> +		bit_name(ID), bit_name(GROUP),
> +		{ .name = NULL, }
> +	};
> +#undef bit_name
> +	__p_bits(buf, size, value, bits);
> +}
> +
> +#define BUF_SIZE		1024
> +
> +#define p_hex(val)		snprintf(buf, BUF_SIZE, "%"PRIx64, (uint64_t)(val))
> +#define p_unsigned(val)		snprintf(buf, BUF_SIZE, "%"PRIu64, (uint64_t)(val))
> +#define p_signed(val)		snprintf(buf, BUF_SIZE, "%"PRId64, (int64_t)(val))
> +#define p_sample_type(val)	__p_sample_type(buf, BUF_SIZE, val)
> +#define p_read_format(val)	__p_read_format(buf, BUF_SIZE, val)
> +
> +#define PRINT_ATTRn(_n, _f, _p)				\
> +do {							\
> +	if (attr->_f) {					\
> +		_p(attr->_f);				\
> +		ret += attr__fprintf(fp, _n, buf, priv);\
> +	}						\
> +} while (0)
>  
> -	ret += fprintf(fp, "%.60s\n", graph_dotted_line);
> +#define PRINT_ATTRf(_f, _p)	PRINT_ATTRn(#_f, _f, _p)
> +
> +int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
> +			     attr__fprintf_f attr__fprintf, void *priv)
> +{
> +	char buf[BUF_SIZE];
> +	int ret = 0;
> +
> +	PRINT_ATTRf(type, p_unsigned);
> +	PRINT_ATTRf(size, p_unsigned);
> +	PRINT_ATTRf(config, p_hex);
> +	PRINT_ATTRn("{ sample_period, sample_freq }", sample_period, p_unsigned);
> +	PRINT_ATTRf(sample_type, p_sample_type);
> +	PRINT_ATTRf(read_format, p_read_format);
> +
> +	PRINT_ATTRf(disabled, p_unsigned);
> +	PRINT_ATTRf(inherit, p_unsigned);
> +	PRINT_ATTRf(pinned, p_unsigned);
> +	PRINT_ATTRf(exclusive, p_unsigned);
> +	PRINT_ATTRf(exclude_user, p_unsigned);
> +	PRINT_ATTRf(exclude_kernel, p_unsigned);
> +	PRINT_ATTRf(exclude_hv, p_unsigned);
> +	PRINT_ATTRf(exclude_idle, p_unsigned);
> +	PRINT_ATTRf(mmap, p_unsigned);
> +	PRINT_ATTRf(comm, p_unsigned);
> +	PRINT_ATTRf(freq, p_unsigned);
> +	PRINT_ATTRf(inherit_stat, p_unsigned);
> +	PRINT_ATTRf(enable_on_exec, p_unsigned);
> +	PRINT_ATTRf(task, p_unsigned);
> +	PRINT_ATTRf(watermark, p_unsigned);
> +	PRINT_ATTRf(precise_ip, p_unsigned);
> +	PRINT_ATTRf(mmap_data, p_unsigned);
> +	PRINT_ATTRf(sample_id_all, p_unsigned);
> +	PRINT_ATTRf(exclude_host, p_unsigned);
> +	PRINT_ATTRf(exclude_guest, p_unsigned);
> +	PRINT_ATTRf(exclude_callchain_kernel, p_unsigned);
> +	PRINT_ATTRf(exclude_callchain_user, p_unsigned);
> +	PRINT_ATTRf(mmap2, p_unsigned);
> +	PRINT_ATTRf(comm_exec, p_unsigned);
> +	PRINT_ATTRf(use_clockid, p_unsigned);
> +
> +	PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned);
> +	PRINT_ATTRf(bp_type, p_unsigned);
> +	PRINT_ATTRn("{ bp_addr, config1 }", bp_addr, p_hex);
> +	PRINT_ATTRn("{ bp_len, config2 }", bp_len, p_hex);
> +	PRINT_ATTRf(sample_regs_user, p_hex);
> +	PRINT_ATTRf(sample_stack_user, p_unsigned);
> +	PRINT_ATTRf(clockid, p_signed);
> +	PRINT_ATTRf(sample_regs_intr, p_hex);
>  
>  	return ret;
>  }
>  
> +static int __open_attr__fprintf(FILE *fp, const char *name, const char *val,
> +				void *priv __attribute__((unused)))
> +{
> +	return fprintf(fp, "  %-32s %s\n", name, val);
> +}
> +
>  static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
>  			      struct thread_map *threads)
>  {
> @@ -1114,8 +1170,12 @@ static int __perf_evsel__open(struct per
>  	if (perf_missing_features.sample_id_all)
>  		evsel->attr.sample_id_all = 0;
>  
> -	if (verbose >= 2)
> -		perf_event_attr__fprintf(&evsel->attr, stderr);
> +	if (verbose >= 2) {
> +		fprintf(stderr, "%.60s\n", graph_dotted_line);
> +		fprintf(stderr, "perf_event_attr:\n");
> +		perf_event_attr__fprintf(stderr, &evsel->attr, __open_attr__fprintf, NULL);
> +		fprintf(stderr, "%.60s\n", graph_dotted_line);
> +	}
>  
>  	for (cpu = 0; cpu < cpus->nr; cpu++) {
>  
> @@ -1996,62 +2056,9 @@ static int comma_fprintf(FILE *fp, bool
>  	return ret;
>  }
>  
> -static int __if_fprintf(FILE *fp, bool *first, const char *field, u64 value)
> +static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
>  {
> -	if (value == 0)
> -		return 0;
> -
> -	return comma_fprintf(fp, first, " %s: %" PRIu64, field, value);
> -}
> -
> -#define if_print(field) printed += __if_fprintf(fp, &first, #field, evsel->attr.field)
> -
> -struct bit_names {
> -	int bit;
> -	const char *name;
> -};
> -
> -static int bits__fprintf(FILE *fp, const char *field, u64 value,
> -			 struct bit_names *bits, bool *first)
> -{
> -	int i = 0, printed = comma_fprintf(fp, first, " %s: ", field);
> -	bool first_bit = true;
> -
> -	do {
> -		if (value & bits[i].bit) {
> -			printed += fprintf(fp, "%s%s", first_bit ? "" : "|", bits[i].name);
> -			first_bit = false;
> -		}
> -	} while (bits[++i].name != NULL);
> -
> -	return printed;
> -}
> -
> -static int sample_type__fprintf(FILE *fp, bool *first, u64 value)
> -{
> -#define bit_name(n) { PERF_SAMPLE_##n, #n }
> -	struct bit_names bits[] = {
> -		bit_name(IP), bit_name(TID), bit_name(TIME), bit_name(ADDR),
> -		bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU),
> -		bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW),
> -		bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER),
> -		bit_name(IDENTIFIER), bit_name(REGS_INTR),
> -		{ .name = NULL, }
> -	};
> -#undef bit_name
> -	return bits__fprintf(fp, "sample_type", value, bits, first);
> -}
> -
> -static int read_format__fprintf(FILE *fp, bool *first, u64 value)
> -{
> -#define bit_name(n) { PERF_FORMAT_##n, #n }
> -	struct bit_names bits[] = {
> -		bit_name(TOTAL_TIME_ENABLED), bit_name(TOTAL_TIME_RUNNING),
> -		bit_name(ID), bit_name(GROUP),
> -		{ .name = NULL, }
> -	};
> -#undef bit_name
> -	return bits__fprintf(fp, "read_format", value, bits, first);
> +	return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
>  }
>  
>  int perf_evsel__fprintf(struct perf_evsel *evsel,
> @@ -2080,52 +2087,13 @@ int perf_evsel__fprintf(struct perf_evse
>  
>  	printed += fprintf(fp, "%s", perf_evsel__name(evsel));
>  
> -	if (details->verbose || details->freq) {
> +	if (details->verbose) {
> +		printed += perf_event_attr__fprintf(fp, &evsel->attr,
> +						    __print_attr__fprintf, &first);
> +	} else if (details->freq) {
>  		printed += comma_fprintf(fp, &first, " sample_freq=%" PRIu64,
>  					 (u64)evsel->attr.sample_freq);
>  	}
> -
> -	if (details->verbose) {
> -		if_print(type);
> -		if_print(config);
> -		if_print(config1);
> -		if_print(config2);
> -		if_print(size);
> -		printed += sample_type__fprintf(fp, &first, evsel->attr.sample_type);
> -		if (evsel->attr.read_format)
> -			printed += read_format__fprintf(fp, &first, evsel->attr.read_format);
> -		if_print(disabled);
> -		if_print(inherit);
> -		if_print(pinned);
> -		if_print(exclusive);
> -		if_print(exclude_user);
> -		if_print(exclude_kernel);
> -		if_print(exclude_hv);
> -		if_print(exclude_idle);
> -		if_print(mmap);
> -		if_print(comm);
> -		if_print(freq);
> -		if_print(inherit_stat);
> -		if_print(enable_on_exec);
> -		if_print(task);
> -		if_print(watermark);
> -		if_print(precise_ip);
> -		if_print(mmap_data);
> -		if_print(sample_id_all);
> -		if_print(exclude_host);
> -		if_print(exclude_guest);
> -		if_print(mmap2);
> -		if_print(comm_exec);
> -		if_print(use_clockid);
> -		if_print(__reserved_1);
> -		if_print(wakeup_events);
> -		if_print(bp_type);
> -		if_print(branch_sample_type);
> -		if_print(sample_regs_user);
> -		if_print(sample_stack_user);
> -		if_print(clockid);
> -		if_print(sample_regs_intr);
> -	}
>  out:
>  	fputc('\n', fp);
>  	return ++printed;
> --- a/tools/perf/util/evsel.h
> +++ b/tools/perf/util/evsel.h
> @@ -359,4 +359,10 @@ static inline bool has_branch_callstack(
>  {
>  	return evsel->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK;
>  }
> +
> +typedef int (*attr__fprintf_f)(FILE *, const char *, const char *, void *);
> +
> +int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
> +			     attr__fprintf_f attr__fprintf, void *priv);
> +
>  #endif /* __PERF_EVSEL_H */
> --- a/tools/perf/util/header.c
> +++ b/tools/perf/util/header.c
> @@ -1055,6 +1055,12 @@ read_event_desc(struct perf_header *ph,
>  	goto out;
>  }
>  
> +static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val,
> +				void *priv __attribute__((unused)))
> +{
> +	return fprintf(fp, ", %s = %s", name, val);
> +}
> +
>  static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
>  {
>  	struct perf_evsel *evsel, *events = read_event_desc(ph, fd);
> @@ -1069,26 +1075,6 @@ static void print_event_desc(struct perf
>  	for (evsel = events; evsel->attr.size; evsel++) {
>  		fprintf(fp, "# event : name = %s, ", evsel->name);
>  
> -		fprintf(fp, "type = %d, config = 0x%"PRIx64
> -			    ", config1 = 0x%"PRIx64", config2 = 0x%"PRIx64,
> -				evsel->attr.type,
> -				(u64)evsel->attr.config,
> -				(u64)evsel->attr.config1,
> -				(u64)evsel->attr.config2);
> -
> -		fprintf(fp, ", excl_usr = %d, excl_kern = %d",
> -				evsel->attr.exclude_user,
> -				evsel->attr.exclude_kernel);
> -
> -		fprintf(fp, ", excl_host = %d, excl_guest = %d",
> -				evsel->attr.exclude_host,
> -				evsel->attr.exclude_guest);
> -
> -		fprintf(fp, ", precise_ip = %d", evsel->attr.precise_ip);
> -
> -		fprintf(fp, ", attr_mmap2 = %d", evsel->attr.mmap2);
> -		fprintf(fp, ", attr_mmap  = %d", evsel->attr.mmap);
> -		fprintf(fp, ", attr_mmap_data = %d", evsel->attr.mmap_data);
>  		if (evsel->ids) {
>  			fprintf(fp, ", id = {");
>  			for (j = 0, id = evsel->id; j < evsel->ids; j++, id++) {
> @@ -1098,9 +1084,8 @@ static void print_event_desc(struct perf
>  			}
>  			fprintf(fp, " }");
>  		}
> -		if (evsel->attr.use_clockid)
> -			fprintf(fp, ", clockid = %d", evsel->attr.clockid);
>  
> +		perf_event_attr__fprintf(fp, &evsel->attr, __desc_attr__fprintf, NULL);
>  
>  		fputc('\n', fp);
>  	}
> 
> 

--
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