From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753686AbbCaKqv (ORCPT ); Tue, 31 Mar 2015 06:46:51 -0400 Received: from casper.infradead.org ([85.118.1.10]:42674 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751542AbbCaKqr (ORCPT ); Tue, 31 Mar 2015 06:46:47 -0400 Date: Tue, 31 Mar 2015 12:46:48 +0200 From: Peter Zijlstra To: David Ahern Cc: Stephane Eranian , Arnaldo Carvalho de Melo , Thomas Gleixner , Jiri Olsa , Linus Torvalds , LKML , John Stultz , "H. Peter Anvin" , Andrew Morton , Ingo Molnar Subject: [RFC][PATCH] perf tools: unify perf_event_attr printing Message-ID: <20150331104648.GD32047@worktop.ger.corp.intel.com> References: <20150327172059.GK23123@twins.programming.kicks-ass.net> <551594DD.7050705@gmail.com> <20150327201534.GD6291@redhat.com> <20150327215942.GL23123@twins.programming.kicks-ass.net> <20150328075549.GG27490@worktop.programming.kicks-ass.net> <551986BC.3000409@gmail.com> <20150330193318.GF23123@twins.programming.kicks-ass.net> <5519A6D8.9060806@gmail.com> <20150331081955.GQ27490@worktop.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150331081955.GQ27490@worktop.programming.kicks-ass.net> User-Agent: Mutt/1.5.22.1 (2013-10-16) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Mar 31, 2015 at 10:19:55AM +0200, Peter Zijlstra wrote: > Fwiw, having 3 incomplete ways to print perf_event_attr() is > disgusting. How about something like so? Its not identical, but at least its complete and consistent. --- tools/perf/util/print_attr.h | 69 +++++++++++++++ tools/perf/util/print_helper.c | 52 +++++++++++ tools/perf/util/print_helper.h | 7 + tools/perf/util/Build | 1 tools/perf/util/evsel.c | 178 +++++---------------------------------- tools/perf/util/header.c | 34 ++----- 6 files changed, 167 insertions(+), 174 deletions(-) --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -74,6 +74,7 @@ libperf-y += data.o libperf-$(CONFIG_X86) += tsc.o libperf-y += cloexec.o libperf-y += thread-stack.o +libperf-y += print_helper.o libperf-$(CONFIG_LIBELF) += symbol-elf.o libperf-$(CONFIG_LIBELF) += probe-event.o --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -26,6 +26,7 @@ #include "perf_regs.h" #include "debug.h" #include "trace-event.h" +#include "print_helper.h" static struct { bool sample_id_all; @@ -1011,21 +1012,6 @@ 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) - -#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; @@ -1033,42 +1019,15 @@ static size_t perf_event_attr__fprintf(s 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); +#define PRINT_ATTR(_n, _f, _p) \ +do { \ + ret += fprintf(fp, " %-19s ", _n); \ + ret += _p(fp, attr->_f); \ +} while (0) + +#include "util/print_attr.h" + +#undef PRINT_ATTR ret += fprintf(fp, "%.60s\n", graph_dotted_line); @@ -1996,64 +1955,6 @@ static int comma_fprintf(FILE *fp, bool return ret; } -static int __if_fprintf(FILE *fp, bool *first, const char *field, u64 value) -{ - 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); -} - int perf_evsel__fprintf(struct perf_evsel *evsel, struct perf_attr_details *details, FILE *fp) { @@ -2080,51 +1981,24 @@ int perf_evsel__fprintf(struct perf_evse printed += fprintf(fp, "%s", perf_evsel__name(evsel)); - if (details->verbose || 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); + +#define PRINT_ATTR(_n, _f, _p) \ +do { \ + if (evsel->attr._f) { \ + printed += comma_fprintf(fp, &first, " %s: ", _n); \ + printed += _p(fp, evsel->attr._f); \ + } \ +} while (0) + +#include "util/print_attr.h" + +#undef PRINT_ATTR + + } else if (details->freq) { + printed += comma_fprintf(fp, &first, " sample_freq=%" PRIu64, + (u64)evsel->attr.sample_freq); } out: fputc('\n', fp); --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -23,6 +23,7 @@ #include "strbuf.h" #include "build-id.h" #include "data.h" +#include "print_helper.h" static u32 header_argc; static const char **header_argv; @@ -1069,26 +1070,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 +1079,18 @@ static void print_event_desc(struct perf } fprintf(fp, " }"); } - if (evsel->attr.use_clockid) - fprintf(fp, ", clockid = %d", evsel->attr.clockid); +#define PRINT_ATTR(_n, _f, _p) \ +do { \ + if (evsel->attr._f) { \ + fprintf(fp, ", %s =", _n); \ + _p(fp, evsel->attr._f); \ + } \ +} while (0) + +#include "util/print_attr.h" + +#undef PRINT_ATTR fputc('\n', fp); } --- /dev/null +++ b/tools/perf/util/print_attr.h @@ -0,0 +1,69 @@ + +#ifndef PRINT_ATTR +/* + * #define PRINT_ATTR(name, field, print) \ + * do { \ + * fprintf(fp, " %s = ", name); \ + * print(fp, attr->field); \ + * } while (0) + */ +#error "General Error and Major Fault yell at you!" +#endif + +#define p_hex(fp, val) fprintf(fp, "%"PRIx64, (uint64_t)(val)) +#define p_unsigned(fp, val) fprintf(fp, "%"PRIu64, (uint64_t)(val)) +#define p_signed(fp, val) fprintf(fp, "%"PRId64, (int64_t)(val)) +#define p_sample_type(fp, val) sample_type__fprintf(fp, val) +#define p_read_format(fp, val) read_format__fprintf(fp, val) + +#define PRINT_ATTRf(field, print) PRINT_ATTR(#field, field, print) + +PRINT_ATTRf(type, p_unsigned); +PRINT_ATTRf(size, p_unsigned); +PRINT_ATTRf(config, p_hex); +PRINT_ATTR("{ 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_ATTR("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned); +PRINT_ATTRf(bp_type, p_unsigned); +PRINT_ATTR("{ bp_addr, config1 }", bp_addr, p_hex); +PRINT_ATTR("{ 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); + +#undef PRINT_ATTRf + +#undef p_hex +#undef p_unsigned +#undef p_signed +#undef p_sample_type +#undef p_read_format --- /dev/null +++ b/tools/perf/util/print_helper.c @@ -0,0 +1,52 @@ + +#include +#include "util.h" +#include "print_helper.h" + +struct bit_names { + int bit; + const char *name; +}; + +static int bits__fprintf(FILE *fp, u64 value, struct bit_names *bits) +{ + int i = 0, printed = 0; + 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; +} + +int sample_type__fprintf(FILE *fp, 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, value, bits); +} + +int read_format__fprintf(FILE *fp, 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, value, bits); +} + --- /dev/null +++ b/tools/perf/util/print_helper.h @@ -0,0 +1,7 @@ +#ifndef PRINT_HELPER_H +#define PRINT_HELPER_H + +extern int sample_type__fprintf(FILE *fp, u64 value); +extern int read_format__fprintf(FILE *fp, u64 value); + +#endif