perf tools: clock_id support and perf_event_attr printing
Peter Zijlstra
maintainercover perf tools: clock_id support and perf_event_attr printing
Hi Arnaldo,
As per your request, here's the latest version of the two patches.
I retained Jiri's and Ingo's ACK on the perf_event_attr printing patch even though I rewrote it since they acked it; if they feel I wrongly did so please holler.
Thanks!
Peter Zijlstra
maintainerPATCH 1/2 perf, record: Add clockid parameter
Teach perf-record about the new perf_event_attr::{use_clockid, clockid} fields. Add a simple parameter to set the clock (if any) to be used for the events to be recorded into the data file.
Since we store the entire perf_event_attr in the EVENT_DESC section we also already store the used clockid in the data file.
--- tools/perf/Documentation/perf-record.txt | 7 ++ tools/perf/builtin-record.c | 78 +++++++++++++++++++++++++++++++ tools/perf/perf.h | 1 tools/perf/util/evsel.c | 59 +++++++++++++++++++++-- tools/perf/util/header.c | 3 + 5 files changed, 144 insertions(+), 4 deletions(-)
tools/perf/Documentation/perf-record.txt +7 -0
@@ -250,6 +250,13 @@ is off by default. --running-time:: Record running and enabled time for read events (:S) +-k:: +--clockid:: +Sets the clock id to use for the various time fields in the perf_event_type +records. See clock_gettime(). In particular CLOCK_MONOTONIC and +CLOCK_MONOTONIC_RAW are supported, some events might also allow +CLOCK_BOOTTIME, CLOCK_REALTIME and CLOCK_TAI. + SEE ALSO -------- linkperf:perf-stat[1], linkperf:perf-list[1]
tools/perf/builtin-record.c +78 -0
96 lines not on this page · raw message
tools/perf/perf.h +1 -0
@@ -62,6 +62,7 @@ struct record_opts {u64 user_interval;bool sample_transaction;unsigned initial_delay; +clockid_t clockid; };struct option ;
tools/perf/util/evsel.c +55 -4
132 lines not on this page · raw message
tools/perf/util/header.c +3 -0
@@ -1098,6 +1098,9 @@ static void print_event_desc(struct perf }fprintf (fp," }" ); } +if (evsel->attr.use_clockid) +fprintf (fp,", clockid = %d" , evsel->attr.clockid); +fputc ('\n' , fp); }
Peter Zijlstra
maintainerRe: [PATCH 1/2] perf, record: Add clockid parameter
Review static struct record record = { · line 817
Quoted 6 lines · Peter Zijlstra
(quoted diff) +1
-0@@ -739,6 +813,7 @@ static struct record record = { .uses_mmap = true, .default_per_cpu = true, }, + .clockid = -1, },
As spotted by dahern this is not working well for all other record_opts instances, fix that by adding a use_clockid field just like perf_event_attr has.
perf test does (now) not appear to fail more with this patch than without.
---
Subject: perf, record: Add clockid parameter
From: Peter Zijlstra <[email protected]>
Date: Tue, 31 Mar 2015 00:19:31 +0200
Teach perf-record about the new perf_event_attr::{use_clockid, clockid} fields. Add a simple parameter to set the clock (if any) to be used for the events to be recorded into the data file.
Since we store the entire perf_event_attr in the EVENT_DESC section we also already store the used clockid in the data file.
--- tools/perf/Documentation/perf-record.txt | 7 ++ tools/perf/builtin-record.c | 80 +++++++++++++++++++++++++++++++ tools/perf/perf.h | 2 tools/perf/util/evsel.c | 59 +++++++++++++++++++++- tools/perf/util/header.c | 3 + 5 files changed, 147 insertions(+), 4 deletions(-)
tools/perf/Documentation/perf-record.txt +7 -0
@@ -250,6 +250,13 @@ is off by default. --running-time:: Record running and enabled time for read events (:S) +-k:: +--clockid:: +Sets the clock id to use for the various time fields in the perf_event_type +records. See clock_gettime(). In particular CLOCK_MONOTONIC and +CLOCK_MONOTONIC_RAW are supported, some events might also allow +CLOCK_BOOTTIME, CLOCK_REALTIME and CLOCK_TAI. + SEE ALSO -------- linkperf:perf-stat[1], linkperf:perf-list[1]
tools/perf/builtin-record.c +80 -0
92 lines not on this page · raw message
tools/perf/perf.h +2 -0
@@ -62,6 +62,8 @@ struct record_opts {u64 user_interval;bool sample_transaction;unsigned initial_delay; +bool use_clockid; +clockid_t clockid; };struct option ;
tools/perf/util/evsel.c +55 -4
132 lines not on this page · raw message
tools/perf/util/header.c +3 -0
@@ -1098,6 +1098,9 @@ static void print_event_desc(struct perf }fprintf (fp," }" ); } +if (evsel->attr.use_clockid) +fprintf (fp,", clockid = %d" , evsel->attr.clockid); +fputc ('\n' , fp); }
Re: [PATCH 1/2] perf, record: Add clockid parameter
Quoted 11 lines · Peter Zijlstra
Review static struct record record = { · line 817
Quoted 6 lines · Peter Zijlstra
(quoted diff) +1
-0@@ -739,6 +813,7 @@ static struct record record = { .uses_mmap = true, .default_per_cpu = true, }, + .clockid = -1, },As spotted by dahern this is not working well for all other
record_optsinstances, fix that by adding ause_clockidfield just likeperf_event_attrhas.
hum, havent realized that.. I saw Arnaldo already included this one in pull req., anyway FWIW it looks ok ;-)
jirka
Peter Zijlstra
maintainerRe: [PATCH 1/2] perf, record: Add clockid parameter
Quoted 13 lines · Jiri Olsa
Quoted 11 lines · Peter Zijlstra
Review static struct record record = { · line 817
Quoted 6 lines · Peter Zijlstra
(quoted diff) +1
-0@@ -739,6 +813,7 @@ static struct record record = { .uses_mmap = true, .default_per_cpu = true, }, + .clockid = -1, },As spotted by dahern this is not working well for all other
record_optsinstances, fix that by adding ause_clockidfield just likeperf_event_attrhas.
Quoted 2 lines
hum, havent realized that.. I saw Arnaldo already included this one in pull req., anyway FWIW it looks ok ;-)
Yeah, I was slightly surprised to find out record_opts were used outside of builtin-record.c, maybe a rename might be in order.
tip-bot for Peter Zijlstra
merge bot[tip:perf/core] perf record: Add clockid parameter
In reply to Peter Zijlstraperf record: Add clockid parameter
Commit-ID: 814c8c38e13c7050259c72f89bb01f3fc903f642 Gitweb: http://git.kernel.org/tip/814c8c38e13c7050259c72f89bb01f3fc903f642 Author: Peter Zijlstra <[email protected]> AuthorDate: Tue, 31 Mar 2015 00:19:31 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 8 Apr 2015 10:04:55 -0300
perf record: Add clockid parameter
Teach perf-record about the new perf_event_attr::{use_clockid, clockid} fields. Add a simple parameter to set the clock (if any) to be used for the events to be recorded into the data file.
Since we store the entire perf_event_attr in the EVENT_DESC section we also already store the used clockid in the data file.
[ Conditionally define CLOCK_BOOTTIME, at least rhel6 doesn't have it - dsahern
Ditto for CLOCK_MONOTONIC_RAW, sles11sp2 doesn't have it - yunlong.song ]
--- tools/perf/Documentation/perf-record.txt | 7 +++ tools/perf/builtin-record.c | 87 ++++++++++++++++++++++++++++++++ tools/perf/perf.h | 2 + tools/perf/util/evsel.c | 59 ++++++++++++++++++++-- tools/perf/util/header.c | 3 ++ 5 files changed, 154 insertions(+), 4 deletions(-)
tools/perf/Documentation/perf-record.txt +7 -0
@@ -250,6 +250,13 @@ is off by default. --running-time:: Record running and enabled time for read events (:S) +-k:: +--clockid:: +Sets the clock id to use for the various time fields in the perf_event_type +records. See clock_gettime(). In particular CLOCK_MONOTONIC and +CLOCK_MONOTONIC_RAW are supported, some events might also allow +CLOCK_BOOTTIME, CLOCK_REALTIME and CLOCK_TAI. + SEE ALSO -------- linkperf:perf-stat[1], linkperf:perf-list[1]
tools/perf/builtin-record.c +87 -0
99 lines not on this page · raw message
tools/perf/perf.h +2 -0
@@ -62,6 +62,8 @@ struct record_opts {u64 user_interval;bool sample_transaction;unsigned initial_delay; +bool use_clockid; +clockid_t clockid; };struct option ;
tools/perf/util/evsel.c +55 -4
132 lines not on this page · raw message
tools/perf/util/header.c +3 -0
@@ -1098,6 +1098,9 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) }fprintf (fp," }" ); } +if (evsel->attr.use_clockid) +fprintf (fp,", clockid = %d" , evsel->attr.clockid); +fputc ('\n' , fp); }
Peter Zijlstra
maintainerPATCH 2/2 perf, tools: Merge all perf_event_attr print functions
In reply to Peter ZijlstraCurrently 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--- 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(-)
tools/perf/util/evsel.c +126 -158
@@ -1011,70 +1011,126 @@ static int get_group_fd(struct perf_evsereturn 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 perif (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, boolreturn 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;
tools/perf/util/evsel.h +6 -0
@@ -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 */
tools/perf/util/header.c +7 -22
@@ -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 perffor (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); }
Re: [PATCH 2/2] perf, tools: Merge all perf_event_attr print functions
Em Tue, Apr 07, 2015 at 11:09:54AM +0200, Peter Zijlstra escreveu:
Quoted 8 lines
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.
Quoted 6 lines
Also, I cannot find a single
print_event_desc()caller.Pre:
$ perf record -vv -e cycles -- sleep 1 ------------------------------------------------------------
If you do the above, i.e. start a line with ----, then the following lines will go down the drain, fixing by prepending a whitespace :-)
- Arnaldo
Quoted 468 lines
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: 1Post:
$ ./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: 1Acked-by Adrian Hunter <[email protected]>Acked-by Ingo Molnar <[email protected]>Acked-by Jiri Olsa <[email protected]>Signed-off-by Peter Zijlstra (Intel) <[email protected]>--- 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(-)tools/perf/util/evsel.c +126
-158@@ -1011,70 +1011,126 @@ static int get_group_fd(struct perf_evsereturn 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 perif (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, boolreturn 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;tools/perf/util/evsel.h +6
-0@@ -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 */ tools/perf/util/header.c +7
-22@@ -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 perffor (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); }
tip-bot for Peter Zijlstra
merge bot[tip:perf/core] perf tools: Merge all perf_event_attr print functions
In reply to Peter Zijlstraperf tools: Merge all perf_event_attr print functions
Commit-ID: 2c5e8c52c6354f77c4019357be8231bcc34456f8 Gitweb: http://git.kernel.org/tip/2c5e8c52c6354f77c4019357be8231bcc34456f8 Author: Peter Zijlstra <[email protected]> AuthorDate: Tue, 7 Apr 2015 11:09:54 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 8 Apr 2015 10:06:28 -0300
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--- tools/perf/util/evsel.c | 288 +++++++++++++++++++++-------------------------- tools/perf/util/evsel.h | 6 + tools/perf/util/header.c | 29 ++--- 3 files changed, 141 insertions(+), 182 deletions(-)
tools/perf/util/evsel.c +128 -160
@@ -1011,70 +1011,126 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread)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 ; - - 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); - - ret +=fprintf (fp,"%.60s\n" , graph_dotted_line); +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); +} + +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) + +#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 @@ retry_sample_id: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 *first, const char *fmt, ...)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) +static int __print_attr__fprintf (FILE *fp,const char *name,const char *val,void *priv) { -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_evsel *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, (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;
tools/perf/util/evsel.h +6 -0
@@ -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 ; } + +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 */
tools/perf/util/header.c +7 -22
@@ -1055,6 +1055,12 @@ error: 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_header *ph, int fd, FILE *fp)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_header *ph, int fd, FILE *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); }
Quoted 7 lines · Peter Zijlstra
Hi Arnaldo,
As per your request, here's the latest version of the two patches.
I retained Jiri's and Ingo's ACK on the
perf_event_attrprinting patch even though I rewrote it since they acked it; if they feel I wrongly did so please holler.
It's only getting better so my ack stands! :-)
Thanks,
Ingo
Em Tue, Apr 07, 2015 at 11:09:52AM +0200, Peter Zijlstra escreveu:
Quoted 7 lines
Hi Arnaldo,
As per your request, here's the latest version of the two patches.
I retained Jiri's and Ingo's ACK on the
perf_event_attrprinting patch even though I rewrote it since they acked it; if they feel I wrongly did so please holler.
Ingo re-acked it, I'll keep Jiri's but will wait for him to renew it before pushing it to Ingo,
Thanks,
- Arnaldo
Quoted 11 lines · Arnaldo Carvalho de Melo
Em Tue, Apr 07, 2015 at 11:09:52AM +0200, Peter Zijlstra escreveu:
Quoted 7 lines
Hi Arnaldo,
As per your request, here's the latest version of the two patches.
I retained Jiri's and Ingo's ACK on the
perf_event_attrprinting patch even though I rewrote it since they acked it; if they feel I wrongly did so please holler.Ingo re-acked it, I'll keep Jiri's but will wait for him to renew it before pushing it to Ingo,
booth look ok to me.. ack ;-)
jirka