提交 2c5e8c52 编写于 作者: P Peter Zijlstra 提交者: Arnaldo Carvalho de Melo

perf tools: Merge all perf_event_attr print functions

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
Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: NAdrian Hunter <adrian.hunter@intel.com>
Acked-by: NIngo Molnar <mingo@kernel.org>
Acked-by: NJiri Olsa <jolsa@kernel.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20150407091150.644238729@infradead.orgSigned-off-by: NArnaldo Carvalho de Melo <acme@redhat.com>
上级 814c8c38
...@@ -1011,70 +1011,126 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread) ...@@ -1011,70 +1011,126 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread)
return fd; return fd;
} }
#define __PRINT_ATTR(fmt, cast, field) \ struct bit_names {
fprintf(fp, " %-19s "fmt"\n", #field, cast attr->field) int bit;
const char *name;
#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) static void __p_bits(char *buf, size_t size, u64 value, struct bit_names *bits)
#define PRINT_ATTR_X64(field) __PRINT_ATTR("%#"PRIx64, (uint64_t), field) {
bool first_bit = true;
#define PRINT_ATTR2N(name1, field1, name2, field2) \ int i = 0;
fprintf(fp, " %-19s %u %-19s %u\n", \
name1, attr->field1, name2, attr->field2) do {
if (value & bits[i].bit) {
#define PRINT_ATTR2(field1, field2) \ buf += scnprintf(buf, size, "%s%s", first_bit ? "" : "|", bits[i].name);
PRINT_ATTR2N(#field1, field1, #field2, field2) first_bit = false;
}
static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp) } while (bits[++i].name != NULL);
{ }
size_t ret = 0;
static void __p_sample_type(char *buf, size_t size, u64 value)
ret += fprintf(fp, "%.60s\n", graph_dotted_line); {
ret += fprintf(fp, "perf_event_attr:\n"); #define bit_name(n) { PERF_SAMPLE_##n, #n }
struct bit_names bits[] = {
ret += PRINT_ATTR_U32(type); bit_name(IP), bit_name(TID), bit_name(TIME), bit_name(ADDR),
ret += PRINT_ATTR_U32(size); bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU),
ret += PRINT_ATTR_X64(config); bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW),
ret += PRINT_ATTR_U64(sample_period); bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER),
ret += PRINT_ATTR_U64(sample_freq); bit_name(IDENTIFIER), bit_name(REGS_INTR),
ret += PRINT_ATTR_X64(sample_type); { .name = NULL, }
ret += PRINT_ATTR_X64(read_format); };
#undef bit_name
ret += PRINT_ATTR2(disabled, inherit); __p_bits(buf, size, value, bits);
ret += PRINT_ATTR2(pinned, exclusive); }
ret += PRINT_ATTR2(exclude_user, exclude_kernel);
ret += PRINT_ATTR2(exclude_hv, exclude_idle); static void __p_read_format(char *buf, size_t size, u64 value)
ret += PRINT_ATTR2(mmap, comm); {
ret += PRINT_ATTR2(freq, inherit_stat); #define bit_name(n) { PERF_FORMAT_##n, #n }
ret += PRINT_ATTR2(enable_on_exec, task); struct bit_names bits[] = {
ret += PRINT_ATTR2(watermark, precise_ip); bit_name(TOTAL_TIME_ENABLED), bit_name(TOTAL_TIME_RUNNING),
ret += PRINT_ATTR2(mmap_data, sample_id_all); bit_name(ID), bit_name(GROUP),
ret += PRINT_ATTR2(exclude_host, exclude_guest); { .name = NULL, }
ret += PRINT_ATTR2N("excl.callchain_kern", exclude_callchain_kernel, };
"excl.callchain_user", exclude_callchain_user); #undef bit_name
ret += PRINT_ATTR2(mmap2, comm_exec); __p_bits(buf, size, value, bits);
ret += __PRINT_ATTR("%u",,use_clockid); }
#define BUF_SIZE 1024
ret += PRINT_ATTR_U32(wakeup_events);
ret += PRINT_ATTR_U32(wakeup_watermark); #define p_hex(val) snprintf(buf, BUF_SIZE, "%"PRIx64, (uint64_t)(val))
ret += PRINT_ATTR_X32(bp_type); #define p_unsigned(val) snprintf(buf, BUF_SIZE, "%"PRIu64, (uint64_t)(val))
ret += PRINT_ATTR_X64(bp_addr); #define p_signed(val) snprintf(buf, BUF_SIZE, "%"PRId64, (int64_t)(val))
ret += PRINT_ATTR_X64(config1); #define p_sample_type(val) __p_sample_type(buf, BUF_SIZE, val)
ret += PRINT_ATTR_U64(bp_len); #define p_read_format(val) __p_read_format(buf, BUF_SIZE, val)
ret += PRINT_ATTR_X64(config2);
ret += PRINT_ATTR_X64(branch_sample_type); #define PRINT_ATTRn(_n, _f, _p) \
ret += PRINT_ATTR_X64(sample_regs_user); do { \
ret += PRINT_ATTR_U32(sample_stack_user); if (attr->_f) { \
ret += PRINT_ATTR_U32(clockid); _p(attr->_f); \
ret += PRINT_ATTR_X64(sample_regs_intr); ret += attr__fprintf(fp, _n, buf, priv);\
} \
ret += fprintf(fp, "%.60s\n", graph_dotted_line); } while (0)
#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; 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, static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
struct thread_map *threads) struct thread_map *threads)
{ {
...@@ -1114,8 +1170,12 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, ...@@ -1114,8 +1170,12 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
if (perf_missing_features.sample_id_all) if (perf_missing_features.sample_id_all)
evsel->attr.sample_id_all = 0; evsel->attr.sample_id_all = 0;
if (verbose >= 2) if (verbose >= 2) {
perf_event_attr__fprintf(&evsel->attr, stderr); 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++) { for (cpu = 0; cpu < cpus->nr; cpu++) {
...@@ -1996,62 +2056,9 @@ static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...) ...@@ -1996,62 +2056,9 @@ static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
return ret; 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); return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
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, int perf_evsel__fprintf(struct perf_evsel *evsel,
...@@ -2080,52 +2087,13 @@ int perf_evsel__fprintf(struct perf_evsel *evsel, ...@@ -2080,52 +2087,13 @@ int perf_evsel__fprintf(struct perf_evsel *evsel,
printed += fprintf(fp, "%s", perf_evsel__name(evsel)); 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, printed += comma_fprintf(fp, &first, " sample_freq=%" PRIu64,
(u64)evsel->attr.sample_freq); (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: out:
fputc('\n', fp); fputc('\n', fp);
return ++printed; return ++printed;
......
...@@ -360,4 +360,10 @@ static inline bool has_branch_callstack(struct perf_evsel *evsel) ...@@ -360,4 +360,10 @@ static inline bool has_branch_callstack(struct perf_evsel *evsel)
{ {
return evsel->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK; 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 */ #endif /* __PERF_EVSEL_H */
...@@ -1055,6 +1055,12 @@ read_event_desc(struct perf_header *ph, int fd) ...@@ -1055,6 +1055,12 @@ read_event_desc(struct perf_header *ph, int fd)
goto out; 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) static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
{ {
struct perf_evsel *evsel, *events = read_event_desc(ph, fd); struct perf_evsel *evsel, *events = read_event_desc(ph, fd);
...@@ -1069,26 +1075,6 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) ...@@ -1069,26 +1075,6 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
for (evsel = events; evsel->attr.size; evsel++) { for (evsel = events; evsel->attr.size; evsel++) {
fprintf(fp, "# event : name = %s, ", evsel->name); 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) { if (evsel->ids) {
fprintf(fp, ", id = {"); fprintf(fp, ", id = {");
for (j = 0, id = evsel->id; j < evsel->ids; j++, id++) { for (j = 0, id = evsel->id; j < evsel->ids; j++, id++) {
...@@ -1098,9 +1084,8 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) ...@@ -1098,9 +1084,8 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
} }
fprintf(fp, " }"); 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); fputc('\n', fp);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册