perf stat: Add scripting support
Jiri Olsa
reviewerv5 cover perf stat: Add scripting support
hi,
sending another version of stat scripting.
v5 changes:
- several patches from v4 already taken
- using u16 for cpu number in cpu_map_event
- renamed PERF_RECORD_HEADER_ATTR_UPDATE to PERF_RECORD_EVENT_UPDATE
- moved low hanging fuits patches to the start of the patchset
- patchset tested by Kan Liang, thanks!
v4 changes:
- added attr update event for event's cpumask
- forbig aggregation on task workloads
- some minor reorders and changelog fixes
v3 changes:
- added attr update event to handle unit,scale,name for event it fixed the uncore_imc_1/cas_count_read/ record/report
- perf report -D now displays stat related events
- some minor and changelog fixes
v2 changes:
- rebased to latest Arnaldo's perf/core
- patches 1 to 11 already merged in
- added --per-core/--per-socket/-A options for perf stat report command to allow custom aggregation in stat report, please check new examples below
- couple changelogs changes
The initial attempt defined its own formula lang and allowed triggering user's script on the end of the stat command:
http://marc.info/?l=linux-kernel&m=136742146322273&w=2
This patchset abandons the idea of new formula language and rather adds support to:
- store stat data into perf.data file
- add python support to process stat events
Basically it allows to store stat data into perf.data and post process it with python scripts in a similar way we do for sampling data.
The stat data are stored in new stat, stat-round, stat-config user events.
stat - stored for each read syscall of the counter
stat round - stored for each interval or end of the command invocation stat config - stores all the config information needed to process data
so report tool could restore the same output as record
The python script can now define 'stat__<eventname>_<modifier>' functions to get stat events data and 'stat__interval' to get stat-round data.
See CPI script example in scripts/python/stat-cpi.py.
Also available in:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/stat_script
thanks,
jirka
Examples:
- To record data for command stat workload:
$ perf stat record kill ...
Performance counter stats for 'kill':
0.372007 task-clock (msec) # 0.613 CPUs utilized
3 context-switches # 0.008 M/sec
0 cpu-migrations # 0.000 K/sec
62 page-faults # 0.167 M/sec
1,129,973 cycles # 3.038 GHz
<not supported> stalled-cycles-frontend
<not supported> stalled-cycles-backend
813,313 instructions # 0.72 insns per cycle
166,161 branches # 446.661 M/sec
8,747 branch-misses # 5.26% of all branches 0.000607287 seconds time elapsed
- To report perf stat data:
$ perf stat report
Performance counter stats for '/home/jolsa/bin/perf stat record kill':
0.372007 task-clock (msec) # inf CPUs utilized
3 context-switches # 0.008 M/sec
0 cpu-migrations # 0.000 K/sec
62 page-faults # 0.167 M/sec
1,129,973 cycles # 3.038 GHz
<not supported> stalled-cycles-frontend
<not supported> stalled-cycles-backend
813,313 instructions # 0.72 insns per cycle
166,161 branches # 446.661 M/sec
8,747 branch-misses # 5.26% of all branches 0.000000000 seconds time elapsed
- To store system-wide period stat data:
$ perf stat -e cycles:u,instructions:u -a -I 1000 record
# time counts unit events
1.000265471 462,311,482 cycles:u (100.00%)
1.000265471 590,037,440 instructions:u
2.000483453 722,532,336 cycles:u (100.00%)
2.000483453 848,678,197 instructions:u
3.000759876 75,990,880 cycles:u (100.00%)
3.000759876 86,187,813 instructions:u
^C 3.213960893 85,329,533 cycles:u (100.00%)
3.213960893 135,954,296 instructions:u - To report perf stat data:
$ perf stat report
# time counts unit events
1.000265471 462,311,482 cycles:u (100.00%)
1.000265471 590,037,440 instructions:u
2.000483453 722,532,336 cycles:u (100.00%)
2.000483453 848,678,197 instructions:u
3.000759876 75,990,880 cycles:u (100.00%)
3.000759876 86,187,813 instructions:u
3.213960893 85,329,533 cycles:u (100.00%)
3.213960893 135,954,296 instructions:u - To run stat-cpi.py script over perf.data:
$ perf script -s scripts/python/stat-cpi.py
1.000265: cpu -1, thread -1 -> cpi 0.783529 (462311482/590037440)
2.000483: cpu -1, thread -1 -> cpi 0.851362 (722532336/848678197)
3.000760: cpu -1, thread -1 -> cpi 0.881689 (75990880/86187813)
3.213961: cpu -1, thread -1 -> cpi 0.627634 (85329533/135954296)- To pipe data from stat to stat-cpi script:
$ perf stat -e cycles:u,instructions:u -A -C 0 -I 1000 record | perf script -s scripts/python/stat-cpi.py
1.000192: cpu 0, thread -1 -> cpi 0.739535 (23921908/32347236)
2.000376: cpu 0, thread -1 -> cpi 1.663482 (2519340/1514498)
3.000621: cpu 0, thread -1 -> cpi 1.396308 (16162767/11575362)
4.000700: cpu 0, thread -1 -> cpi 1.092246 (20077258/18381624)
5.000867: cpu 0, thread -1 -> cpi 0.473816 (45157586/95306156)
6.001034: cpu 0, thread -1 -> cpi 0.532792 (43701668/82023818)
7.001195: cpu 0, thread -1 -> cpi 1.122059 (29890042/26638561)- Raw script stat data output:
$ perf stat -e cycles:u,instructions:u -A -C 0 -I 1000 record | perf --no-pager script
CPU THREAD VAL ENA RUN TIME EVENT
0 -1 12302059 1000811347 1000810712 1000198821 cycles:u
0 -1 2565362 1000823218 1000823218 1000198821 instructions:u
0 -1 14453353 1000812704 1000812704 2000382283 cycles:u
0 -1 4600932 1000799342 1000799342 2000382283 instructions:u
0 -1 15245106 1000774425 1000774425 3000538255 cycles:u
0 -1 2624324 1000769310 1000769310 3000538255 instructions:u- To display different aggregation in report:
$ perf stat -e cycles -a -I 1000 record sleep 3
# time counts unit events
1.000223609 703,427,617 cycles
2.000443651 609,975,307 cycles
3.000569616 668,479,597 cycles
3.000735323 1,155,816 cycles $ perf stat report
# time counts unit events
1.000223609 703,427,617 cycles
2.000443651 609,975,307 cycles
3.000569616 668,479,597 cycles
3.000735323 1,155,816 cycles $ perf stat report --per-core
# time core cpus counts unit events
1.000223609 S0-C0 2 327,612,412 cycles
1.000223609 S0-C1 2 375,815,205 cycles
2.000443651 S0-C0 2 287,462,177 cycles
2.000443651 S0-C1 2 322,513,130 cycles
3.000569616 S0-C0 2 271,571,908 cycles
3.000569616 S0-C1 2 396,907,689 cycles
3.000735323 S0-C0 2 694,977 cycles
3.000735323 S0-C1 2 460,839 cycles $ perf stat report --per-socket
# time socket cpus counts unit events
1.000223609 S0 4 703,427,617 cycles
2.000443651 S0 4 609,975,307 cycles
3.000569616 S0 4 668,479,597 cycles
3.000735323 S0 4 1,155,816 cycles $ perf stat report -A
# time CPU counts unit events
1.000223609 CPU0 205,431,505 cycles
1.000223609 CPU1 122,180,907 cycles
1.000223609 CPU2 176,649,682 cycles
1.000223609 CPU3 199,165,523 cycles
2.000443651 CPU0 148,447,922 cycles
2.000443651 CPU1 139,014,255 cycles
2.000443651 CPU2 204,436,559 cycles
2.000443651 CPU3 118,076,571 cycles
3.000569616 CPU0 149,788,954 cycles
3.000569616 CPU1 121,782,954 cycles
3.000569616 CPU2 247,277,700 cycles
3.000569616 CPU3 149,629,989 cycles
3.000735323 CPU0 269,675 cycles
3.000735323 CPU1 425,302 cycles
3.000735323 CPU2 364,169 cycles
3.000735323 CPU3 96,670 cycles ---
Jiri Olsa (52):
perf cpu_map: Add cpu_map__empty_new function
perf stat: Cache aggregated map entries in extra cpumap perf tools: Add thread_map event
perf tools: Add thread_map event sythesize function
perf tools: Add thread_map__new_event function
perf tools: Add perf_event__fprintf_thread_map function perf tools: Add cpu_map event
perf tools: Add cpu_map event synthesize function
perf tools: Add cpu_map__new_event function
perf tools: Add perf_event__fprintf_cpu_map function
perf tools: Add stat config event
perf tools: Add stat config event synthesize function
perf tools: Add stat config event read function
perf tools: Add stat event
perf tools: Add stat event synthesize function
perf tools: Add stat event read function
perf tools: Add stat round event
perf tools: Add stat round event synthesize function
perf tools: Add stat events fprintf functions
perf tools: Add event_update event
perf tools: Add event_update event unit type
perf tools: Add event_update event scale type
perf tools: Add event_update event name type
perf tools: Add event_update event cpus type
perf tools: Add perf_event__fprintf_event_update function perf report: Display newly added events in raw dump
perf tools: Introduce stat feature
perf tools: Move id_offset out of struct perf_evsel union perf stat record: Add record command
perf stat record: Initialize record features
perf stat record: Synthesize stat record data
perf stat record: Store events IDs in perf data file
perf stat record: Add pipe support for record command
perf stat record: Write stat events on record
perf stat record: Write stat round events on record
perf stat record: Do not allow record with multiple runs mode perf stat record: Synthesize event update events
perf stat report: Add report command
perf stat report: Process cpu/threads maps
perf stat report: Process stat config event
perf stat report: Add support to initialize aggr_map from file perf stat report: Process stat and stat round events
perf stat report: Process event update events
perf stat report: Move csv_sep initialization before report command perf stat report: Allow to override aggr_mode
perf script: Process cpu/threads maps
perf script: Process stat config event
perf script: Add process_stat/process_stat_interval scripting interface perf script: Add stat default handlers
perf script: Display stat events by default
perf script: Add python support for stat events
perf script: Add stat-cpi.py script
tools/perf/Documentation/perf-stat.txt | 34 ++ tools/perf/builtin-record.c | 2 + tools/perf/builtin-script.c | 139 +++++ tools/perf/builtin-stat.c | 643 ++++++++++++++++++++- tools/perf/scripts/python/stat-cpi.py | 74 +++ tools/perf/tests/Build | 3 + tools/perf/tests/builtin-test.c | 24 + tools/perf/tests/cpumap.c | 88 +++ tools/perf/tests/event_update.c | 117 ++++ tools/perf/tests/stat.c | 111 ++++ tools/perf/tests/tests.h | 7 + tools/perf/tests/thread-map.c | 43 ++ tools/perf/util/cpumap.c | 59 ++ tools/perf/util/cpumap.h | 2 + tools/perf/util/event.c | 308 ++++++++++ tools/perf/util/event.h | 150 ++++- tools/perf/util/evlist.c | 6 +- tools/perf/util/evlist.h | 3 + tools/perf/util/evsel.h | 2 +- tools/perf/util/header.c | 205 +++++++ tools/perf/util/header.h | 17 + .../util/scripting-engines/trace-event-python.c | 114 +++- tools/perf/util/session.c | 189 ++++++ tools/perf/util/stat.c | 62 ++ tools/perf/util/stat.h | 10 + tools/perf/util/thread_map.c | 27 + tools/perf/util/thread_map.h | 3 + tools/perf/util/tool.h | 8 +- tools/perf/util/trace-event.h | 4 + 29 files changed, 2427 insertions(+), 27 deletions(-) create mode 100644 tools/perf/scripts/python/stat-cpi.py create mode 100644 tools/perf/tests/cpumap.c create mode 100644 tools/perf/tests/event_update.c create mode 100644 tools/perf/tests/stat.c
Jiri Olsa
reviewerPATCH v5 1/52 perf cpu_map: Add cpu_map__empty_new function
Adding cpu_map__empty_new interface to create empty cpumap with given size. The cpumap entries are initialized with -1.
It'll be used for caching cpu_map in following patches.
--- tools/perf/util/cpumap.c | 17 +++++++++++++++++ tools/perf/util/cpumap.h | 1 + 2 files changed, 18 insertions(+)
tools/perf/util/cpumap.c +17 -0
@@ -203,6 +203,23 @@ struct cpu_map *cpu_map__dummy_new(void)return cpus; } +struct cpu_map *cpu_map__empty_new (int nr) +{ +struct cpu_map *cpus =malloc (sizeof (*cpus) +sizeof (int ) * nr); + +if (cpus !=NULL ) { +int i; + + cpus->nr = nr; +for (i =0 ; i < nr; i++) + cpus->map[i] =-1 ; + +atomic_set (&cpus->refcnt,1 ); + } + +return cpus; +} +static void cpu_map__delete (struct cpu_map *map) {if (map) {
tools/perf/util/cpumap.h +1 -0
@@ -15,6 +15,7 @@ struct cpu_map { };struct cpu_map *cpu_map__new (const char *cpu_list); +struct cpu_map *cpu_map__empty_new (int nr);struct cpu_map *cpu_map__dummy_new (void );struct cpu_map *cpu_map__read (FILE *file);size_t cpu_map__fprintf (struct cpu_map *map,FILE *fp);
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf cpu_map: Add cpu_map__empty_new function
perf cpu_map: Add cpu_map__empty_new function
Commit-ID: 2322f573f8131da9c6d1fab01fe0a0c2c23aa549 Gitweb: http://git.kernel.org/tip/2322f573f8131da9c6d1fab01fe0a0c2c23aa549 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:17 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Tue, 27 Oct 2015 15:05:36 -0300
perf cpu_map: Add cpu_map__empty_new function
Adding cpu_map__empty_new interface to create empty cpumap with given size. The cpumap entries are initialized with -1.
It'll be used for caching cpu_map in following patches.
--- tools/perf/util/cpumap.c | 17 +++++++++++++++++ tools/perf/util/cpumap.h | 1 + 2 files changed, 18 insertions(+)
tools/perf/util/cpumap.c +17 -0
@@ -203,6 +203,23 @@ struct cpu_map *cpu_map__dummy_new(void)return cpus; } +struct cpu_map *cpu_map__empty_new (int nr) +{ +struct cpu_map *cpus =malloc (sizeof (*cpus) +sizeof (int ) * nr); + +if (cpus !=NULL ) { +int i; + + cpus->nr = nr; +for (i =0 ; i < nr; i++) + cpus->map[i] =-1 ; + +atomic_set (&cpus->refcnt,1 ); + } + +return cpus; +} +static void cpu_map__delete (struct cpu_map *map) {if (map) {
tools/perf/util/cpumap.h +1 -0
@@ -15,6 +15,7 @@ struct cpu_map { };struct cpu_map *cpu_map__new (const char *cpu_list); +struct cpu_map *cpu_map__empty_new (int nr);struct cpu_map *cpu_map__dummy_new (void );struct cpu_map *cpu_map__read (FILE *file);size_t cpu_map__fprintf (struct cpu_map *map,FILE *fp);
Jiri Olsa
reviewerPATCH v5 2/52 perf stat: Cache aggregated map entries in extra cpumap
In reply to Jiri OlsaCurrently any time we need to access socket or core id for given cpu, we access the sysfs topology file.
Adding cpus_aggr_map cpu_map to cache those entries.
--- tools/perf/builtin-stat.c | 60 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +56 -4
@@ -100,6 +100,8 @@ static struct target target = { .uid = UINT_MAX, }; +typedef int (*aggr_get_id_t )(struct cpu_map *m,int cpu); +static int run_count =1 ;static bool no_inherit = false;static volatile pid_t child_pid =-1 ;
@@ -119,7 +121,7 @@ static unsigned int unit_width = 4; /* strlen("unit") */static bool forever = false;static struct timespec ref_time;static struct cpu_map *aggr_map; -static int (*aggr_get_id)(struct cpu_map *m,int cpu); +static aggr_get_id_t aggr_get_id;static volatile int done =0 ;
@@ -944,6 +946,7 @@ static int stat__set_big_num(const struct option *opt __maybe_unused,return 0 ; } +static int perf_stat__get_socket (struct cpu_map *map,int cpu) {return cpu_map__get_socket (map, cpu,NULL );
@@ -954,22 +957,63 @@ static int perf_stat__get_core(struct cpu_map *map, int cpu)return cpu_map__get_core (map, cpu,NULL ); } +static int cpu_map__get_max (struct cpu_map *map) +{ +int i, max =-1 ; + +for (i =0 ; i < map->nr; i++) { +if (map->map[i] > max) + max = map->map[i]; + } + +return max; +} + +static struct cpu_map *cpus_aggr_map; + +static int perf_stat__get_aggr (aggr_get_id_t get_id,struct cpu_map *map,int idx) +{ +int cpu; + +if (idx >= map->nr) +return -1 ; + + cpu = map->map[idx]; + +if (cpus_aggr_map->map[cpu] ==-1 ) + cpus_aggr_map->map[cpu] =get_id (map, idx); + +return cpus_aggr_map->map[cpu]; +} + +static int perf_stat__get_socket_cached (struct cpu_map *map,int idx) +{ +return perf_stat__get_aggr (perf_stat__get_socket, map, idx); +} + +static int perf_stat__get_core_cached (struct cpu_map *map,int idx) +{ +return perf_stat__get_aggr (perf_stat__get_core, map, idx); +} +static int perf_stat_init_aggr_mode (void ) { +int nr; +switch (stat_config.aggr_mode) {case AGGR_SOCKET :if (cpu_map__build_socket_map (evsel_list->cpus, &aggr_map)) {perror ("cannot build socket map" );return -1 ; } - aggr_get_id = perf_stat__get_socket; + aggr_get_id = perf_stat__get_socket_cached;break ;case AGGR_CORE :if (cpu_map__build_core_map (evsel_list->cpus, &aggr_map)) {perror ("cannot build core map" );return -1 ; } - aggr_get_id = perf_stat__get_core; + aggr_get_id = perf_stat__get_core_cached;break ;case AGGR_NONE :case AGGR_GLOBAL :
@@ -978,7 +1022,15 @@ static int perf_stat_init_aggr_mode(void)default :break ; } -return 0 ; + +/* +* The evsel_list->cpus is the base we operate on, +* taking the highest cpu number to be the size of +* the aggregation translate cpumap. +*/ + nr =cpu_map__get_max (evsel_list->cpus); + cpus_aggr_map =cpu_map__empty_new (nr +1 ); +return cpus_aggr_map ?0 : -ENOMEM ; }/*
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Cache aggregated map entries in extra cpumap
perf stat: Cache aggregated map entries in extra cpumap
Commit-ID: 1e5a29318ba8506f52a8d727b5c6a53143f9882a Gitweb: http://git.kernel.org/tip/1e5a29318ba8506f52a8d727b5c6a53143f9882a Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:18 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Tue, 27 Oct 2015 15:08:07 -0300
perf stat: Cache aggregated map entries in extra cpumap
Currently any time we need to access socket or core id for given cpu, we access the sysfs topology file.
Adding a cpus_aggr_map cpu_map to cache those entries.
--- tools/perf/builtin-stat.c | 59 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +55 -4
@@ -100,6 +100,8 @@ static struct target target = { .uid = UINT_MAX, }; +typedef int (*aggr_get_id_t )(struct cpu_map *m,int cpu); +static int run_count =1 ;static bool no_inherit = false;static volatile pid_t child_pid =-1 ;
@@ -119,7 +121,7 @@ static unsigned int unit_width = 4; /* strlen("unit") */static bool forever = false;static struct timespec ref_time;static struct cpu_map *aggr_map; -static int (*aggr_get_id)(struct cpu_map *m,int cpu); +static aggr_get_id_t aggr_get_id;static volatile int done =0 ;
@@ -954,22 +956,63 @@ static int perf_stat__get_core(struct cpu_map *map, int cpu)return cpu_map__get_core (map, cpu,NULL ); } +static int cpu_map__get_max (struct cpu_map *map) +{ +int i, max =-1 ; + +for (i =0 ; i < map->nr; i++) { +if (map->map[i] > max) + max = map->map[i]; + } + +return max; +} + +static struct cpu_map *cpus_aggr_map; + +static int perf_stat__get_aggr (aggr_get_id_t get_id,struct cpu_map *map,int idx) +{ +int cpu; + +if (idx >= map->nr) +return -1 ; + + cpu = map->map[idx]; + +if (cpus_aggr_map->map[cpu] ==-1 ) + cpus_aggr_map->map[cpu] =get_id (map, idx); + +return cpus_aggr_map->map[cpu]; +} + +static int perf_stat__get_socket_cached (struct cpu_map *map,int idx) +{ +return perf_stat__get_aggr (perf_stat__get_socket, map, idx); +} + +static int perf_stat__get_core_cached (struct cpu_map *map,int idx) +{ +return perf_stat__get_aggr (perf_stat__get_core, map, idx); +} +static int perf_stat_init_aggr_mode (void ) { +int nr; +switch (stat_config.aggr_mode) {case AGGR_SOCKET :if (cpu_map__build_socket_map (evsel_list->cpus, &aggr_map)) {perror ("cannot build socket map" );return -1 ; } - aggr_get_id = perf_stat__get_socket; + aggr_get_id = perf_stat__get_socket_cached;break ;case AGGR_CORE :if (cpu_map__build_core_map (evsel_list->cpus, &aggr_map)) {perror ("cannot build core map" );return -1 ; } - aggr_get_id = perf_stat__get_core; + aggr_get_id = perf_stat__get_core_cached;break ;case AGGR_NONE :case AGGR_GLOBAL :
@@ -978,7 +1021,15 @@ static int perf_stat_init_aggr_mode(void)default :break ; } -return 0 ; + +/* +* The evsel_list->cpus is the base we operate on, +* taking the highest cpu number to be the size of +* the aggregation translate cpumap. +*/ + nr =cpu_map__get_max (evsel_list->cpus); + cpus_aggr_map =cpu_map__empty_new (nr +1 ); +return cpus_aggr_map ?0 : -ENOMEM ; }/*
Jiri Olsa
reviewerPATCH v5 3/52 perf tools: Add thread_map event
In reply to Jiri OlsaAdding thread_map event to pass/store thread maps
as data in pipe/perf.data.
Storing thread ID along with the standard comm[16] thread name string.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 13 +++++++++++++ tools/perf/util/session.c | 26 ++++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 42 insertions(+), 1 deletion(-)
tools/perf/util/event.c +1 -0
@@ -37,6 +37,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_AUXTRACE_INFO] = "AUXTRACE_INFO", [PERF_RECORD_AUXTRACE] = "AUXTRACE", [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", + [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +13 -0
@@ -226,6 +226,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_AUXTRACE_INFO =70 ,PERF_RECORD_AUXTRACE =71 ,PERF_RECORD_AUXTRACE_ERROR =72 , +PERF_RECORD_THREAD_MAP =73 , PERF_RECORD_HEADER_MAX };
@@ -356,6 +357,17 @@ struct context_switch_event {u32 next_prev_tid; }; +struct thread_map_data_event { +u64 pid; +char comm[16 ]; +}; + +struct thread_map_event { +struct perf_event_header header; +u64 nr; +struct thread_map_data_event data[]; +}; +union perf_event {struct perf_event_header header;struct mmap_event mmap;
@@ -378,6 +390,7 @@ union perf_event {struct aux_event aux;struct itrace_start_event itrace_start;struct context_switch_event context_switch; +struct thread_map_event thread_map; };void perf_event__print_totals (void );
tools/perf/util/session.c +26 -0
@@ -296,6 +296,16 @@ int process_event_auxtrace_error_stub(struct perf_tool *tool __maybe_unused,return 0 ; } + +static +int process_event_thread_map_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_session *session__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} +void perf_tool__fill_defaults (struct perf_tool *tool) {if (tool->sample ==NULL )
@@ -346,6 +356,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->auxtrace = process_event_auxtrace_stub;if (tool->auxtrace_error ==NULL ) tool->auxtrace_error = process_event_auxtrace_error_stub; +if (tool->thread_map ==NULL ) + tool->thread_map = process_event_thread_map_stub; }static void swap_sample_id_all (union perf_event *event,void *data)
@@ -616,6 +628,17 @@ static void perf_event__auxtrace_error_swap(union perf_event *event, event->auxtrace_error.ip =bswap_64 (event->auxtrace_error.ip); } +static void perf_event__thread_map_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ +unsigned i; + + event->thread_map.nr =bswap_64 (event->thread_map.nr); + +for (i =0 ; i < event->thread_map.nr; i++) + event->thread_map.data[i].pid =bswap_64 (event->thread_map.data[i].pid); +} +typedef void (*perf_event__swap_op )(union perf_event *event,bool sample_id_all);
@@ -643,6 +666,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_AUXTRACE_INFO] = perf_event__auxtrace_info_swap, [PERF_RECORD_AUXTRACE] = perf_event__auxtrace_swap, [PERF_RECORD_AUXTRACE_ERROR] = perf_event__auxtrace_error_swap, + [PERF_RECORD_THREAD_MAP] = perf_event__thread_map_swap, [PERF_RECORD_HEADER_MAX] = NULL, };
@@ -1179,6 +1203,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,case PERF_RECORD_AUXTRACE_ERROR :perf_session__auxtrace_error_inc (session, event);return tool->auxtrace_error (tool, event, session); +case PERF_RECORD_THREAD_MAP : +return tool->thread_map (tool, event, session);default :return -EINVAL ; }
tools/perf/util/tool.h +2 -1
@@ -55,7 +55,8 @@ struct perf_tool {event_op2 build_id, id_index, auxtrace_info, - auxtrace_error; + auxtrace_error, + thread_map;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;
Signature · 1 line
2.4.3
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 03/52] perf tools: Add thread_map event
Em Sun, Oct 25, 2015 at 03:51:19PM +0100, Jiri Olsa escreveu:
Quoted 40 lines
Adding
thread_mapevent to pass/store thread maps
as data in pipe/perf.data.Storing thread ID along with the standard comm[16] thread name string.
Signed-off-by Jiri Olsa <[email protected]>--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 13 +++++++++++++ tools/perf/util/session.c | 26 ++++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 42 insertions(+), 1 deletion(-)tools/perf/util/event.c +1
-0@@ -37,6 +37,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_AUXTRACE_INFO] = "AUXTRACE_INFO", [PERF_RECORD_AUXTRACE] = "AUXTRACE", [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", + [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", };const char *perf_event__name (unsigned int id)tools/perf/util/event.h +1
-0@@ -226,6 +226,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_AUXTRACE_INFO =70 ,PERF_RECORD_AUXTRACE =71 ,PERF_RECORD_AUXTRACE_ERROR =72 , +PERF_RECORD_THREAD_MAP =73 , PERF_RECORD_HEADER_MAX };
tools/perf/util/event.h struct context_switch_event { · line 360
Quoted 4 lines
tools/perf/util/event.h +1
-0@@ -356,6 +357,17 @@ struct context_switch_event {u32 next_prev_tid; }; +struct thread_map_data_event {
Humm, I think "data" here is way too vague here, how about "thread_map_event_entry"?
Moving of "entry" to the end also helps in understanding that this is not an "event" per se, it doesn't have the perv_event_header, etc, its just an entry in a 'struct thread_map_event'.
I'm tentatively doing this change in my local branch, please let me know if you have any reason to object to such a change,
- Arnaldo
Quoted 102 lines
tools/perf/util/event.h +11
-0+u64 pid; +char comm[16 ]; +}; + +struct thread_map_event { +struct perf_event_header header; +u64 nr; +struct thread_map_data_event data[]; +}; +union perf_event {struct perf_event_header header;struct mmap_event mmap;@@ -378,6 +390,7 @@ union perf_event {struct aux_event aux;struct itrace_start_event itrace_start;struct context_switch_event context_switch; +struct thread_map_event thread_map; };void perf_event__print_totals (void );tools/perf/util/session.c +26
-0@@ -296,6 +296,16 @@ int process_event_auxtrace_error_stub(struct perf_tool *tool __maybe_unused,return 0 ; } + +static +int process_event_thread_map_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_session *session__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} +void perf_tool__fill_defaults (struct perf_tool *tool) {if (tool->sample ==NULL )@@ -346,6 +356,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->auxtrace = process_event_auxtrace_stub;if (tool->auxtrace_error ==NULL ) tool->auxtrace_error = process_event_auxtrace_error_stub; +if (tool->thread_map ==NULL ) + tool->thread_map = process_event_thread_map_stub; }static void swap_sample_id_all (union perf_event *event,void *data)@@ -616,6 +628,17 @@ static void perf_event__auxtrace_error_swap(union perf_event *event, event->auxtrace_error.ip =bswap_64 (event->auxtrace_error.ip); } +static void perf_event__thread_map_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ +unsigned i; + + event->thread_map.nr =bswap_64 (event->thread_map.nr); + +for (i =0 ; i < event->thread_map.nr; i++) + event->thread_map.data[i].pid =bswap_64 (event->thread_map.data[i].pid); +} +typedef void (*perf_event__swap_op )(union perf_event *event,bool sample_id_all);@@ -643,6 +666,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_AUXTRACE_INFO] = perf_event__auxtrace_info_swap, [PERF_RECORD_AUXTRACE] = perf_event__auxtrace_swap, [PERF_RECORD_AUXTRACE_ERROR] = perf_event__auxtrace_error_swap, + [PERF_RECORD_THREAD_MAP] = perf_event__thread_map_swap, [PERF_RECORD_HEADER_MAX] = NULL, };@@ -1179,6 +1203,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,case PERF_RECORD_AUXTRACE_ERROR :perf_session__auxtrace_error_inc (session, event);return tool->auxtrace_error (tool, event, session); +case PERF_RECORD_THREAD_MAP : +return tool->thread_map (tool, event, session);default :return -EINVAL ; }tools/perf/util/tool.h +2
-1@@ -55,7 +55,8 @@ struct perf_tool {event_op2 build_id, id_index, auxtrace_info, - auxtrace_error; + auxtrace_error, + thread_map;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;Signature · 1 line
2.4.3
Re: [PATCH 03/52] perf tools: Add thread_map event
On Mon, Oct 26, 2015 at 02:42:06PM -0300, Arnaldo Carvalho de Melo wrote:
SNIP
Quoted 14 lines
tools/perf/util/event.h struct context_switch_event { · line 360
Quoted 10 lines
tools/perf/util/event.h +2
-0PERF_RECORD_AUXTRACE_ERROR =72 , +PERF_RECORD_THREAD_MAP =73 , PERF_RECORD_HEADER_MAX };@@ -356,6 +357,17 @@ struct context_switch_event {u32 next_prev_tid; }; +struct thread_map_data_event {Humm, I think "data" here is way too vague here, how about "
thread_map_event_entry"?
Quoted 6 lines
Moving of "entry" to the end also helps in understanding that this is not an "event" per se, it doesn't have the
perv_event_header, etc, its just an entry in a 'structthread_map_event'.I'm tentatively doing this change in my local branch, please let me know if you have any reason to object to such a change,
np, hope there's not much dependency on this later in patchset ;-) probably not..
thanks,
jirka
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 03/52] perf tools: Add thread_map event
In reply to Arnaldo Carvalho de MeloEm Mon, Oct 26, 2015 at 02:42:06PM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 49 lines
Em Sun, Oct 25, 2015 at 03:51:19PM +0100, Jiri Olsa escreveu:
Quoted 40 lines
Adding
thread_mapevent to pass/store thread maps
as data in pipe/perf.data.Storing thread ID along with the standard comm[16] thread name string.
Signed-off-by Jiri Olsa <[email protected]>--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 13 +++++++++++++ tools/perf/util/session.c | 26 ++++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 42 insertions(+), 1 deletion(-)tools/perf/util/event.c +1
-0@@ -37,6 +37,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_AUXTRACE_INFO] = "AUXTRACE_INFO", [PERF_RECORD_AUXTRACE] = "AUXTRACE", [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", + [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", };const char *perf_event__name (unsigned int id)tools/perf/util/event.h +1
-0@@ -226,6 +226,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_AUXTRACE_INFO =70 ,PERF_RECORD_AUXTRACE =71 ,PERF_RECORD_AUXTRACE_ERROR =72 , +PERF_RECORD_THREAD_MAP =73 , PERF_RECORD_HEADER_MAX };tools/perf/util/event.h struct context_switch_event { · line 360
Quoted 4 lines
tools/perf/util/event.h +1
-0@@ -356,6 +357,17 @@ struct context_switch_event {u32 next_prev_tid; }; +struct thread_map_data_event {Humm, I think "data" here is way too vague here, how about "
thread_map_event_entry"?
Quoted 6 lines
Moving of "entry" to the end also helps in understanding that this is not an "event" per se, it doesn't have the
perv_event_header, etc, its just an entry in a 'structthread_map_event'.I'm tentatively doing this change in my local branch, please let me know if you have any reason to object to such a change,
The resulting patch, that I'm merging with this one:
tools/perf/util/event.h +2 -2
@@ -357,7 +357,7 @@ struct context_switch_event {u32 next_prev_tid; }; -struct thread_map_data_event { +struct thread_map_event_entry {u64 pid;char comm[16 ]; };
@@ -365,7 +365,7 @@ struct thread_map_data_event {struct thread_map_event {struct perf_event_header header;u64 nr; -struct thread_map_data_event data[]; +struct thread_map_event_entry entries[]; };union perf_event {
tools/perf/util/session.c +1 -1
@@ -636,7 +636,7 @@ static void perf_event__thread_map_swap(union perf_event *event, event->thread_map.nr =bswap_64 (event->thread_map.nr);for (i =0 ; i < event->thread_map.nr; i++) - event->thread_map.data[i].pid =bswap_64 (event->thread_map.data[i].pid); + event->thread_map.entries[i].pid =bswap_64 (event->thread_map.entries[i].pid); } typedef void (*perf_event__swap_op)(union perf_event *event,
Re: [PATCH 03/52] perf tools: Add thread_map event
On Mon, Oct 26, 2015 at 02:48:25PM -0300, Arnaldo Carvalho de Melo wrote:
SNIP
Quoted 8 lines
Quoted 8 lines
tools/perf/util/event.h struct context_switch_event {
Quoted 4 lines
tools/perf/util/event.h +1
-0u32 next_prev_tid; }; +struct thread_map_data_event {Humm, I think "data" here is way too vague here, how about "
thread_map_event_entry"?
Quoted 8 lines
Quoted 6 lines
Moving of "entry" to the end also helps in understanding that this is not an "event" per se, it doesn't have the
perv_event_header, etc, its just an entry in a 'structthread_map_event'.I'm tentatively doing this change in my local branch, please let me know if you have any reason to object to such a change,
The resulting patch, that I'm merging with this one:
seems ok, thanks
jirka
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 03/52] perf tools: Add thread_map event
Em Mon, Oct 26, 2015 at 06:55:45PM +0100, Jiri Olsa escreveu:
Quoted 16 lines · Arnaldo Carvalho de Melo
SNIP
Quoted 12 lines
Quoted 12 lines
tools/perf/util/event.h struct context_switch_event {
Quoted 4 lines
tools/perf/util/event.h +1
-0u32 next_prev_tid; }; +struct thread_map_data_event {Humm, I think "data" here is way too vague here, how about "
thread_map_event_entry"?Moving of "entry" to the end also helps in understanding that this is not an "event" per se, it doesn't have the
perv_event_header, etc, its just an entry in a 'structthread_map_event'.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
I'm tentatively doing this change in my local branch, please let me know if you have any reason to object to such a change,
The resulting patch, that I'm merging with this one:
seems ok, thanks
Thanks for checking, hopefully I can push this today.
- Arnaldo
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf thread_map: Add thread_map user level event
In reply to Jiri Olsaperf thread_map: Add thread_map user level event
Commit-ID: 5f3339d2e83ca587c2e13c3e37e1b5fb7c68ebe5 Gitweb: http://git.kernel.org/tip/5f3339d2e83ca587c2e13c3e37e1b5fb7c68ebe5 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:19 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:16 -0300
perf thread_map: Add thread_map user level event
Adding the thread_map event to pass/store thread maps as data in the pipe/perf.data.
Storing the thread ID along with the standard comm[16] thread name string.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 13 +++++++++++++ tools/perf/util/session.c | 26 ++++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 42 insertions(+), 1 deletion(-)
tools/perf/util/event.c +1 -0
@@ -37,6 +37,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_AUXTRACE_INFO] = "AUXTRACE_INFO", [PERF_RECORD_AUXTRACE] = "AUXTRACE", [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", + [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +13 -0
@@ -226,6 +226,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_AUXTRACE_INFO =70 ,PERF_RECORD_AUXTRACE =71 ,PERF_RECORD_AUXTRACE_ERROR =72 , +PERF_RECORD_THREAD_MAP =73 , PERF_RECORD_HEADER_MAX };
@@ -356,6 +357,17 @@ struct context_switch_event {u32 next_prev_tid; }; +struct thread_map_event_entry { +u64 pid; +char comm[16 ]; +}; + +struct thread_map_event { +struct perf_event_header header; +u64 nr; +struct thread_map_event_entry entries[]; +}; +union perf_event {struct perf_event_header header;struct mmap_event mmap;
@@ -378,6 +390,7 @@ union perf_event {struct aux_event aux;struct itrace_start_event itrace_start;struct context_switch_event context_switch; +struct thread_map_event thread_map; };void perf_event__print_totals (void );
tools/perf/util/session.c +26 -0
@@ -296,6 +296,16 @@ int process_event_auxtrace_error_stub(struct perf_tool *tool __maybe_unused,return 0 ; } + +static +int process_event_thread_map_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_session *session__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} +void perf_tool__fill_defaults (struct perf_tool *tool) {if (tool->sample ==NULL )
@@ -346,6 +356,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->auxtrace = process_event_auxtrace_stub;if (tool->auxtrace_error ==NULL ) tool->auxtrace_error = process_event_auxtrace_error_stub; +if (tool->thread_map ==NULL ) + tool->thread_map = process_event_thread_map_stub; }static void swap_sample_id_all (union perf_event *event,void *data)
@@ -616,6 +628,17 @@ static void perf_event__auxtrace_error_swap(union perf_event *event, event->auxtrace_error.ip =bswap_64 (event->auxtrace_error.ip); } +static void perf_event__thread_map_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ +unsigned i; + + event->thread_map.nr =bswap_64 (event->thread_map.nr); + +for (i =0 ; i < event->thread_map.nr; i++) + event->thread_map.entries[i].pid =bswap_64 (event->thread_map.entries[i].pid); +} +typedef void (*perf_event__swap_op )(union perf_event *event,bool sample_id_all);
@@ -643,6 +666,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_AUXTRACE_INFO] = perf_event__auxtrace_info_swap, [PERF_RECORD_AUXTRACE] = perf_event__auxtrace_swap, [PERF_RECORD_AUXTRACE_ERROR] = perf_event__auxtrace_error_swap, + [PERF_RECORD_THREAD_MAP] = perf_event__thread_map_swap, [PERF_RECORD_HEADER_MAX] = NULL, };
@@ -1179,6 +1203,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,case PERF_RECORD_AUXTRACE_ERROR :perf_session__auxtrace_error_inc (session, event);return tool->auxtrace_error (tool, event, session); +case PERF_RECORD_THREAD_MAP : +return tool->thread_map (tool, event, session);default :return -EINVAL ; }
tools/perf/util/tool.h +2 -1
@@ -55,7 +55,8 @@ struct perf_tool {event_op2 build_id, id_index, auxtrace_info, - auxtrace_error; + auxtrace_error, + thread_map;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;
Jiri Olsa
reviewerPATCH v5 4/52 perf tools: Add thread_map event sythesize function
In reply to Jiri OlsaIntroduce perf_event__synthesize_thread_map2 function to synthesize struct thread_map.
The perf_event__synthesize_thread_map name is already taken for synthesizing complete threads data (comm/mmap/fork).
--- tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/tests.h | 1 + tools/perf/tests/thread-map.c | 29 +++++++++++++++++++++++++++++ tools/perf/util/event.c | 36 ++++++++++++++++++++++++++++++++++++ tools/perf/util/event.h | 4 ++++ 5 files changed, 74 insertions(+)
tools/perf/tests/builtin-test.c +4 -0
@@ -166,6 +166,10 @@ static struct test generic_tests[] = { .func = test_session_topology, }, { + .desc = "Test thread map synthesize", + .func = test__thread_map_synthesize, + }, + { .func = NULL, }, };
tools/perf/tests/tests.h +1 -0
@@ -67,6 +67,7 @@ int test__kmod_path__parse(void);int test__thread_map (void );int test__llvm (void );int test_session_topology (void ); +int test__thread_map_synthesize (void );#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/tests/thread-map.c +29 -0
@@ -40,3 +40,32 @@ int test__thread_map(void)thread_map__put (map);return 0 ; } + +static int process_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ +struct thread_map_event *map = &event->thread_map; + +TEST_ASSERT_VAL ("wrong nr" , map->nr ==1 ); +TEST_ASSERT_VAL ("wrong pid" , map->data[0 ].pid == (u64 )getpid ()); +TEST_ASSERT_VAL ("wrong comm" , !strcmp (map->data[0 ].comm,"perf" )); +return 0 ; +} + +int test__thread_map_synthesize (void ) +{ +struct thread_map *threads; + +/* test map on current pid */ + threads =thread_map__new_by_pid (getpid ()); +TEST_ASSERT_VAL ("failed to alloc map" , threads); + +thread_map__read_comms (threads); + +TEST_ASSERT_VAL ("failed to synthesize map" , + !perf_event__synthesize_thread_map2 (NULL , threads, process_event,NULL )); + +return 0 ; +}
tools/perf/util/event.c +36 -0
@@ -700,6 +700,42 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,return err; } +int perf_event__synthesize_thread_map2 (struct perf_tool *tool, +struct thread_map *threads, +perf_event__handler_t process, +struct machine *machine) +{ +union perf_event *event; +int i, err, size; + + size =sizeof (event->thread_map); + size += threads->nr *sizeof (event->thread_map.data[0 ]); + + event =zalloc (size); +if (!event) +return -ENOMEM ; + + event->header.type =PERF_RECORD_THREAD_MAP ; + event->header.size = size; + event->thread_map.nr = threads->nr; + +for (i =0 ; i < threads->nr; i++) { +struct thread_map_data_event *data = &event->thread_map.data[i]; +char *comm =thread_map__comm (threads, i); + +if (!comm) + comm = (char *)"" ; + + data->pid =thread_map__pid (threads, i); +strncpy ((char *) &data->comm, comm,sizeof (data->comm)); + } + + err =process (tool, event,NULL , machine); + +free (event); +return err; +} +size_t perf_event__fprintf_comm (union perf_event *event,FILE *fp) {const char *s;
tools/perf/util/event.h +4 -0
@@ -408,6 +408,10 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,perf_event__handler_t process, struct machine *machine, bool mmap_data, unsigned int proc_map_timeout); +int perf_event__synthesize_thread_map2 (struct perf_tool *tool, +struct thread_map *threads, +perf_event__handler_t process, +struct machine *machine); int perf_event__synthesize_threads(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine, bool mmap_data,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf thread_map: Add thread_map event sythesize function
perf thread_map: Add thread_map event sythesize function
Commit-ID: 99471c967a00c875bb5d61f377d4267904545499 Gitweb: http://git.kernel.org/tip/99471c967a00c875bb5d61f377d4267904545499 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:20 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:16 -0300
perf thread_map: Add thread_map event sythesize function
Introduce the perf_event__synthesize_thread_map2 function to synthesize struct thread_map.
The perf_event__synthesize_thread_map name is already taken for synthesizing the complete threads data (comm/mmap/fork).
--- tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/tests.h | 1 + tools/perf/tests/thread-map.c | 29 +++++++++++++++++++++++++++++ tools/perf/util/event.c | 36 ++++++++++++++++++++++++++++++++++++ tools/perf/util/event.h | 4 ++++ 5 files changed, 74 insertions(+)
tools/perf/tests/builtin-test.c +4 -0
@@ -180,6 +180,10 @@ static struct test generic_tests[] = { }, }, { + .desc = "Test thread map synthesize", + .func = test__thread_map_synthesize, + }, + { .func = NULL, }, };
tools/perf/tests/tests.h +1 -0
@@ -79,6 +79,7 @@ int test__bpf(int subtest);const char *test__bpf_subtest_get_desc (int subtest);int test__bpf_subtest_get_nr (void );int test_session_topology (int subtest); +int test__thread_map_synthesize (int subtest);#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/tests/thread-map.c +29 -0
@@ -40,3 +40,32 @@ int test__thread_map(int subtest __maybe_unused)thread_map__put (map);return 0 ; } + +static int process_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ +struct thread_map_event *map = &event->thread_map; + +TEST_ASSERT_VAL ("wrong nr" , map->nr ==1 ); +TEST_ASSERT_VAL ("wrong pid" , map->entries[0 ].pid == (u64 )getpid ()); +TEST_ASSERT_VAL ("wrong comm" , !strcmp (map->entries[0 ].comm,"perf" )); +return 0 ; +} + +int test__thread_map_synthesize (int subtest__maybe_unused ) +{ +struct thread_map *threads; + +/* test map on current pid */ + threads =thread_map__new_by_pid (getpid ()); +TEST_ASSERT_VAL ("failed to alloc map" , threads); + +thread_map__read_comms (threads); + +TEST_ASSERT_VAL ("failed to synthesize map" , + !perf_event__synthesize_thread_map2 (NULL , threads, process_event,NULL )); + +return 0 ; +}
tools/perf/util/event.c +36 -0
@@ -700,6 +700,42 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,return err; } +int perf_event__synthesize_thread_map2 (struct perf_tool *tool, +struct thread_map *threads, +perf_event__handler_t process, +struct machine *machine) +{ +union perf_event *event; +int i, err, size; + + size =sizeof (event->thread_map); + size += threads->nr *sizeof (event->thread_map.entries[0 ]); + + event =zalloc (size); +if (!event) +return -ENOMEM ; + + event->header.type =PERF_RECORD_THREAD_MAP ; + event->header.size = size; + event->thread_map.nr = threads->nr; + +for (i =0 ; i < threads->nr; i++) { +struct thread_map_event_entry *entry = &event->thread_map.entries[i]; +char *comm =thread_map__comm (threads, i); + +if (!comm) + comm = (char *)"" ; + + entry->pid =thread_map__pid (threads, i); +strncpy ((char *) &entry->comm, comm,sizeof (entry->comm)); + } + + err =process (tool, event,NULL , machine); + +free (event); +return err; +} +size_t perf_event__fprintf_comm (union perf_event *event,FILE *fp) {const char *s;
tools/perf/util/event.h +4 -0
@@ -408,6 +408,10 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,perf_event__handler_t process, struct machine *machine, bool mmap_data, unsigned int proc_map_timeout); +int perf_event__synthesize_thread_map2 (struct perf_tool *tool, +struct thread_map *threads, +perf_event__handler_t process, +struct machine *machine); int perf_event__synthesize_threads(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine, bool mmap_data,
Jiri Olsa
reviewerPATCH v5 5/52 perf tools: Add thread_map__new_event function
In reply to Jiri OlsaIntroducing thread_map__new_event function to create struct thread_map object from thread_map event.
--- tools/perf/tests/thread-map.c | 14 ++++++++++++++ tools/perf/util/thread_map.c | 27 +++++++++++++++++++++++++++ tools/perf/util/thread_map.h | 3 +++ 3 files changed, 44 insertions(+)
tools/perf/tests/thread-map.c +14 -0
@@ -47,10 +47,24 @@ static int process_event(struct perf_tool *tool __maybe_unused, struct machine *machine __maybe_unused) {struct thread_map_event *map = &event->thread_map; +struct thread_map *threads;TEST_ASSERT_VAL ("wrong nr" , map->nr ==1 );TEST_ASSERT_VAL ("wrong pid" , map->data[0 ].pid == (u64 )getpid ());TEST_ASSERT_VAL ("wrong comm" , !strcmp (map->data[0 ].comm,"perf" )); + + threads =thread_map__new_event (&event->thread_map); +TEST_ASSERT_VAL ("failed to alloc map" , threads); + +TEST_ASSERT_VAL ("wrong nr" , threads->nr ==1 ); +TEST_ASSERT_VAL ("wrong pid" , +thread_map__pid (threads,0 ) ==getpid ()); +TEST_ASSERT_VAL ("wrong comm" , +thread_map__comm (threads,0 ) && + !strcmp (thread_map__comm (threads,0 ),"perf" )); +TEST_ASSERT_VAL ("wrong refcnt" , +atomic_read (&threads->refcnt) ==1 ); +thread_map__put (threads);return 0 ; }
tools/perf/util/thread_map.c +27 -0
@@ -13,6 +13,7 @@#include "thread_map.h" #include "util.h" #include "debug.h" +#include "event.h" /* Skip "." and ".." directories */ static int filter (const struct dirent *dir)
@@ -408,3 +409,29 @@ void thread_map__read_comms(struct thread_map *threads)for (i =0 ; i < threads->nr; ++i)comm_init (threads, i); } + +static void thread_map__copy_event (struct thread_map *threads, +struct thread_map_event *event) +{ +unsigned i; + + threads->nr = (int ) event->nr; + +for (i =0 ; i < event->nr; i++) { +thread_map__set_pid (threads, i, (pid_t ) event->data[i].pid); + threads->map[i].comm =strndup (event->data[i].comm,16 ); + } + +atomic_set (&threads->refcnt,1 ); +} + +struct thread_map *thread_map__new_event (struct thread_map_event *event) +{ +struct thread_map *threads; + + threads =thread_map__alloc (event->nr); +if (threads) +thread_map__copy_event (threads, event); + +return threads; +}
tools/perf/util/thread_map.h +3 -0
@@ -16,11 +16,14 @@ struct thread_map {struct thread_map_data map[]; }; +struct thread_map_event ; +struct thread_map *thread_map__new_dummy (void );struct thread_map *thread_map__new_by_pid (pid_t pid);struct thread_map *thread_map__new_by_tid (pid_t tid);struct thread_map *thread_map__new_by_uid (uid_t uid);struct thread_map *thread_map__new (pid_t pid,pid_t tid,uid_t uid); +struct thread_map *thread_map__new_event (struct thread_map_event *event);struct thread_map *thread_map__get (struct thread_map *map);void thread_map__put (struct thread_map *map);
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf thread_map: Add thread_map__new_event function
perf thread_map: Add thread_map__new_event function
Commit-ID: 59660942397b57b37eccba014544623cf4beb12b Gitweb: http://git.kernel.org/tip/59660942397b57b37eccba014544623cf4beb12b Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:21 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:16 -0300
perf thread_map: Add thread_map__new_event function
Introducing the thread_map__new_event function to create a struct thread_map object from a thread_map event.
--- tools/perf/tests/thread-map.c | 14 ++++++++++++++ tools/perf/util/thread_map.c | 27 +++++++++++++++++++++++++++ tools/perf/util/thread_map.h | 3 +++ 3 files changed, 44 insertions(+)
tools/perf/tests/thread-map.c +14 -0
@@ -47,10 +47,24 @@ static int process_event(struct perf_tool *tool __maybe_unused, struct machine *machine __maybe_unused) {struct thread_map_event *map = &event->thread_map; +struct thread_map *threads;TEST_ASSERT_VAL ("wrong nr" , map->nr ==1 );TEST_ASSERT_VAL ("wrong pid" , map->entries[0 ].pid == (u64 )getpid ());TEST_ASSERT_VAL ("wrong comm" , !strcmp (map->entries[0 ].comm,"perf" )); + + threads =thread_map__new_event (&event->thread_map); +TEST_ASSERT_VAL ("failed to alloc map" , threads); + +TEST_ASSERT_VAL ("wrong nr" , threads->nr ==1 ); +TEST_ASSERT_VAL ("wrong pid" , +thread_map__pid (threads,0 ) ==getpid ()); +TEST_ASSERT_VAL ("wrong comm" , +thread_map__comm (threads,0 ) && + !strcmp (thread_map__comm (threads,0 ),"perf" )); +TEST_ASSERT_VAL ("wrong refcnt" , +atomic_read (&threads->refcnt) ==1 ); +thread_map__put (threads);return 0 ; }
tools/perf/util/thread_map.c +27 -0
@@ -13,6 +13,7 @@#include "thread_map.h" #include "util.h" #include "debug.h" +#include "event.h" /* Skip "." and ".." directories */ static int filter (const struct dirent *dir)
@@ -409,3 +410,29 @@ void thread_map__read_comms(struct thread_map *threads)for (i =0 ; i < threads->nr; ++i)comm_init (threads, i); } + +static void thread_map__copy_event (struct thread_map *threads, +struct thread_map_event *event) +{ +unsigned i; + + threads->nr = (int ) event->nr; + +for (i =0 ; i < event->nr; i++) { +thread_map__set_pid (threads, i, (pid_t ) event->entries[i].pid); + threads->map[i].comm =strndup (event->entries[i].comm,16 ); + } + +atomic_set (&threads->refcnt,1 ); +} + +struct thread_map *thread_map__new_event (struct thread_map_event *event) +{ +struct thread_map *threads; + + threads =thread_map__alloc (event->nr); +if (threads) +thread_map__copy_event (threads, event); + +return threads; +}
tools/perf/util/thread_map.h +3 -0
@@ -16,11 +16,14 @@ struct thread_map {struct thread_map_data map[]; }; +struct thread_map_event ; +struct thread_map *thread_map__new_dummy (void );struct thread_map *thread_map__new_by_pid (pid_t pid);struct thread_map *thread_map__new_by_tid (pid_t tid);struct thread_map *thread_map__new_by_uid (uid_t uid);struct thread_map *thread_map__new (pid_t pid,pid_t tid,uid_t uid); +struct thread_map *thread_map__new_event (struct thread_map_event *event);struct thread_map *thread_map__get (struct thread_map *map);void thread_map__put (struct thread_map *map);
Jiri Olsa
reviewerPATCH v5 6/52 perf tools: Add perf_event__fprintf_thread_map function
In reply to Jiri OlsaTo display thread_map event for raw dump.
--- tools/perf/util/event.c | 16 ++++++++++++++++ tools/perf/util/event.h | 1 + 2 files changed, 17 insertions(+)
tools/perf/util/event.c +16 -0
@@ -820,6 +820,22 @@ size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) event->mmap2.filename); } +size_t perf_event__fprintf_thread_map (union perf_event *event,FILE *fp) +{ +struct thread_map *threads =thread_map__new_event (&event->thread_map); +size_t ret; + + ret =fprintf (fp," nr: " ); + +if (threads) + ret +=thread_map__fprintf (threads, fp); +else + ret +=fprintf (fp,"failed to get threads from event\n" ); + +thread_map__put (threads); +return ret; +} + int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample,
tools/perf/util/event.h +1 -0
@@ -516,6 +516,7 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp);size_t perf_event__fprintf_aux (union perf_event *event,FILE *fp);size_t perf_event__fprintf_itrace_start (union perf_event *event,FILE *fp);size_t perf_event__fprintf_switch (union perf_event *event,FILE *fp); +size_t perf_event__fprintf_thread_map (union perf_event *event,FILE *fp);size_t perf_event__fprintf (union perf_event *event,FILE *fp); u64 kallsyms__get_function_start(const char *kallsyms_filename,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf thread_map: Add perf_event__fprintf_thread_map function
perf thread_map: Add perf_event__fprintf_thread_map function
Commit-ID: ec7fa596f514b76a5f1003ffe9e6dfb50cb9e811 Gitweb: http://git.kernel.org/tip/ec7fa596f514b76a5f1003ffe9e6dfb50cb9e811 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:22 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:17 -0300
perf thread_map: Add perf_event__fprintf_thread_map function
To display a thread_map event for a raw dump.
--- tools/perf/util/event.c | 16 ++++++++++++++++ tools/perf/util/event.h | 1 + 2 files changed, 17 insertions(+)
tools/perf/util/event.c +16 -0
@@ -820,6 +820,22 @@ size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) event->mmap2.filename); } +size_t perf_event__fprintf_thread_map (union perf_event *event,FILE *fp) +{ +struct thread_map *threads =thread_map__new_event (&event->thread_map); +size_t ret; + + ret =fprintf (fp," nr: " ); + +if (threads) + ret +=thread_map__fprintf (threads, fp); +else + ret +=fprintf (fp,"failed to get threads from event\n" ); + +thread_map__put (threads); +return ret; +} + int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample,
tools/perf/util/event.h +1 -0
@@ -516,6 +516,7 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp);size_t perf_event__fprintf_aux (union perf_event *event,FILE *fp);size_t perf_event__fprintf_itrace_start (union perf_event *event,FILE *fp);size_t perf_event__fprintf_switch (union perf_event *event,FILE *fp); +size_t perf_event__fprintf_thread_map (union perf_event *event,FILE *fp);size_t perf_event__fprintf (union perf_event *event,FILE *fp); u64 kallsyms__get_function_start(const char *kallsyms_filename,
Jiri Olsa
reviewerPATCH v5 7/52 perf tools: Add cpu_map event
In reply to Jiri OlsaAdding cpu_map event to pass/store cpu maps as data in pipe/perf.data.
We store maps in 2 formats:
- list of cpus
- mask of cpus
The format that takes less space is selected transparently in following patch.
The interface is made generic, so we could add cpumap event data into another event in following patches.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 28 ++++++++++++++++++++++++++ tools/perf/util/session.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 81 insertions(+), 1 deletion(-)
tools/perf/util/event.c +1 -0
@@ -38,6 +38,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_AUXTRACE] = "AUXTRACE", [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", + [PERF_RECORD_CPU_MAP] = "CPU_MAP", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +28 -0
@@ -227,6 +227,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_AUXTRACE =71 ,PERF_RECORD_AUXTRACE_ERROR =72 ,PERF_RECORD_THREAD_MAP =73 , +PERF_RECORD_CPU_MAP =74 , PERF_RECORD_HEADER_MAX };
@@ -271,6 +272,32 @@ struct events_stats {u32 nr_proc_map_timeout; }; +enum { +PERF_CPU_MAP__CPUS =0 , +PERF_CPU_MAP__MASK =1 , +}; + +struct cpu_map_data_cpus { +u16 nr; +u16 cpu[]; +}; + +struct cpu_map_data_mask { +u16 nr; +u16 long_size; +unsigned long mask[]; +}; + +struct cpu_map_data { +u16 type; +char data[]; +}; + +struct cpu_map_event { +struct perf_event_header header; +struct cpu_map_data data; +}; +struct attr_event {struct perf_event_header header;struct perf_event_attr attr;
@@ -391,6 +418,7 @@ union perf_event {struct itrace_start_event itrace_start;struct context_switch_event context_switch;struct thread_map_event thread_map; +struct cpu_map_event cpu_map; };void perf_event__print_totals (void );
tools/perf/util/session.c +50 -0
80 lines not on this page · raw message
tools/perf/util/tool.h +2 -1
@@ -56,7 +56,8 @@ struct perf_tool { id_index, auxtrace_info, auxtrace_error, - thread_map; + thread_map, + cpu_map;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf cpu_map: Add cpu_map user level event
perf cpu_map: Add cpu_map user level event
Commit-ID: 6640b6c227fc85fd8bdcc4a31239a04450487f6a Gitweb: http://git.kernel.org/tip/6640b6c227fc85fd8bdcc4a31239a04450487f6a Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:23 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:17 -0300
perf cpu_map: Add cpu_map user level event
Adding the cpu_map event to pass/store cpu maps as data in a pipe/perf.data.
We store maps in 2 formats:
- list of cpus
- mask of cpus
The format that takes less space is selected transparently in the following patch.
The interface is made generic, so we could add the cpumap event data into another event in the following patches.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 28 ++++++++++++++++++++++++++ tools/perf/util/session.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 81 insertions(+), 1 deletion(-)
tools/perf/util/event.c +1 -0
@@ -38,6 +38,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_AUXTRACE] = "AUXTRACE", [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", + [PERF_RECORD_CPU_MAP] = "CPU_MAP", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +28 -0
@@ -227,6 +227,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_AUXTRACE =71 ,PERF_RECORD_AUXTRACE_ERROR =72 ,PERF_RECORD_THREAD_MAP =73 , +PERF_RECORD_CPU_MAP =74 , PERF_RECORD_HEADER_MAX };
@@ -271,6 +272,32 @@ struct events_stats {u32 nr_proc_map_timeout; }; +enum { +PERF_CPU_MAP__CPUS =0 , +PERF_CPU_MAP__MASK =1 , +}; + +struct cpu_map_entries { +u16 nr; +u16 cpu[]; +}; + +struct cpu_map_mask { +u16 nr; +u16 long_size; +unsigned long mask[]; +}; + +struct cpu_map_data { +u16 type; +char data[]; +}; + +struct cpu_map_event { +struct perf_event_header header; +struct cpu_map_data data; +}; +struct attr_event {struct perf_event_header header;struct perf_event_attr attr;
@@ -391,6 +418,7 @@ union perf_event {struct itrace_start_event itrace_start;struct context_switch_event context_switch;struct thread_map_event thread_map; +struct cpu_map_event cpu_map; };void perf_event__print_totals (void );
tools/perf/util/session.c +50 -0
80 lines not on this page · raw message
tools/perf/util/tool.h +2 -1
@@ -56,7 +56,8 @@ struct perf_tool { id_index, auxtrace_info, auxtrace_error, - thread_map; + thread_map, + cpu_map;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;
Jiri Olsa
reviewerPATCH v5 8/52 perf tools: Add cpu_map event synthesize function
In reply to Jiri OlsaIntroduce perf_event__synthesize_cpu_map function to synthesize struct cpu_map.
Added generic interface:
cpu_map_data__alloc
cpu_map_data__synthesize
to make the cpu_map synthesizing usable for other events.
--- tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 ++ tools/perf/tests/cpumap.c | 71 ++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/event.c | 131 ++++++++++++++++++++++++++++++++++++++++ tools/perf/util/event.h | 8 +++ 6 files changed, 216 insertions(+) create mode 100644 tools/perf/tests/cpumap.c
tools/perf/tests/Build +1 -0
@@ -33,6 +33,7 @@ perf-y += kmod-path.o perf-y += thread-map.o perf-y += llvm.o perf-y += topology.o +perf-y += cpumap.o ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64)) perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
tools/perf/tests/builtin-test.c +4 -0
@@ -170,6 +170,10 @@ static struct test generic_tests[] = { .func = test__thread_map_synthesize, }, { + .desc = "Test cpu map synthesize", + .func = test__cpu_map_synthesize, + }, + { .func = NULL, }, };
tools/perf/tests/cpumap.c new file +71 -0
71 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -68,6 +68,7 @@ int test__thread_map(void);int test__llvm (void );int test_session_topology (void );int test__thread_map_synthesize (void ); +int test__cpu_map_synthesize (void );#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/util/event.c +131 -0
137 lines not on this page · raw message
tools/perf/util/event.h +8 -0
@@ -425,6 +425,7 @@ void perf_event__print_totals(void);struct perf_tool ;struct thread_map ; +struct cpu_map ; typedef int (*perf_event__handler_t)(struct perf_tool *tool, union perf_event *event,
@@ -440,6 +441,10 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool,struct thread_map *threads, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_cpu_map (struct perf_tool *tool, +struct cpu_map *cpus, +perf_event__handler_t process, +struct machine *machine); int perf_event__synthesize_threads(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine, bool mmap_data,
@@ -550,4 +555,7 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp);u64 kallsyms__get_function_start (const char *kallsyms_filename,const char *symbol_name); +void *cpu_map_data__alloc (struct cpu_map *map,size_t *size,u16 *type,int *max); +void cpu_map_data__synthesize (struct cpu_map_data *data,struct cpu_map *map, +u16 type,int max);#endif /* __PERF_RECORD_H */
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf cpu_map: Add cpu_map event synthesize function
perf cpu_map: Add cpu_map event synthesize function
Commit-ID: 6c872901af07c41745f1abf5ceac9b3b4d9cdbb6 Gitweb: http://git.kernel.org/tip/6c872901af07c41745f1abf5ceac9b3b4d9cdbb6 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:24 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:18 -0300
perf cpu_map: Add cpu_map event synthesize function
Introduce the perf_event__synthesize_cpu_map function to synthesize a struct cpu_map.
Added generic interface:
cpu_map_data__alloc
cpu_map_data__synthesize
to make the cpu_map synthesizing usable for other events.
--- tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 ++ tools/perf/tests/cpumap.c | 71 ++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/event.c | 131 ++++++++++++++++++++++++++++++++++++++++ tools/perf/util/event.h | 8 +++ 6 files changed, 216 insertions(+)
tools/perf/tests/Build +1 -0
@@ -34,6 +34,7 @@ perf-y += thread-map.o perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o perf-y += bpf.o perf-y += topology.o +perf-y += cpumap.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir)
tools/perf/tests/builtin-test.c +4 -0
@@ -184,6 +184,10 @@ static struct test generic_tests[] = { .func = test__thread_map_synthesize, }, { + .desc = "Test cpu map synthesize", + .func = test__cpu_map_synthesize, + }, + { .func = NULL, }, };
tools/perf/tests/cpumap.c new file +71 -0
71 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -80,6 +80,7 @@ const char *test__bpf_subtest_get_desc(int subtest);int test__bpf_subtest_get_nr (void );int test_session_topology (int subtest);int test__thread_map_synthesize (int subtest); +int test__cpu_map_synthesize (int subtest);#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/util/event.c +131 -0
137 lines not on this page · raw message
tools/perf/util/event.h +8 -0
@@ -425,6 +425,7 @@ void perf_event__print_totals(void);struct perf_tool ;struct thread_map ; +struct cpu_map ; typedef int (*perf_event__handler_t)(struct perf_tool *tool, union perf_event *event,
@@ -440,6 +441,10 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool,struct thread_map *threads, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_cpu_map (struct perf_tool *tool, +struct cpu_map *cpus, +perf_event__handler_t process, +struct machine *machine); int perf_event__synthesize_threads(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine, bool mmap_data,
@@ -550,4 +555,7 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp);u64 kallsyms__get_function_start (const char *kallsyms_filename,const char *symbol_name); +void *cpu_map_data__alloc (struct cpu_map *map,size_t *size,u16 *type,int *max); +void cpu_map_data__synthesize (struct cpu_map_data *data,struct cpu_map *map, +u16 type,int max);#endif /* __PERF_RECORD_H */
Jiri Olsa
reviewerPATCH v5 9/52 perf tools: Add cpu_map__new_event function
In reply to Jiri OlsaIntroducing cpu_map__new_event function to create
struct cpu_map object from cpu_map event.
--- tools/perf/tests/cpumap.c | 25 +++++++++++++++++++++---- tools/perf/util/cpumap.c | 42 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/cpumap.h | 1 + 3 files changed, 64 insertions(+), 4 deletions(-)
tools/perf/tests/cpumap.c +21 -4
@@ -6,12 +6,13 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused,struct perf_sample *sample__maybe_unused , struct machine *machine __maybe_unused) { - struct cpu_map_event *map = &event->cpu_map; + struct cpu_map_event *map_event = &event->cpu_map;struct cpu_map_data_mask *mask;struct cpu_map_data *data; +struct cpu_map *map;int i; - data = &map->data; + data = &map_event->data;TEST_ASSERT_VAL ("wrong type" , data->type ==PERF_CPU_MAP__MASK );
@@ -23,6 +24,14 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused,TEST_ASSERT_VAL ("wrong cpu" ,test_bit (i, mask->mask)); } + map =cpu_map__new_data (data); +TEST_ASSERT_VAL ("wrong nr" , map->nr ==20 ); + +for (i =0 ; i <20 ; i++) { +TEST_ASSERT_VAL ("wrong cpu" , map->map[i] == i); + } + +cpu_map__put (map);return 0 ; }
@@ -31,11 +40,12 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,struct perf_sample *sample__maybe_unused , struct machine *machine __maybe_unused) { - struct cpu_map_event *map = &event->cpu_map; + struct cpu_map_event *map_event = &event->cpu_map;struct cpu_map_data_cpus *cpus;struct cpu_map_data *data; +struct cpu_map *map; - data = &map->data; + data = &map_event->data;TEST_ASSERT_VAL ("wrong type" , data->type ==PERF_CPU_MAP__CPUS );
@@ -44,6 +54,13 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,TEST_ASSERT_VAL ("wrong nr" , cpus->nr ==2 );TEST_ASSERT_VAL ("wrong cpu" , cpus->cpu[0 ] ==1 );TEST_ASSERT_VAL ("wrong cpu" , cpus->cpu[1 ] ==256 ); + + map =cpu_map__new_data (data); +TEST_ASSERT_VAL ("wrong nr" , map->nr ==2 ); +TEST_ASSERT_VAL ("wrong cpu" , map->map[0 ] ==1 ); +TEST_ASSERT_VAL ("wrong cpu" , map->map[1 ] ==256 ); +TEST_ASSERT_VAL ("wrong refcnt" ,atomic_read (&map->refcnt) ==1 ); +cpu_map__put (map);return 0 ; }
tools/perf/util/cpumap.c +42 -0
54 lines not on this page · raw message
tools/perf/util/cpumap.h +1 -0
@@ -17,6 +17,7 @@ struct cpu_map {struct cpu_map *cpu_map__new (const char *cpu_list);struct cpu_map *cpu_map__empty_new (int nr);struct cpu_map *cpu_map__dummy_new (void ); +struct cpu_map *cpu_map__new_data (struct cpu_map_data *data);struct cpu_map *cpu_map__read (FILE *file);size_t cpu_map__fprintf (struct cpu_map *map,FILE *fp);int cpu_map__get_socket_id (int cpu);
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf cpu_map: Add cpu_map__new_event function
perf cpu_map: Add cpu_map__new_event function
Commit-ID: f77b57ad4fc42a074eae564bbb6660f0a3ff5503 Gitweb: http://git.kernel.org/tip/f77b57ad4fc42a074eae564bbb6660f0a3ff5503 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:25 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:18 -0300
perf cpu_map: Add cpu_map__new_event function
Introducing the cpu_map__new_event function to create a struct cpu_map object from a cpu_map event.
--- tools/perf/tests/cpumap.c | 25 +++++++++++++++++++++---- tools/perf/util/cpumap.c | 42 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/cpumap.h | 1 + 3 files changed, 64 insertions(+), 4 deletions(-)
tools/perf/tests/cpumap.c +21 -4
@@ -6,12 +6,13 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused,struct perf_sample *sample__maybe_unused , struct machine *machine __maybe_unused) { - struct cpu_map_event *map = &event->cpu_map; + struct cpu_map_event *map_event = &event->cpu_map;struct cpu_map_mask *mask;struct cpu_map_data *data; +struct cpu_map *map;int i; - data = &map->data; + data = &map_event->data;TEST_ASSERT_VAL ("wrong type" , data->type ==PERF_CPU_MAP__MASK );
@@ -23,6 +24,14 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused,TEST_ASSERT_VAL ("wrong cpu" ,test_bit (i, mask->mask)); } + map =cpu_map__new_data (data); +TEST_ASSERT_VAL ("wrong nr" , map->nr ==20 ); + +for (i =0 ; i <20 ; i++) { +TEST_ASSERT_VAL ("wrong cpu" , map->map[i] == i); + } + +cpu_map__put (map);return 0 ; }
@@ -31,11 +40,12 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,struct perf_sample *sample__maybe_unused , struct machine *machine __maybe_unused) { - struct cpu_map_event *map = &event->cpu_map; + struct cpu_map_event *map_event = &event->cpu_map;struct cpu_map_entries *cpus;struct cpu_map_data *data; +struct cpu_map *map; - data = &map->data; + data = &map_event->data;TEST_ASSERT_VAL ("wrong type" , data->type ==PERF_CPU_MAP__CPUS );
@@ -44,6 +54,13 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,TEST_ASSERT_VAL ("wrong nr" , cpus->nr ==2 );TEST_ASSERT_VAL ("wrong cpu" , cpus->cpu[0 ] ==1 );TEST_ASSERT_VAL ("wrong cpu" , cpus->cpu[1 ] ==256 ); + + map =cpu_map__new_data (data); +TEST_ASSERT_VAL ("wrong nr" , map->nr ==2 ); +TEST_ASSERT_VAL ("wrong cpu" , map->map[0 ] ==1 ); +TEST_ASSERT_VAL ("wrong cpu" , map->map[1 ] ==256 ); +TEST_ASSERT_VAL ("wrong refcnt" ,atomic_read (&map->refcnt) ==1 ); +cpu_map__put (map);return 0 ; }
tools/perf/util/cpumap.c +42 -0
54 lines not on this page · raw message
tools/perf/util/cpumap.h +1 -0
@@ -17,6 +17,7 @@ struct cpu_map {struct cpu_map *cpu_map__new (const char *cpu_list);struct cpu_map *cpu_map__empty_new (int nr);struct cpu_map *cpu_map__dummy_new (void ); +struct cpu_map *cpu_map__new_data (struct cpu_map_data *data);struct cpu_map *cpu_map__read (FILE *file);size_t cpu_map__fprintf (struct cpu_map *map,FILE *fp);int cpu_map__get_socket_id (int cpu);
Jiri Olsa
reviewerPATCH v5 10/52 perf tools: Add perf_event__fprintf_cpu_map function
In reply to Jiri OlsaTo display cpu_map event for raw dump.
--- tools/perf/util/event.c | 16 ++++++++++++++++ tools/perf/util/event.h | 1 + 2 files changed, 17 insertions(+)
tools/perf/util/event.c +16 -0
@@ -968,6 +968,22 @@ size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp)return ret; } +size_t perf_event__fprintf_cpu_map (union perf_event *event,FILE *fp) +{ +struct cpu_map *cpus =cpu_map__new_data (&event->cpu_map.data); +size_t ret; + + ret =fprintf (fp," nr: " ); + +if (cpus) + ret +=cpu_map__fprintf (cpus, fp); +else + ret +=fprintf (fp,"failed to get cpumap from event\n" ); + +cpu_map__put (cpus); +return ret; +} + int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample,
tools/perf/util/event.h +1 -0
@@ -550,6 +550,7 @@ size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp);size_t perf_event__fprintf_itrace_start (union perf_event *event,FILE *fp);size_t perf_event__fprintf_switch (union perf_event *event,FILE *fp);size_t perf_event__fprintf_thread_map (union perf_event *event,FILE *fp); +size_t perf_event__fprintf_cpu_map (union perf_event *event,FILE *fp);size_t perf_event__fprintf (union perf_event *event,FILE *fp); u64 kallsyms__get_function_start(const char *kallsyms_filename,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf cpu_map: Add perf_event__fprintf_cpu_map function
perf cpu_map: Add perf_event__fprintf_cpu_map function
Commit-ID: eb12a1afdc02e59fc09934743490549c77327b1a Gitweb: http://git.kernel.org/tip/eb12a1afdc02e59fc09934743490549c77327b1a Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:26 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:18 -0300
perf cpu_map: Add perf_event__fprintf_cpu_map function
To display a cpu_map event for raw dump.
--- tools/perf/util/event.c | 16 ++++++++++++++++ tools/perf/util/event.h | 1 + 2 files changed, 17 insertions(+)
tools/perf/util/event.c +16 -0
@@ -968,6 +968,22 @@ size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp)return ret; } +size_t perf_event__fprintf_cpu_map (union perf_event *event,FILE *fp) +{ +struct cpu_map *cpus =cpu_map__new_data (&event->cpu_map.data); +size_t ret; + + ret =fprintf (fp," nr: " ); + +if (cpus) + ret +=cpu_map__fprintf (cpus, fp); +else + ret +=fprintf (fp,"failed to get cpumap from event\n" ); + +cpu_map__put (cpus); +return ret; +} + int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample,
tools/perf/util/event.h +1 -0
@@ -550,6 +550,7 @@ size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp);size_t perf_event__fprintf_itrace_start (union perf_event *event,FILE *fp);size_t perf_event__fprintf_switch (union perf_event *event,FILE *fp);size_t perf_event__fprintf_thread_map (union perf_event *event,FILE *fp); +size_t perf_event__fprintf_cpu_map (union perf_event *event,FILE *fp);size_t perf_event__fprintf (union perf_event *event,FILE *fp); u64 kallsyms__get_function_start(const char *kallsyms_filename,
Jiri Olsa
reviewerPATCH v5 11/52 perf tools: Add stat config event
In reply to Jiri OlsaAdding stat config event to pass/store stat config data, so report tools (report/script) know how to interpret stat data.
The config data are stored in 'tag|value' way to allow easy extension and backward compatibility.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 20 ++++++++++++++++++++ tools/perf/util/session.c | 24 ++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 47 insertions(+), 1 deletion(-)
tools/perf/util/event.c +1 -0
@@ -39,6 +39,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", [PERF_RECORD_CPU_MAP] = "CPU_MAP", + [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +20 -0
@@ -228,6 +228,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_AUXTRACE_ERROR =72 ,PERF_RECORD_THREAD_MAP =73 ,PERF_RECORD_CPU_MAP =74 , +PERF_RECORD_STAT_CONFIG =75 , PERF_RECORD_HEADER_MAX };
@@ -395,6 +396,24 @@ struct thread_map_event {struct thread_map_data_event data[]; }; +enum { +PERF_STAT_CONFIG_TERM__AGGR_MODE =0 , +PERF_STAT_CONFIG_TERM__INTERVAL =1 , +PERF_STAT_CONFIG_TERM__SCALE =2 , +PERF_STAT_CONFIG_TERM__MAX =3 , +}; + +struct stat_config_term_event { +u64 tag; +u64 val; +}; + +struct stat_config_event { +struct perf_event_header header; +u64 nr; +struct stat_config_term_event data[]; +}; +union perf_event {struct perf_event_header header;struct mmap_event mmap;
@@ -419,6 +438,7 @@ union perf_event {struct context_switch_event context_switch;struct thread_map_event thread_map;struct cpu_map_event cpu_map; +struct stat_config_event stat_config; };void perf_event__print_totals (void );
tools/perf/util/session.c +24 -0
@@ -315,6 +315,15 @@ int process_event_cpu_map_stub(struct perf_tool *tool __maybe_unused,return 0 ; } +static +int process_event_stat_config_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_session *session__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} +void perf_tool__fill_defaults (struct perf_tool *tool) {if (tool->sample ==NULL )
@@ -369,6 +378,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->thread_map = process_event_thread_map_stub;if (tool->cpu_map ==NULL ) tool->cpu_map = process_event_cpu_map_stub; +if (tool->stat_config ==NULL ) + tool->stat_config = process_event_stat_config_stub; }static void swap_sample_id_all (union perf_event *event,void *data)
@@ -686,6 +697,16 @@ static void perf_event__cpu_map_swap(union perf_event *event, } } +static void perf_event__stat_config_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ +u64 size; + + size = event->stat_config.nr *sizeof (event->stat_config.data[0 ]); + size +=1 ;/* nr item itself */ +mem_bswap_64 (&event->stat_config.nr, size); +} +typedef void (*perf_event__swap_op )(union perf_event *event,bool sample_id_all);
@@ -715,6 +736,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_AUXTRACE_ERROR] = perf_event__auxtrace_error_swap, [PERF_RECORD_THREAD_MAP] = perf_event__thread_map_swap, [PERF_RECORD_CPU_MAP] = perf_event__cpu_map_swap, + [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap, [PERF_RECORD_HEADER_MAX] = NULL, };
@@ -1255,6 +1277,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,return tool->thread_map (tool, event, session);case PERF_RECORD_CPU_MAP :return tool->cpu_map (tool, event, session); +case PERF_RECORD_STAT_CONFIG : +return tool->stat_config (tool, event, session);default :return -EINVAL ; }
tools/perf/util/tool.h +2 -1
@@ -57,7 +57,8 @@ struct perf_tool { auxtrace_info, auxtrace_error, thread_map, - cpu_map; + cpu_map, + stat_config;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;
Signature · 1 line
2.4.3
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 11/52] perf tools: Add stat config event
Em Sun, Oct 25, 2015 at 03:51:27PM +0100, Jiri Olsa escreveu:
Quoted 6 lines
Adding stat config event to pass/store stat config data, so report tools (report/script) know how to interpret stat data.
The config data are stored in 'tag|value' way to allow easy extension and backward compatibility.
I wonder if this couldn't be renamed 'PERF_RECORD_CONFIG' and just go on using one of those 2^64-1 tags for the 'stat config' needs, but then this is just a matter of changing the name of this event, which won't break anything when done.
Other stuff we may want to have stored like this include sysctl, sysfs values, kernel command line options used, etc.
- Arnaldo
Quoted 145 lines
Signed-off-by Jiri Olsa <[email protected]>--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 20 ++++++++++++++++++++ tools/perf/util/session.c | 24 ++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 47 insertions(+), 1 deletion(-)tools/perf/util/event.c +1
-0@@ -39,6 +39,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", [PERF_RECORD_CPU_MAP] = "CPU_MAP", + [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", };const char *perf_event__name (unsigned int id)tools/perf/util/event.h +20
-0@@ -228,6 +228,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_AUXTRACE_ERROR =72 ,PERF_RECORD_THREAD_MAP =73 ,PERF_RECORD_CPU_MAP =74 , +PERF_RECORD_STAT_CONFIG =75 , PERF_RECORD_HEADER_MAX };@@ -395,6 +396,24 @@ struct thread_map_event {struct thread_map_data_event data[]; }; +enum { +PERF_STAT_CONFIG_TERM__AGGR_MODE =0 , +PERF_STAT_CONFIG_TERM__INTERVAL =1 , +PERF_STAT_CONFIG_TERM__SCALE =2 , +PERF_STAT_CONFIG_TERM__MAX =3 , +}; + +struct stat_config_term_event { +u64 tag; +u64 val; +}; + +struct stat_config_event { +struct perf_event_header header; +u64 nr; +struct stat_config_term_event data[]; +}; +union perf_event {struct perf_event_header header;struct mmap_event mmap;@@ -419,6 +438,7 @@ union perf_event {struct context_switch_event context_switch;struct thread_map_event thread_map;struct cpu_map_event cpu_map; +struct stat_config_event stat_config; };void perf_event__print_totals (void );tools/perf/util/session.c +24
-0@@ -315,6 +315,15 @@ int process_event_cpu_map_stub(struct perf_tool *tool __maybe_unused,return 0 ; } +static +int process_event_stat_config_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_session *session__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} +void perf_tool__fill_defaults (struct perf_tool *tool) {if (tool->sample ==NULL )@@ -369,6 +378,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->thread_map = process_event_thread_map_stub;if (tool->cpu_map ==NULL ) tool->cpu_map = process_event_cpu_map_stub; +if (tool->stat_config ==NULL ) + tool->stat_config = process_event_stat_config_stub; }static void swap_sample_id_all (union perf_event *event,void *data)@@ -686,6 +697,16 @@ static void perf_event__cpu_map_swap(union perf_event *event, } } +static void perf_event__stat_config_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ +u64 size; + + size = event->stat_config.nr *sizeof (event->stat_config.data[0 ]); + size +=1 ;/* nr item itself */ +mem_bswap_64 (&event->stat_config.nr, size); +} +typedef void (*perf_event__swap_op )(union perf_event *event,bool sample_id_all);@@ -715,6 +736,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_AUXTRACE_ERROR] = perf_event__auxtrace_error_swap, [PERF_RECORD_THREAD_MAP] = perf_event__thread_map_swap, [PERF_RECORD_CPU_MAP] = perf_event__cpu_map_swap, + [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap, [PERF_RECORD_HEADER_MAX] = NULL, };@@ -1255,6 +1277,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,return tool->thread_map (tool, event, session);case PERF_RECORD_CPU_MAP :return tool->cpu_map (tool, event, session); +case PERF_RECORD_STAT_CONFIG : +return tool->stat_config (tool, event, session);default :return -EINVAL ; }tools/perf/util/tool.h +2
-1@@ -57,7 +57,8 @@ struct perf_tool { auxtrace_info, auxtrace_error, thread_map, - cpu_map; + cpu_map, + stat_config;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;Signature · 1 line
2.4.3
Re: [PATCH 11/52] perf tools: Add stat config event
Quoted 5 lines · Arnaldo Carvalho de Melo
Em Sun, Oct 25, 2015 at 03:51:27PM +0100, Jiri Olsa escreveu:
Quoted 4 lines
Adding stat config event to pass/store stat config data, so report tools (report/script) know how to interpret stat data.
Quoted 7 lines
Quoted 2 lines
The config data are stored in 'tag|value' way to allow easy extension and backward compatibility.
I wonder if this couldn't be renamed '
PERF_RECORD_CONFIG' and just go on using one of those 2^64-1 tags for the 'stat config' needs, but then this is just a matter of changing the name of this event, which won't break anything when done.
we use this event to update 'struct perf_stat_config', so it's kind of stat specific
Quoted 3 lines
Other stuff we may want to have stored like this include sysctl, sysfs values, kernel command line options used, etc.
I think we could easily add record specific event for this once it's needed.. there's plenty of free numbers in user events area ;-)
jirka
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 11/52] perf tools: Add stat config event
Em Tue, Oct 27, 2015 at 02:30:43PM +0100, Jiri Olsa escreveu:
Quoted 9 lines · Arnaldo Carvalho de Melo
Quoted 8 lines
Em Sun, Oct 25, 2015 at 03:51:27PM +0100, Jiri Olsa escreveu:
Quoted 6 lines
Adding stat config event to pass/store stat config data, so report tools (report/script) know how to interpret stat data.
The config data are stored in 'tag|value' way to allow easy extension and backward compatibility.
Quoted 7 lines
Quoted 4 lines
I wonder if this couldn't be renamed '
PERF_RECORD_CONFIG' and just go on using one of those 2^64-1 tags for the 'stat config' needs, but then this is just a matter of changing the name of this event, which won't break anything when done.we use this event to update 'struct
perf_stat_config', so it's kind of stat specific
What makes it specific? Isn't this just tag/value? If it was generic all it would take would be for us to register a range of values (or several) to be handled by the stat config reading routine.
Quoted 6 lines
Quoted 2 lines
Other stuff we may want to have stored like this include sysctl, sysfs values, kernel command line options used, etc.
I think we could easily add record specific event for this once it's needed.. there's plenty of free numbers in user events area ;-)
Shhh, don't ask PeterZ about it ;-)
But seriously, what makes this specific? Do you envision the stat code needing 2^64-1 tags?
Anyway, we can revisit this when code needing to store tag/value appears.
- Arnaldo
Re: [PATCH 11/52] perf tools: Add stat config event
Quoted 25 lines · Arnaldo Carvalho de Melo
Em Tue, Oct 27, 2015 at 02:30:43PM +0100, Jiri Olsa escreveu:
Quoted 9 lines · Arnaldo Carvalho de Melo
Quoted 8 lines
Em Sun, Oct 25, 2015 at 03:51:27PM +0100, Jiri Olsa escreveu:
Quoted 6 lines
Adding stat config event to pass/store stat config data, so report tools (report/script) know how to interpret stat data.
The config data are stored in 'tag|value' way to allow easy extension and backward compatibility.
Quoted 7 lines
Quoted 4 lines
I wonder if this couldn't be renamed '
PERF_RECORD_CONFIG' and just go on using one of those 2^64-1 tags for the 'stat config' needs, but then this is just a matter of changing the name of this event, which won't break anything when done.we use this event to update 'struct
perf_stat_config', so it's kind of stat specificWhat makes it specific? Isn't this just tag/value? If it was generic all it would take would be for us to register a range of values (or several) to be handled by the stat config reading routine.
Quoted 3 lines
Quoted 2 lines
Other stuff we may want to have stored like this include sysctl, sysfs values, kernel command line options used, etc.
Quoted 8 lines
Quoted 3 lines
I think we could easily add record specific event for this once it's needed.. there's plenty of free numbers in user events area ;-)
Shhh, don't ask PeterZ about it ;-)
But seriously, what makes this specific? Do you envision the stat code needing 2^64-1 tags?
nope ;-)
it's just the read function perf_event__read_stat_config takes the 'struct perf_stat_config *' and updates it based on the event data.
we would need to change the code to be more generic.. but as you said, it's future ;-)
jirka
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 11/52] perf tools: Add stat config event
Em Tue, Oct 27, 2015 at 02:51:54PM +0100, Jiri Olsa escreveu:
Quoted 10 lines · Arnaldo Carvalho de Melo
Quoted 8 lines
Quoted 3 lines
I think we could easily add record specific event for this once it's needed.. there's plenty of free numbers in user events area ;-)
Shhh, don't ask PeterZ about it ;-)
But seriously, what makes this specific? Do you envision the stat code needing 2^64-1 tags?
Quoted 7 lines
nope ;-)
it's just the read function
perf_event__read_stat_configtakes the 'structperf_stat_config*' and updates it based on the event data.we would need to change the code to be more generic.. but as you said, it's future ;-)
Right, I applied the patch, I was just curious if I was missing some detail that would prevent us from using this as a generic tag/value perf.data storing facility.
- Arnaldo
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add stat config user level event
In reply to Jiri Olsaperf tools: Add stat config user level event
Commit-ID: 374fb9e362f64e730388abc1de9bb93829670a54 Gitweb: http://git.kernel.org/tip/374fb9e362f64e730388abc1de9bb93829670a54 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:27 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:18 -0300
perf tools: Add stat config user level event
Adding the stat config event to pass/store stat config data, so report tools (report/script) know how to interpret stat data.
The config data is stored in a 'tag|value' way to allow for easy extension and backwards compatibility.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 20 ++++++++++++++++++++ tools/perf/util/session.c | 24 ++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 47 insertions(+), 1 deletion(-)
tools/perf/util/event.c +1 -0
@@ -39,6 +39,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", [PERF_RECORD_CPU_MAP] = "CPU_MAP", + [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +20 -0
@@ -228,6 +228,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_AUXTRACE_ERROR =72 ,PERF_RECORD_THREAD_MAP =73 ,PERF_RECORD_CPU_MAP =74 , +PERF_RECORD_STAT_CONFIG =75 , PERF_RECORD_HEADER_MAX };
@@ -395,6 +396,24 @@ struct thread_map_event {struct thread_map_event_entry entries[]; }; +enum { +PERF_STAT_CONFIG_TERM__AGGR_MODE =0 , +PERF_STAT_CONFIG_TERM__INTERVAL =1 , +PERF_STAT_CONFIG_TERM__SCALE =2 , +PERF_STAT_CONFIG_TERM__MAX =3 , +}; + +struct stat_config_event_entry { +u64 tag; +u64 val; +}; + +struct stat_config_event { +struct perf_event_header header; +u64 nr; +struct stat_config_event_entry data[]; +}; +union perf_event {struct perf_event_header header;struct mmap_event mmap;
@@ -419,6 +438,7 @@ union perf_event {struct context_switch_event context_switch;struct thread_map_event thread_map;struct cpu_map_event cpu_map; +struct stat_config_event stat_config; };void perf_event__print_totals (void );
tools/perf/util/session.c +24 -0
@@ -315,6 +315,15 @@ int process_event_cpu_map_stub(struct perf_tool *tool __maybe_unused,return 0 ; } +static +int process_event_stat_config_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_session *session__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} +void perf_tool__fill_defaults (struct perf_tool *tool) {if (tool->sample ==NULL )
@@ -369,6 +378,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->thread_map = process_event_thread_map_stub;if (tool->cpu_map ==NULL ) tool->cpu_map = process_event_cpu_map_stub; +if (tool->stat_config ==NULL ) + tool->stat_config = process_event_stat_config_stub; }static void swap_sample_id_all (union perf_event *event,void *data)
@@ -686,6 +697,16 @@ static void perf_event__cpu_map_swap(union perf_event *event, } } +static void perf_event__stat_config_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ +u64 size; + + size = event->stat_config.nr *sizeof (event->stat_config.data[0 ]); + size +=1 ;/* nr item itself */ +mem_bswap_64 (&event->stat_config.nr, size); +} +typedef void (*perf_event__swap_op )(union perf_event *event,bool sample_id_all);
@@ -715,6 +736,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_AUXTRACE_ERROR] = perf_event__auxtrace_error_swap, [PERF_RECORD_THREAD_MAP] = perf_event__thread_map_swap, [PERF_RECORD_CPU_MAP] = perf_event__cpu_map_swap, + [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap, [PERF_RECORD_HEADER_MAX] = NULL, };
@@ -1255,6 +1277,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,return tool->thread_map (tool, event, session);case PERF_RECORD_CPU_MAP :return tool->cpu_map (tool, event, session); +case PERF_RECORD_STAT_CONFIG : +return tool->stat_config (tool, event, session);default :return -EINVAL ; }
tools/perf/util/tool.h +2 -1
@@ -57,7 +57,8 @@ struct perf_tool { auxtrace_info, auxtrace_error, thread_map, - cpu_map; + cpu_map, + stat_config;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;
Jiri Olsa
reviewerPATCH v5 12/52 perf tools: Add stat config event synthesize function
In reply to Jiri OlsaIntroduce perf_event__synthesize_stat_config function to synthesize 'struct perf_stat_config'.
Storing stat config in form of tag-value pairs in a believe it'll sort out future version issues.
--- tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/stat.c | 53 +++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/event.c | 40 +++++++++++++++++++++++++++++++ tools/perf/util/event.h | 5 ++++ 6 files changed, 104 insertions(+) create mode 100644 tools/perf/tests/stat.c
tools/perf/tests/Build +1 -0
@@ -34,6 +34,7 @@ perf-y += thread-map.o perf-y += llvm.o perf-y += topology.o perf-y += cpumap.o +perf-y += stat.o ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64)) perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
tools/perf/tests/builtin-test.c +4 -0
@@ -174,6 +174,10 @@ static struct test generic_tests[] = { .func = test__cpu_map_synthesize, }, { + .desc = "Test stat config synthesize", + .func = test__synthesize_stat_config, + }, + { .func = NULL, }, };
tools/perf/tests/stat.c new file +53 -0
53 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -69,6 +69,7 @@ int test__llvm(void);int test_session_topology (void );int test__thread_map_synthesize (void );int test__cpu_map_synthesize (void ); +int test__synthesize_stat_config (void );#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/util/event.c +40 -0
@@ -10,6 +10,8 @@#include "thread.h" #include "thread_map.h" #include "symbol/kallsyms.h" +#include "asm/bug.h" +#include "stat.h" static const char *perf_event__names[] = { [0 ] ="TOTAL" ,
@@ -869,6 +871,44 @@ int perf_event__synthesize_cpu_map(struct perf_tool *tool,return err; } +int perf_event__synthesize_stat_config (struct perf_tool *tool, +struct perf_stat_config *config, +perf_event__handler_t process, +struct machine *machine) +{ +struct stat_config_event *event; +int size, i =0 , err; + + size =sizeof (*event); + size += (PERF_STAT_CONFIG_TERM__MAX *sizeof (event->data[0 ])); + + event =zalloc (size); +if (!event) +return -ENOMEM ; + + event->header.type =PERF_RECORD_STAT_CONFIG ; + event->header.size = size; + event->nr =PERF_STAT_CONFIG_TERM__MAX ; + +#define ADD (__term, __val) \ + event->data[i].tag = PERF_STAT_CONFIG_TERM__##__term; \ + event->data[i].val = __val; \ + i++; + + ADD(AGGR_MODE, config->aggr_mode) + ADD(INTERVAL, config->interval) + ADD(SCALE, config->scale) + +WARN_ONCE (i !=PERF_STAT_CONFIG_TERM__MAX , +"stat config terms unbalanced\n" ); +#undef ADD + + err =process (tool, (union perf_event *) event,NULL , machine); + +free (event); +return err; +} +size_t perf_event__fprintf_comm (union perf_event *event,FILE *fp) {const char *s;
tools/perf/util/event.h +5 -0
@@ -446,6 +446,7 @@ void perf_event__print_totals(void);struct perf_tool ;struct thread_map ;struct cpu_map ; +struct perf_stat_config ; typedef int (*perf_event__handler_t)(struct perf_tool *tool, union perf_event *event,
@@ -472,6 +473,10 @@ int perf_event__synthesize_threads(struct perf_tool *tool,int perf_event__synthesize_kernel_mmap (struct perf_tool *tool,perf_event__handler_t process,struct machine *machine); +int perf_event__synthesize_stat_config (struct perf_tool *tool, +struct perf_stat_config *config, +perf_event__handler_t process, +struct machine *machine); int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t process,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add stat config event synthesize function
perf tools: Add stat config event synthesize function
Commit-ID: 6742434261158ad9678bf15b165304e0200cc324 Gitweb: http://git.kernel.org/tip/6742434261158ad9678bf15b165304e0200cc324 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:28 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:19 -0300
perf tools: Add stat config event synthesize function
Introduce the perf_event__synthesize_stat_config to synthesize a 'struct perf_stat_config'.
Storing the stat config in the form of tag-value pairs will, I believe, sort out future version extensibility issues.
--- tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/stat.c | 53 +++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/event.c | 40 +++++++++++++++++++++++++++++++ tools/perf/util/event.h | 5 ++++ 6 files changed, 104 insertions(+)
tools/perf/tests/Build +1 -0
@@ -35,6 +35,7 @@ perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o perf-y += bpf.o perf-y += topology.o perf-y += cpumap.o +perf-y += stat.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir)
tools/perf/tests/builtin-test.c +4 -0
@@ -188,6 +188,10 @@ static struct test generic_tests[] = { .func = test__cpu_map_synthesize, }, { + .desc = "Test stat config synthesize", + .func = test__synthesize_stat_config, + }, + { .func = NULL, }, };
tools/perf/tests/stat.c new file +53 -0
53 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -81,6 +81,7 @@ int test__bpf_subtest_get_nr(void);int test_session_topology (int subtest);int test__thread_map_synthesize (int subtest);int test__cpu_map_synthesize (int subtest); +int test__synthesize_stat_config (int subtest);#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/util/event.c +40 -0
@@ -10,6 +10,8 @@#include "thread.h" #include "thread_map.h" #include "symbol/kallsyms.h" +#include "asm/bug.h" +#include "stat.h" static const char *perf_event__names[] = { [0 ] ="TOTAL" ,
@@ -869,6 +871,44 @@ int perf_event__synthesize_cpu_map(struct perf_tool *tool,return err; } +int perf_event__synthesize_stat_config (struct perf_tool *tool, +struct perf_stat_config *config, +perf_event__handler_t process, +struct machine *machine) +{ +struct stat_config_event *event; +int size, i =0 , err; + + size =sizeof (*event); + size += (PERF_STAT_CONFIG_TERM__MAX *sizeof (event->data[0 ])); + + event =zalloc (size); +if (!event) +return -ENOMEM ; + + event->header.type =PERF_RECORD_STAT_CONFIG ; + event->header.size = size; + event->nr =PERF_STAT_CONFIG_TERM__MAX ; + +#define ADD (__term, __val) \ + event->data[i].tag = PERF_STAT_CONFIG_TERM__##__term; \ + event->data[i].val = __val; \ + i++; + + ADD(AGGR_MODE, config->aggr_mode) + ADD(INTERVAL, config->interval) + ADD(SCALE, config->scale) + +WARN_ONCE (i !=PERF_STAT_CONFIG_TERM__MAX , +"stat config terms unbalanced\n" ); +#undef ADD + + err =process (tool, (union perf_event *) event,NULL , machine); + +free (event); +return err; +} +size_t perf_event__fprintf_comm (union perf_event *event,FILE *fp) {const char *s;
tools/perf/util/event.h +5 -0
@@ -446,6 +446,7 @@ void perf_event__print_totals(void);struct perf_tool ;struct thread_map ;struct cpu_map ; +struct perf_stat_config ; typedef int (*perf_event__handler_t)(struct perf_tool *tool, union perf_event *event,
@@ -472,6 +473,10 @@ int perf_event__synthesize_threads(struct perf_tool *tool,int perf_event__synthesize_kernel_mmap (struct perf_tool *tool,perf_event__handler_t process,struct machine *machine); +int perf_event__synthesize_stat_config (struct perf_tool *tool, +struct perf_stat_config *config, +perf_event__handler_t process, +struct machine *machine); int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t process,
Jiri Olsa
reviewerPATCH v5 13/52 perf tools: Add stat config event read function
In reply to Jiri OlsaIntroducing perf_event__read_stat_config function to read struct perf_stat_config object data from stat config event.
--- tools/perf/tests/stat.c | 6 ++++++ tools/perf/util/event.c | 24 ++++++++++++++++++++++++ tools/perf/util/event.h | 2 ++ 3 files changed, 32 insertions(+)
tools/perf/tests/stat.c +6 -0
@@ -24,6 +24,7 @@ static int process_event(struct perf_tool *tool __maybe_unused, struct machine *machine __maybe_unused) {struct stat_config_event *config = &event->stat_config; +struct perf_stat_config stat_config;#define HAS (term, val) \ has_term(config, PERF_STAT_CONFIG_TERM__##term, val)
@@ -35,6 +36,11 @@ static int process_event(struct perf_tool *tool __maybe_unused,#undef HAS +perf_event__read_stat_config (&stat_config, config); + +TEST_ASSERT_VAL ("wrong aggr_mode" , stat_config.aggr_mode ==AGGR_CORE ); +TEST_ASSERT_VAL ("wrong scale" , stat_config.scale ==1 ); +TEST_ASSERT_VAL ("wrong interval" , stat_config.interval ==1 );return 0 ; }
tools/perf/util/event.c +24 -0
@@ -909,6 +909,30 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool,return err; } +void perf_event__read_stat_config (struct perf_stat_config *config, +struct stat_config_event *event) +{ +unsigned i; + +for (i =0 ; i < event->nr; i++) { + +switch (event->data[i].tag) { +#define CASE (__term, __val) \ + case PERF_STAT_CONFIG_TERM__##__term: \ + config->__val = event->data[i].val; \ + break; + + CASE(AGGR_MODE, aggr_mode) + CASE(SCALE, scale) + CASE(INTERVAL, interval) +#undef CASE +default : +pr_warning ("unknown stat config term %" PRIu64"\n" , + event->data[i].tag); + } + } +} +size_t perf_event__fprintf_comm (union perf_event *event,FILE *fp) {const char *s;
tools/perf/util/event.h +2 -0
@@ -477,6 +477,8 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool,struct perf_stat_config *config, perf_event__handler_t process, struct machine *machine); +void perf_event__read_stat_config (struct perf_stat_config *config, +struct stat_config_event *event); int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t process,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add stat config event read function
perf tools: Add stat config event read function
Commit-ID: 8e381596b67af53564a69f16440d3e5d5a73d034 Gitweb: http://git.kernel.org/tip/8e381596b67af53564a69f16440d3e5d5a73d034 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:29 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:19 -0300
perf tools: Add stat config event read function
Introducing the perf_event__read_stat_config function to read a struct perf_stat_config object data from a stat config event.
--- tools/perf/tests/stat.c | 6 ++++++ tools/perf/util/event.c | 24 ++++++++++++++++++++++++ tools/perf/util/event.h | 2 ++ 3 files changed, 32 insertions(+)
tools/perf/tests/stat.c +6 -0
@@ -24,6 +24,7 @@ static int process_event(struct perf_tool *tool __maybe_unused, struct machine *machine __maybe_unused) {struct stat_config_event *config = &event->stat_config; +struct perf_stat_config stat_config;#define HAS (term, val) \ has_term(config, PERF_STAT_CONFIG_TERM__##term, val)
@@ -35,6 +36,11 @@ static int process_event(struct perf_tool *tool __maybe_unused,#undef HAS +perf_event__read_stat_config (&stat_config, config); + +TEST_ASSERT_VAL ("wrong aggr_mode" , stat_config.aggr_mode ==AGGR_CORE ); +TEST_ASSERT_VAL ("wrong scale" , stat_config.scale ==1 ); +TEST_ASSERT_VAL ("wrong interval" , stat_config.interval ==1 );return 0 ; }
tools/perf/util/event.c +24 -0
@@ -909,6 +909,30 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool,return err; } +void perf_event__read_stat_config (struct perf_stat_config *config, +struct stat_config_event *event) +{ +unsigned i; + +for (i =0 ; i < event->nr; i++) { + +switch (event->data[i].tag) { +#define CASE (__term, __val) \ + case PERF_STAT_CONFIG_TERM__##__term: \ + config->__val = event->data[i].val; \ + break; + + CASE(AGGR_MODE, aggr_mode) + CASE(SCALE, scale) + CASE(INTERVAL, interval) +#undef CASE +default : +pr_warning ("unknown stat config term %" PRIu64"\n" , + event->data[i].tag); + } + } +} +size_t perf_event__fprintf_comm (union perf_event *event,FILE *fp) {const char *s;
tools/perf/util/event.h +2 -0
@@ -477,6 +477,8 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool,struct perf_stat_config *config, perf_event__handler_t process, struct machine *machine); +void perf_event__read_stat_config (struct perf_stat_config *config, +struct stat_config_event *event); int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t process,
Jiri Olsa
reviewerPATCH v5 14/52 perf tools: Add stat event
In reply to Jiri OlsaAdding stat event to store 'struct perf_counter_values' for given event/cpu/thread.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 19 +++++++++++++++++++ tools/perf/util/session.c | 25 +++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 47 insertions(+), 1 deletion(-)
tools/perf/util/event.c +1 -0
@@ -42,6 +42,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", [PERF_RECORD_CPU_MAP] = "CPU_MAP", [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", + [PERF_RECORD_STAT] = "STAT", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +19 -0
@@ -229,6 +229,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_THREAD_MAP =73 ,PERF_RECORD_CPU_MAP =74 ,PERF_RECORD_STAT_CONFIG =75 , +PERF_RECORD_STAT =76 , PERF_RECORD_HEADER_MAX };
@@ -414,6 +415,23 @@ struct stat_config_event {struct stat_config_term_event data[]; }; +struct stat_event { +struct perf_event_header header; + +u64 id; +u32 cpu; +u32 thread; + +union { +struct { +u64 val; +u64 ena; +u64 run; + }; +u64 values[3 ]; + }; +}; +union perf_event {struct perf_event_header header;struct mmap_event mmap;
@@ -439,6 +457,7 @@ union perf_event {struct thread_map_event thread_map;struct cpu_map_event cpu_map;struct stat_config_event stat_config; +struct stat_event stat; };void perf_event__print_totals (void );
tools/perf/util/session.c +25 -0
@@ -324,6 +324,15 @@ int process_event_stat_config_stub(struct perf_tool *tool __maybe_unused,return 0 ; } +static int process_stat_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_session *perf_session +__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} +void perf_tool__fill_defaults (struct perf_tool *tool) {if (tool->sample ==NULL )
@@ -380,6 +389,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->cpu_map = process_event_cpu_map_stub;if (tool->stat_config ==NULL ) tool->stat_config = process_event_stat_config_stub; +if (tool->stat ==NULL ) + tool->stat = process_stat_stub; }static void swap_sample_id_all (union perf_event *event,void *data)
@@ -707,6 +718,17 @@ static void perf_event__stat_config_swap(union perf_event *event,mem_bswap_64 (&event->stat_config.nr, size); } +static void perf_event__stat_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ + event->stat.id =bswap_64 (event->stat.id); + event->stat.thread =bswap_32 (event->stat.thread); + event->stat.cpu =bswap_32 (event->stat.cpu); + event->stat.val =bswap_64 (event->stat.val); + event->stat.ena =bswap_64 (event->stat.ena); + event->stat.run =bswap_64 (event->stat.run); +} +typedef void (*perf_event__swap_op )(union perf_event *event,bool sample_id_all);
@@ -737,6 +759,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_THREAD_MAP] = perf_event__thread_map_swap, [PERF_RECORD_CPU_MAP] = perf_event__cpu_map_swap, [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap, + [PERF_RECORD_STAT] = perf_event__stat_swap, [PERF_RECORD_HEADER_MAX] = NULL, };
@@ -1279,6 +1302,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,return tool->cpu_map (tool, event, session);case PERF_RECORD_STAT_CONFIG :return tool->stat_config (tool, event, session); +case PERF_RECORD_STAT : +return tool->stat (tool, event, session);default :return -EINVAL ; }
tools/perf/util/tool.h +2 -1
@@ -58,7 +58,8 @@ struct perf_tool { auxtrace_error, thread_map, cpu_map, - stat_config; + stat_config, + stat;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add stat user level event
perf tools: Add stat user level event
Commit-ID: d80518c90bb2b4af9755d79af5dfe9d44e04cdb9 Gitweb: http://git.kernel.org/tip/d80518c90bb2b4af9755d79af5dfe9d44e04cdb9 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:30 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:38:20 -0300
perf tools: Add stat user level event
Adding a stat event to store a 'struct perf_counter_values' for a given event/cpu/thread.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 19 +++++++++++++++++++ tools/perf/util/session.c | 25 +++++++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 47 insertions(+), 1 deletion(-)
tools/perf/util/event.c +1 -0
@@ -42,6 +42,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", [PERF_RECORD_CPU_MAP] = "CPU_MAP", [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", + [PERF_RECORD_STAT] = "STAT", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +19 -0
@@ -229,6 +229,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_THREAD_MAP =73 ,PERF_RECORD_CPU_MAP =74 ,PERF_RECORD_STAT_CONFIG =75 , +PERF_RECORD_STAT =76 , PERF_RECORD_HEADER_MAX };
@@ -414,6 +415,23 @@ struct stat_config_event {struct stat_config_event_entry data[]; }; +struct stat_event { +struct perf_event_header header; + +u64 id; +u32 cpu; +u32 thread; + +union { +struct { +u64 val; +u64 ena; +u64 run; + }; +u64 values[3 ]; + }; +}; +union perf_event {struct perf_event_header header;struct mmap_event mmap;
@@ -439,6 +457,7 @@ union perf_event {struct thread_map_event thread_map;struct cpu_map_event cpu_map;struct stat_config_event stat_config; +struct stat_event stat; };void perf_event__print_totals (void );
tools/perf/util/session.c +25 -0
@@ -324,6 +324,15 @@ int process_event_stat_config_stub(struct perf_tool *tool __maybe_unused,return 0 ; } +static int process_stat_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_session *perf_session +__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} +void perf_tool__fill_defaults (struct perf_tool *tool) {if (tool->sample ==NULL )
@@ -380,6 +389,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->cpu_map = process_event_cpu_map_stub;if (tool->stat_config ==NULL ) tool->stat_config = process_event_stat_config_stub; +if (tool->stat ==NULL ) + tool->stat = process_stat_stub; }static void swap_sample_id_all (union perf_event *event,void *data)
@@ -707,6 +718,17 @@ static void perf_event__stat_config_swap(union perf_event *event,mem_bswap_64 (&event->stat_config.nr, size); } +static void perf_event__stat_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ + event->stat.id =bswap_64 (event->stat.id); + event->stat.thread =bswap_32 (event->stat.thread); + event->stat.cpu =bswap_32 (event->stat.cpu); + event->stat.val =bswap_64 (event->stat.val); + event->stat.ena =bswap_64 (event->stat.ena); + event->stat.run =bswap_64 (event->stat.run); +} +typedef void (*perf_event__swap_op )(union perf_event *event,bool sample_id_all);
@@ -737,6 +759,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_THREAD_MAP] = perf_event__thread_map_swap, [PERF_RECORD_CPU_MAP] = perf_event__cpu_map_swap, [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap, + [PERF_RECORD_STAT] = perf_event__stat_swap, [PERF_RECORD_HEADER_MAX] = NULL, };
@@ -1279,6 +1302,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,return tool->cpu_map (tool, event, session);case PERF_RECORD_STAT_CONFIG :return tool->stat_config (tool, event, session); +case PERF_RECORD_STAT : +return tool->stat (tool, event, session);default :return -EINVAL ; }
tools/perf/util/tool.h +2 -1
@@ -58,7 +58,8 @@ struct perf_tool { auxtrace_error, thread_map, cpu_map, - stat_config; + stat_config, + stat;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;
Jiri Olsa
reviewerPATCH v5 15/52 perf tools: Add stat event synthesize function
In reply to Jiri OlsaIntroduce perf_event__synthesize_stat function to
synthesize 'struct stat_event'.
--- tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/stat.c | 41 ++++++++++++++++++++++++++++++++++++----- tools/perf/tests/tests.h | 1 + tools/perf/util/event.c | 22 ++++++++++++++++++++++ tools/perf/util/event.h | 7 ++++++- 5 files changed, 69 insertions(+), 6 deletions(-)
tools/perf/tests/builtin-test.c +4 -0
@@ -178,6 +178,10 @@ static struct test generic_tests[] = { .func = test__synthesize_stat_config, }, { + .desc = "Test stat synthesize", + .func = test__synthesize_stat, + }, + { .func = NULL, }, };
tools/perf/tests/stat.c +36 -5
59 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -70,6 +70,7 @@ int test_session_topology(void);int test__thread_map_synthesize (void );int test__cpu_map_synthesize (void );int test__synthesize_stat_config (void ); +int test__synthesize_stat (void );#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/util/event.c +22 -0
@@ -910,6 +910,28 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool,return err; } +int perf_event__synthesize_stat (struct perf_tool *tool, +u32 cpu,u32 thread,u64 id, +struct perf_counts_values *count, +perf_event__handler_t process, +struct machine *machine) +{ +struct stat_event event; + + event.header.type =PERF_RECORD_STAT ; + event.header.size =sizeof (event); + event.header.misc =0 ; + + event.id = id; + event.cpu = cpu; + event.thread = thread; + event.val = count->val; + event.ena = count->ena; + event.run = count->run; + +return process (tool, (union perf_event *) &event,NULL , machine); +} +void perf_event__read_stat_config (struct perf_stat_config *config,struct stat_config_event *event) {
tools/perf/util/event.h +6 -1
@@ -466,6 +466,7 @@ struct perf_tool;struct thread_map ;struct cpu_map ;struct perf_stat_config ; +struct perf_counts_values ; typedef int (*perf_event__handler_t)(struct perf_tool *tool, union perf_event *event,
@@ -498,7 +499,11 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool, struct machine *machine);void perf_event__read_stat_config (struct perf_stat_config *config,struct stat_config_event *event); - +int perf_event__synthesize_stat (struct perf_tool *tool, +u32 cpu,u32 thread,u64 id, +struct perf_counts_values *count, +perf_event__handler_t process, +struct machine *machine);int perf_event__synthesize_modules (struct perf_tool *tool,perf_event__handler_t process,struct machine *machine);
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add stat event synthesize function
perf tools: Add stat event synthesize function
Commit-ID: 5796f8f073fe50171376f058376dde93ec5f3785 Gitweb: http://git.kernel.org/tip/5796f8f073fe50171376f058376dde93ec5f3785 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:31 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:55:31 -0300
perf tools: Add stat event synthesize function
Introduce the perf_event__synthesize_stat function to synthesize a 'struct stat_event'.
--- tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/stat.c | 41 ++++++++++++++++++++++++++++++++++++----- tools/perf/tests/tests.h | 1 + tools/perf/util/event.c | 22 ++++++++++++++++++++++ tools/perf/util/event.h | 7 ++++++- 5 files changed, 69 insertions(+), 6 deletions(-)
tools/perf/tests/builtin-test.c +4 -0
@@ -192,6 +192,10 @@ static struct test generic_tests[] = { .func = test__synthesize_stat_config, }, { + .desc = "Test stat synthesize", + .func = test__synthesize_stat, + }, + { .func = NULL, }, };
tools/perf/tests/stat.c +36 -5
59 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -82,6 +82,7 @@ int test_session_topology(int subtest);int test__thread_map_synthesize (int subtest);int test__cpu_map_synthesize (int subtest);int test__synthesize_stat_config (int subtest); +int test__synthesize_stat (int subtest);#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/util/event.c +22 -0
@@ -910,6 +910,28 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool,return err; } +int perf_event__synthesize_stat (struct perf_tool *tool, +u32 cpu,u32 thread,u64 id, +struct perf_counts_values *count, +perf_event__handler_t process, +struct machine *machine) +{ +struct stat_event event; + + event.header.type =PERF_RECORD_STAT ; + event.header.size =sizeof (event); + event.header.misc =0 ; + + event.id = id; + event.cpu = cpu; + event.thread = thread; + event.val = count->val; + event.ena = count->ena; + event.run = count->run; + +return process (tool, (union perf_event *) &event,NULL , machine); +} +void perf_event__read_stat_config (struct perf_stat_config *config,struct stat_config_event *event) {
tools/perf/util/event.h +6 -1
@@ -466,6 +466,7 @@ struct perf_tool;struct thread_map ;struct cpu_map ;struct perf_stat_config ; +struct perf_counts_values ; typedef int (*perf_event__handler_t)(struct perf_tool *tool, union perf_event *event,
@@ -498,7 +499,11 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool, struct machine *machine);void perf_event__read_stat_config (struct perf_stat_config *config,struct stat_config_event *event); - +int perf_event__synthesize_stat (struct perf_tool *tool, +u32 cpu,u32 thread,u64 id, +struct perf_counts_values *count, +perf_event__handler_t process, +struct machine *machine);int perf_event__synthesize_modules (struct perf_tool *tool,perf_event__handler_t process,struct machine *machine);
Jiri Olsa
reviewerPATCH v5 16/52 perf tools: Add stat event read function
In reply to Jiri OlsaIntroducing perf_event__process_stat_event function to process 'struct perf_stat' data from stat event.
--- tools/perf/util/stat.c | 23 +++++++++++++++++++++++ tools/perf/util/stat.h | 6 ++++++ 2 files changed, 29 insertions(+)
tools/perf/util/stat.c +23 -0
@@ -341,3 +341,26 @@ int perf_stat_process_counter(struct perf_stat_config *config,return 0 ; } + +int perf_event__process_stat_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_session *session) +{ +struct perf_counts_values count; +struct stat_event *stat = &event->stat; +struct perf_evsel *counter; + + count.val = stat->val; + count.ena = stat->ena; + count.run = stat->run; + + counter =perf_evlist__id2evsel (session->evlist, stat->id); +if (!counter) { +pr_err ("Failed to resolve counter for stat event.\n" ); +return -EINVAL ; + } + + *perf_counts (counter->counts, stat->cpu, stat->thread) = count; + counter->supported = true; +return 0 ; +}
tools/perf/util/stat.h +6 -0
@@ -90,4 +90,10 @@ void perf_evlist__reset_stats(struct perf_evlist *evlist);int perf_stat_process_counter (struct perf_stat_config *config,struct perf_evsel *counter); +struct perf_tool ; +union perf_event ; +struct perf_session ; +int perf_event__process_stat_event (struct perf_tool *tool, +union perf_event *event, +struct perf_session *session);#endif
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add stat event read function
perf tools: Add stat event read function
Commit-ID: 0ea0e3558607626196eb09ace796aac585e61f5c Gitweb: http://git.kernel.org/tip/0ea0e3558607626196eb09ace796aac585e61f5c Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:32 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:55:43 -0300
perf tools: Add stat event read function
Introducing the perf_event__process_stat_event function to process a 'struct perf_stat' data from a stat event.
--- tools/perf/util/stat.c | 23 +++++++++++++++++++++++ tools/perf/util/stat.h | 6 ++++++ 2 files changed, 29 insertions(+)
tools/perf/util/stat.c +23 -0
@@ -341,3 +341,26 @@ int perf_stat_process_counter(struct perf_stat_config *config,return 0 ; } + +int perf_event__process_stat_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_session *session) +{ +struct perf_counts_values count; +struct stat_event *st = &event->stat; +struct perf_evsel *counter; + + count.val = st->val; + count.ena = st->ena; + count.run = st->run; + + counter =perf_evlist__id2evsel (session->evlist, st->id); +if (!counter) { +pr_err ("Failed to resolve counter for stat event.\n" ); +return -EINVAL ; + } + + *perf_counts (counter->counts, st->cpu, st->thread) = count; + counter->supported = true; +return 0 ; +}
tools/perf/util/stat.h +6 -0
@@ -90,4 +90,10 @@ void perf_evlist__reset_stats(struct perf_evlist *evlist);int perf_stat_process_counter (struct perf_stat_config *config,struct perf_evsel *counter); +struct perf_tool ; +union perf_event ; +struct perf_session ; +int perf_event__process_stat_event (struct perf_tool *tool, +union perf_event *event, +struct perf_session *session);#endif
Jiri Olsa
reviewerPATCH v5 17/52 perf tools: Add stat round event
In reply to Jiri OlsaAdding stat round event to be stored after each stat interval round, so report tools (report/script) get notified and process interval data.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 13 +++++++++++++ tools/perf/util/session.c | 21 +++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 37 insertions(+), 1 deletion(-)
tools/perf/util/event.c +1 -0
@@ -43,6 +43,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_CPU_MAP] = "CPU_MAP", [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", [PERF_RECORD_STAT] = "STAT", + [PERF_RECORD_STAT_ROUND] = "STAT_ROUND", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +13 -0
@@ -230,6 +230,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_CPU_MAP =74 ,PERF_RECORD_STAT_CONFIG =75 ,PERF_RECORD_STAT =76 , +PERF_RECORD_STAT_ROUND =77 , PERF_RECORD_HEADER_MAX };
@@ -432,6 +433,17 @@ struct stat_event { }; }; +enum { +PERF_STAT_ROUND_TYPE__INTERVAL =0 , +PERF_STAT_ROUND_TYPE__FINAL =1 , +}; + +struct stat_round_event { +struct perf_event_header header; +u64 type; +u64 time; +}; +union perf_event {struct perf_event_header header;struct mmap_event mmap;
@@ -458,6 +470,7 @@ union perf_event {struct cpu_map_event cpu_map;struct stat_config_event stat_config;struct stat_event stat; +struct stat_round_event stat_round; };void perf_event__print_totals (void );
tools/perf/util/session.c +21 -0
@@ -333,6 +333,15 @@ static int process_stat_stub(struct perf_tool *tool __maybe_unused,return 0 ; } +static int process_stat_round_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_session *perf_session +__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} +void perf_tool__fill_defaults (struct perf_tool *tool) {if (tool->sample ==NULL )
@@ -391,6 +400,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->stat_config = process_event_stat_config_stub;if (tool->stat ==NULL ) tool->stat = process_stat_stub; +if (tool->stat_round ==NULL ) + tool->stat_round = process_stat_round_stub; }static void swap_sample_id_all (union perf_event *event,void *data)
@@ -729,6 +740,13 @@ static void perf_event__stat_swap(union perf_event *event, event->stat.run =bswap_64 (event->stat.run); } +static void perf_event__stat_round_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ + event->stat_round.type =bswap_64 (event->stat_round.type); + event->stat_round.time =bswap_64 (event->stat_round.time); +} +typedef void (*perf_event__swap_op )(union perf_event *event,bool sample_id_all);
@@ -760,6 +778,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_CPU_MAP] = perf_event__cpu_map_swap, [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap, [PERF_RECORD_STAT] = perf_event__stat_swap, + [PERF_RECORD_STAT_ROUND] = perf_event__stat_round_swap, [PERF_RECORD_HEADER_MAX] = NULL, };
@@ -1304,6 +1323,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,return tool->stat_config (tool, event, session);case PERF_RECORD_STAT :return tool->stat (tool, event, session); +case PERF_RECORD_STAT_ROUND : +return tool->stat_round (tool, event, session);default :return -EINVAL ; }
tools/perf/util/tool.h +2 -1
@@ -59,7 +59,8 @@ struct perf_tool { thread_map, cpu_map, stat_config, - stat; + stat, + stat_round;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add stat round user level event
perf tools: Add stat round user level event
Commit-ID: 2d8f0f18a5c37cf0322cb385b99adb1167b7cf78 Gitweb: http://git.kernel.org/tip/2d8f0f18a5c37cf0322cb385b99adb1167b7cf78 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:33 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:55:43 -0300
perf tools: Add stat round user level event
Adding the stat round event to be stored after each stat interval round, so that report tools (report/script) gets notified and process interval data.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 13 +++++++++++++ tools/perf/util/session.c | 21 +++++++++++++++++++++ tools/perf/util/tool.h | 3 ++- 4 files changed, 37 insertions(+), 1 deletion(-)
tools/perf/util/event.c +1 -0
@@ -43,6 +43,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_CPU_MAP] = "CPU_MAP", [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", [PERF_RECORD_STAT] = "STAT", + [PERF_RECORD_STAT_ROUND] = "STAT_ROUND", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +13 -0
@@ -230,6 +230,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_CPU_MAP =74 ,PERF_RECORD_STAT_CONFIG =75 ,PERF_RECORD_STAT =76 , +PERF_RECORD_STAT_ROUND =77 , PERF_RECORD_HEADER_MAX };
@@ -432,6 +433,17 @@ struct stat_event { }; }; +enum { +PERF_STAT_ROUND_TYPE__INTERVAL =0 , +PERF_STAT_ROUND_TYPE__FINAL =1 , +}; + +struct stat_round_event { +struct perf_event_header header; +u64 type; +u64 time; +}; +union perf_event {struct perf_event_header header;struct mmap_event mmap;
@@ -458,6 +470,7 @@ union perf_event {struct cpu_map_event cpu_map;struct stat_config_event stat_config;struct stat_event stat; +struct stat_round_event stat_round; };void perf_event__print_totals (void );
tools/perf/util/session.c +21 -0
@@ -333,6 +333,15 @@ static int process_stat_stub(struct perf_tool *tool __maybe_unused,return 0 ; } +static int process_stat_round_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_session *perf_session +__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} +void perf_tool__fill_defaults (struct perf_tool *tool) {if (tool->sample ==NULL )
@@ -391,6 +400,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->stat_config = process_event_stat_config_stub;if (tool->stat ==NULL ) tool->stat = process_stat_stub; +if (tool->stat_round ==NULL ) + tool->stat_round = process_stat_round_stub; }static void swap_sample_id_all (union perf_event *event,void *data)
@@ -729,6 +740,13 @@ static void perf_event__stat_swap(union perf_event *event, event->stat.run =bswap_64 (event->stat.run); } +static void perf_event__stat_round_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ + event->stat_round.type =bswap_64 (event->stat_round.type); + event->stat_round.time =bswap_64 (event->stat_round.time); +} +typedef void (*perf_event__swap_op )(union perf_event *event,bool sample_id_all);
@@ -760,6 +778,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_CPU_MAP] = perf_event__cpu_map_swap, [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap, [PERF_RECORD_STAT] = perf_event__stat_swap, + [PERF_RECORD_STAT_ROUND] = perf_event__stat_round_swap, [PERF_RECORD_HEADER_MAX] = NULL, };
@@ -1304,6 +1323,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,return tool->stat_config (tool, event, session);case PERF_RECORD_STAT :return tool->stat (tool, event, session); +case PERF_RECORD_STAT_ROUND : +return tool->stat_round (tool, event, session);default :return -EINVAL ; }
tools/perf/util/tool.h +2 -1
@@ -59,7 +59,8 @@ struct perf_tool { thread_map, cpu_map, stat_config, - stat; + stat, + stat_round;event_op3 auxtrace;bool ordered_events;bool ordering_requires_timestamps;
Jiri Olsa
reviewerPATCH v5 18/52 perf tools: Add stat round event synthesize function
In reply to Jiri OlsaIntroduce perf_event__synthesize_stat_round function to synthesize 'struct stat_round_event'.
--- tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/stat.c | 21 +++++++++++++++++++++ tools/perf/tests/tests.h | 2 ++ tools/perf/util/event.c | 17 +++++++++++++++++ tools/perf/util/event.h | 4 ++++ 5 files changed, 48 insertions(+)
tools/perf/tests/builtin-test.c +4 -0
@@ -182,6 +182,10 @@ static struct test generic_tests[] = { .func = test__synthesize_stat, }, { + .desc = "Test stat round synthesize", + .func = test__synthesize_stat_round, + }, + { .func = NULL, }, };
tools/perf/tests/stat.c +21 -0
@@ -88,3 +88,24 @@ int test__synthesize_stat(void)return 0 ; } + +static int process_stat_round_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ +struct stat_round_event *stat_round = &event->stat_round; + +TEST_ASSERT_VAL ("wrong time" , stat_round->time ==0xdeadbeef ); +TEST_ASSERT_VAL ("wrong type" , stat_round->type ==PERF_STAT_ROUND_TYPE__INTERVAL ); +return 0 ; +} + +int test__synthesize_stat_round (void ) +{ +TEST_ASSERT_VAL ("failed to synthesize stat_config" , + !perf_event__synthesize_stat_round (NULL ,0xdeadbeef ,PERF_STAT_ROUND_TYPE__INTERVAL , + process_stat_round_event,NULL )); + +return 0 ; +}
tools/perf/tests/tests.h +2 -0
@@ -71,6 +71,8 @@ int test__thread_map_synthesize(void);int test__cpu_map_synthesize (void );int test__synthesize_stat_config (void );int test__synthesize_stat (void ); +int test__synthesize_stat_round (void ); +#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/util/event.c +17 -0
@@ -933,6 +933,23 @@ int perf_event__synthesize_stat(struct perf_tool *tool,return process (tool, (union perf_event *) &event,NULL , machine); } +int perf_event__synthesize_stat_round (struct perf_tool *tool, +u64 time,u64 type, +perf_event__handler_t process, +struct machine *machine) +{ +struct stat_round_event event; + + event.header.type =PERF_RECORD_STAT_ROUND ; + event.header.size =sizeof (event); + event.header.misc =0 ; + + event.time = time; + event.type = type; + +return process (tool, (union perf_event *) &event,NULL , machine); +} +void perf_event__read_stat_config (struct perf_stat_config *config,struct stat_config_event *event) {
tools/perf/util/event.h +4 -0
@@ -517,6 +517,10 @@ int perf_event__synthesize_stat(struct perf_tool *tool,struct perf_counts_values *count, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_stat_round (struct perf_tool *tool, +u64 time,u64 type, +perf_event__handler_t process, +struct machine *machine);int perf_event__synthesize_modules (struct perf_tool *tool,perf_event__handler_t process,struct machine *machine);
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add stat round event synthesize function
perf tools: Add stat round event synthesize function
Commit-ID: d4c2259195f538505d2570e78555532372fb4ad2 Gitweb: http://git.kernel.org/tip/d4c2259195f538505d2570e78555532372fb4ad2 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:34 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 14:55:44 -0300
perf tools: Add stat round event synthesize function
Introduce the perf_event__synthesize_stat_round function to synthesize a 'struct stat_round_event'.
--- tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/stat.c | 21 +++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/event.c | 17 +++++++++++++++++ tools/perf/util/event.h | 4 ++++ 5 files changed, 47 insertions(+)
tools/perf/tests/builtin-test.c +4 -0
@@ -196,6 +196,10 @@ static struct test generic_tests[] = { .func = test__synthesize_stat, }, { + .desc = "Test stat round synthesize", + .func = test__synthesize_stat_round, + }, + { .func = NULL, }, };
tools/perf/tests/stat.c +21 -0
@@ -88,3 +88,24 @@ int test__synthesize_stat(int subtest __maybe_unused)return 0 ; } + +static int process_stat_round_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ +struct stat_round_event *stat_round = &event->stat_round; + +TEST_ASSERT_VAL ("wrong time" , stat_round->time ==0xdeadbeef ); +TEST_ASSERT_VAL ("wrong type" , stat_round->type ==PERF_STAT_ROUND_TYPE__INTERVAL ); +return 0 ; +} + +int test__synthesize_stat_round (int subtest__maybe_unused ) +{ +TEST_ASSERT_VAL ("failed to synthesize stat_config" , + !perf_event__synthesize_stat_round (NULL ,0xdeadbeef ,PERF_STAT_ROUND_TYPE__INTERVAL , + process_stat_round_event,NULL )); + +return 0 ; +}
tools/perf/tests/tests.h +1 -0
@@ -83,6 +83,7 @@ int test__thread_map_synthesize(int subtest);int test__cpu_map_synthesize (int subtest);int test__synthesize_stat_config (int subtest);int test__synthesize_stat (int subtest); +int test__synthesize_stat_round (int subtest);#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/util/event.c +17 -0
@@ -933,6 +933,23 @@ int perf_event__synthesize_stat(struct perf_tool *tool,return process (tool, (union perf_event *) &event,NULL , machine); } +int perf_event__synthesize_stat_round (struct perf_tool *tool, +u64 evtime,u64 type, +perf_event__handler_t process, +struct machine *machine) +{ +struct stat_round_event event; + + event.header.type =PERF_RECORD_STAT_ROUND ; + event.header.size =sizeof (event); + event.header.misc =0 ; + + event.time = evtime; + event.type = type; + +return process (tool, (union perf_event *) &event,NULL , machine); +} +void perf_event__read_stat_config (struct perf_stat_config *config,struct stat_config_event *event) {
tools/perf/util/event.h +4 -0
@@ -517,6 +517,10 @@ int perf_event__synthesize_stat(struct perf_tool *tool,struct perf_counts_values *count, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_stat_round (struct perf_tool *tool, +u64 time,u64 type, +perf_event__handler_t process, +struct machine *machine);int perf_event__synthesize_modules (struct perf_tool *tool,perf_event__handler_t process,struct machine *machine);
Jiri Olsa
reviewerPATCH v5 19/52 perf tools: Add stat events fprintf functions
In reply to Jiri OlsaIntroducing following functions to display stat events for raw dump.
perf_event__fprintf_stat
perf_event__fprintf_stat_round
perf_event__fprintf_stat_config
--- tools/perf/util/stat.c | 39 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 4 ++++ 2 files changed, 43 insertions(+)
tools/perf/util/stat.c +39 -0
@@ -364,3 +364,42 @@ int perf_event__process_stat_event(struct perf_tool *tool __maybe_unused, counter->supported = true;return 0 ; } + +size_t perf_event__fprintf_stat (union perf_event *event,FILE *fp) +{ +struct stat_event *stat = (struct stat_event *) event; +size_t ret; + + ret =fprintf (fp,"\n... id %" PRIu64", cpu %d, thread %d\n" , + stat->id, stat->cpu, stat->thread); + ret +=fprintf (fp,"... value %" PRIu64", enabled %" PRIu64", running %" PRIu64"\n" , + stat->val, stat->ena, stat->run); + +return ret; +} + +size_t perf_event__fprintf_stat_round (union perf_event *event,FILE *fp) +{ +struct stat_round_event *round = (struct stat_round_event *) event; +size_t ret; + + ret =fprintf (fp,"\n... time %" PRIu64", type %s\n" , round->time, + round->type ==PERF_STAT_ROUND_TYPE__FINAL ?"FINAL" :"INTERVAL" ); + +return ret; +} + +size_t perf_event__fprintf_stat_config (union perf_event *event,FILE *fp) +{ +struct perf_stat_config sc; +size_t ret; + +perf_event__read_stat_config (&sc, &event->stat_config); + + ret =fprintf (fp,"\n" ); + ret +=fprintf (fp,"... aggr_mode %d\n" , sc.aggr_mode); + ret +=fprintf (fp,"... scale %d\n" , sc.scale); + ret +=fprintf (fp,"... interval %u\n" , sc.interval); + +return ret; +}
tools/perf/util/stat.h +4 -0
@@ -96,4 +96,8 @@ struct perf_session;int perf_event__process_stat_event (struct perf_tool *tool,union perf_event *event,struct perf_session *session); + +size_t perf_event__fprintf_stat (union perf_event *event,FILE *fp); +size_t perf_event__fprintf_stat_round (union perf_event *event,FILE *fp); +size_t perf_event__fprintf_stat_config (union perf_event *event,FILE *fp);#endif
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add stat events fprintf functions
perf tools: Add stat events fprintf functions
Commit-ID: e08a4564e23f8f89a055d717887674f54a9da515 Gitweb: http://git.kernel.org/tip/e08a4564e23f8f89a055d717887674f54a9da515 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:35 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 15:09:38 -0300
perf tools: Add stat events fprintf functions
Introducing the following functions to display the stat events for raw dump.
perf_event__fprintf_stat
perf_event__fprintf_stat_round
perf_event__fprintf_stat_config
--- tools/perf/util/stat.c | 39 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 4 ++++ 2 files changed, 43 insertions(+)
tools/perf/util/stat.c +39 -0
@@ -364,3 +364,42 @@ int perf_event__process_stat_event(struct perf_tool *tool __maybe_unused, counter->supported = true;return 0 ; } + +size_t perf_event__fprintf_stat (union perf_event *event,FILE *fp) +{ +struct stat_event *st = (struct stat_event *) event; +size_t ret; + + ret =fprintf (fp,"\n... id %" PRIu64", cpu %d, thread %d\n" , + st->id, st->cpu, st->thread); + ret +=fprintf (fp,"... value %" PRIu64", enabled %" PRIu64", running %" PRIu64"\n" , + st->val, st->ena, st->run); + +return ret; +} + +size_t perf_event__fprintf_stat_round (union perf_event *event,FILE *fp) +{ +struct stat_round_event *rd = (struct stat_round_event *)event; +size_t ret; + + ret =fprintf (fp,"\n... time %" PRIu64", type %s\n" , rd->time, + rd->type ==PERF_STAT_ROUND_TYPE__FINAL ?"FINAL" :"INTERVAL" ); + +return ret; +} + +size_t perf_event__fprintf_stat_config (union perf_event *event,FILE *fp) +{ +struct perf_stat_config sc; +size_t ret; + +perf_event__read_stat_config (&sc, &event->stat_config); + + ret =fprintf (fp,"\n" ); + ret +=fprintf (fp,"... aggr_mode %d\n" , sc.aggr_mode); + ret +=fprintf (fp,"... scale %d\n" , sc.scale); + ret +=fprintf (fp,"... interval %u\n" , sc.interval); + +return ret; +}
tools/perf/util/stat.h +4 -0
@@ -96,4 +96,8 @@ struct perf_session;int perf_event__process_stat_event (struct perf_tool *tool,union perf_event *event,struct perf_session *session); + +size_t perf_event__fprintf_stat (union perf_event *event,FILE *fp); +size_t perf_event__fprintf_stat_round (union perf_event *event,FILE *fp); +size_t perf_event__fprintf_stat_config (union perf_event *event,FILE *fp);#endif
Jiri Olsa
reviewerPATCH v5 20/52 perf tools: Add event_update event
In reply to Jiri OlsaIt'll server as base event for additional event attributes details, that are not part of the attr event.
At the moment this event is just dummy one without specific functionality. The type value will distinguish the update event details. It comes in following patches.
The idea for this event is to be extensible for any update that event might need in the future.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 10 ++++++++++ tools/perf/util/header.c | 20 ++++++++++++++++++++ tools/perf/util/header.h | 3 +++ tools/perf/util/session.c | 21 +++++++++++++++++++++ tools/perf/util/tool.h | 1 + 6 files changed, 56 insertions(+)
tools/perf/util/event.c +1 -0
@@ -44,6 +44,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", [PERF_RECORD_STAT] = "STAT", [PERF_RECORD_STAT_ROUND] = "STAT_ROUND", + [PERF_RECORD_EVENT_UPDATE] = "EVENT_UPDATE", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +10 -0
@@ -231,6 +231,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_STAT_CONFIG =75 ,PERF_RECORD_STAT =76 ,PERF_RECORD_STAT_ROUND =77 , +PERF_RECORD_EVENT_UPDATE =78 , PERF_RECORD_HEADER_MAX };
@@ -307,6 +308,14 @@ struct attr_event {u64 id[]; }; +struct event_update_event { +struct perf_event_header header; +u64 type; +u64 id; + +char data[]; +}; +#define MAX_EVENT_NAME 64struct perf_trace_event_type {
@@ -456,6 +465,7 @@ union perf_event {struct throttle_event throttle;struct sample_event sample;struct attr_event attr; +struct event_update_event event_update;struct event_type_event event_type;struct tracing_data_event tracing_data;struct build_id_event build_id;
tools/perf/util/header.c +20 -0
@@ -2745,6 +2745,26 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused,return 0 ; } +int perf_event__process_event_update (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_evlist **pevlist) +{ +struct event_update_event *ev = &event->event_update; +struct perf_evlist *evlist; +struct perf_evsel *evsel; + +if (!pevlist || *pevlist ==NULL ) +return -EINVAL ; + + evlist = *pevlist; + + evsel =perf_evlist__id2evsel (evlist, ev->id); +if (evsel ==NULL ) +return -EINVAL ; + +return 0 ; +} +int perf_event__synthesize_tracing_data (struct perf_tool *tool,int fd,struct perf_evlist *evlist,perf_event__handler_t process)
tools/perf/util/header.h +3 -0
@@ -107,6 +107,9 @@ int perf_event__synthesize_attrs(struct perf_tool *tool, perf_event__handler_t process);int perf_event__process_attr (struct perf_tool *tool,union perf_event *event,struct perf_evlist **pevlist); +int perf_event__process_event_update (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_evlist **pevlist); int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct perf_evlist *evlist,
tools/perf/util/session.c +21 -0
@@ -205,6 +205,15 @@ static int process_event_synth_attr_stub(struct perf_tool *tool __maybe_unused,return 0 ; } +static int process_event_synth_event_update_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_evlist **pevlist +__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} + static int process_event_sample_stub(struct perf_tool *tool __maybe_unused, union perf_event *event __maybe_unused, struct perf_sample *sample __maybe_unused,
@@ -374,6 +383,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->unthrottle = process_event_stub;if (tool->attr ==NULL ) tool->attr = process_event_synth_attr_stub; +if (tool->event_update ==NULL ) + tool->event_update = process_event_synth_event_update_stub;if (tool->tracing_data ==NULL ) tool->tracing_data = process_event_synth_tracing_data_stub;if (tool->build_id ==NULL )
@@ -625,6 +636,13 @@ static void perf_event__hdr_attr_swap(union perf_event *event,mem_bswap_64 (event->attr.id, size); } +static void perf_event__event_update_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ + event->event_update.type =bswap_64 (event->event_update.type); + event->event_update.id =bswap_64 (event->event_update.id); +} +static void perf_event__event_type_swap (union perf_event *event,bool sample_id_all__maybe_unused ) {
@@ -779,6 +797,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap, [PERF_RECORD_STAT] = perf_event__stat_swap, [PERF_RECORD_STAT_ROUND] = perf_event__stat_round_swap, + [PERF_RECORD_EVENT_UPDATE] = perf_event__event_update_swap, [PERF_RECORD_HEADER_MAX] = NULL, };
@@ -1290,6 +1309,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,perf_session__set_comm_exec (session); }return err; +case PERF_RECORD_EVENT_UPDATE : +return tool->event_update (tool, event, &session->evlist);case PERF_RECORD_HEADER_EVENT_TYPE :/* * Depreceated, but we need to handle it for sake
tools/perf/util/tool.h +1 -0
@@ -50,6 +50,7 @@ struct perf_tool { throttle, unthrottle;event_attr_op attr; +event_attr_op event_update;event_op2 tracing_data;event_oe finished_round; event_op2 build_id,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add event_update user level event
perf tools: Add event_update user level event
Commit-ID: ffe777254cce24fb5fde3f0aa91fc755cfb1b812 Gitweb: http://git.kernel.org/tip/ffe777254cce24fb5fde3f0aa91fc755cfb1b812 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:36 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 15:10:16 -0300
perf tools: Add event_update user level event
It'll serve as a base event for additional event attributes details, that are not part of the attr event.
At the moment this event is just a dummy one without any specific functionality. The type value will distinguish the update event details. It'll come in the following patches.
The idea for this event is to be extensible for any update that the event might need in the future.
--- tools/perf/util/event.c | 1 + tools/perf/util/event.h | 10 ++++++++++ tools/perf/util/header.c | 20 ++++++++++++++++++++ tools/perf/util/header.h | 3 +++ tools/perf/util/session.c | 21 +++++++++++++++++++++ tools/perf/util/tool.h | 1 + 6 files changed, 56 insertions(+)
tools/perf/util/event.c +1 -0
@@ -44,6 +44,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", [PERF_RECORD_STAT] = "STAT", [PERF_RECORD_STAT_ROUND] = "STAT_ROUND", + [PERF_RECORD_EVENT_UPDATE] = "EVENT_UPDATE", };const char *perf_event__name (unsigned int id)
tools/perf/util/event.h +10 -0
@@ -231,6 +231,7 @@ enum perf_user_event_type { /* above any possible kernel type */PERF_RECORD_STAT_CONFIG =75 ,PERF_RECORD_STAT =76 ,PERF_RECORD_STAT_ROUND =77 , +PERF_RECORD_EVENT_UPDATE =78 , PERF_RECORD_HEADER_MAX };
@@ -307,6 +308,14 @@ struct attr_event {u64 id[]; }; +struct event_update_event { +struct perf_event_header header; +u64 type; +u64 id; + +char data[]; +}; +#define MAX_EVENT_NAME 64struct perf_trace_event_type {
@@ -456,6 +465,7 @@ union perf_event {struct throttle_event throttle;struct sample_event sample;struct attr_event attr; +struct event_update_event event_update;struct event_type_event event_type;struct tracing_data_event tracing_data;struct build_id_event build_id;
tools/perf/util/header.c +20 -0
@@ -2745,6 +2745,26 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused,return 0 ; } +int perf_event__process_event_update (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_evlist **pevlist) +{ +struct event_update_event *ev = &event->event_update; +struct perf_evlist *evlist; +struct perf_evsel *evsel; + +if (!pevlist || *pevlist ==NULL ) +return -EINVAL ; + + evlist = *pevlist; + + evsel =perf_evlist__id2evsel (evlist, ev->id); +if (evsel ==NULL ) +return -EINVAL ; + +return 0 ; +} +int perf_event__synthesize_tracing_data (struct perf_tool *tool,int fd,struct perf_evlist *evlist,perf_event__handler_t process)
tools/perf/util/header.h +3 -0
@@ -107,6 +107,9 @@ int perf_event__synthesize_attrs(struct perf_tool *tool, perf_event__handler_t process);int perf_event__process_attr (struct perf_tool *tool,union perf_event *event,struct perf_evlist **pevlist); +int perf_event__process_event_update (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_evlist **pevlist); int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct perf_evlist *evlist,
tools/perf/util/session.c +21 -0
@@ -205,6 +205,15 @@ static int process_event_synth_attr_stub(struct perf_tool *tool __maybe_unused,return 0 ; } +static int process_event_synth_event_update_stub (struct perf_tool *tool__maybe_unused , +union perf_event *event__maybe_unused , +struct perf_evlist **pevlist +__maybe_unused ) +{ +dump_printf (": unhandled!\n" ); +return 0 ; +} + static int process_event_sample_stub(struct perf_tool *tool __maybe_unused, union perf_event *event __maybe_unused, struct perf_sample *sample __maybe_unused,
@@ -374,6 +383,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->unthrottle = process_event_stub;if (tool->attr ==NULL ) tool->attr = process_event_synth_attr_stub; +if (tool->event_update ==NULL ) + tool->event_update = process_event_synth_event_update_stub;if (tool->tracing_data ==NULL ) tool->tracing_data = process_event_synth_tracing_data_stub;if (tool->build_id ==NULL )
@@ -625,6 +636,13 @@ static void perf_event__hdr_attr_swap(union perf_event *event,mem_bswap_64 (event->attr.id, size); } +static void perf_event__event_update_swap (union perf_event *event, +bool sample_id_all__maybe_unused ) +{ + event->event_update.type =bswap_64 (event->event_update.type); + event->event_update.id =bswap_64 (event->event_update.id); +} +static void perf_event__event_type_swap (union perf_event *event,bool sample_id_all__maybe_unused ) {
@@ -779,6 +797,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap, [PERF_RECORD_STAT] = perf_event__stat_swap, [PERF_RECORD_STAT_ROUND] = perf_event__stat_round_swap, + [PERF_RECORD_EVENT_UPDATE] = perf_event__event_update_swap, [PERF_RECORD_HEADER_MAX] = NULL, };
@@ -1290,6 +1309,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,perf_session__set_comm_exec (session); }return err; +case PERF_RECORD_EVENT_UPDATE : +return tool->event_update (tool, event, &session->evlist);case PERF_RECORD_HEADER_EVENT_TYPE :/* * Depreceated, but we need to handle it for sake
tools/perf/util/tool.h +1 -0
@@ -50,6 +50,7 @@ struct perf_tool { throttle, unthrottle;event_attr_op attr; +event_attr_op event_update;event_op2 tracing_data;event_oe finished_round; event_op2 build_id,
Jiri Olsa
reviewerPATCH v5 21/52 perf tools: Add event_update event unit type
In reply to Jiri OlsaAdding unit type 'event update' event, that stores/transfer events unit name. The unit name is part of the perf stat output data.
--- tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/event_update.c | 42 +++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/event.h | 4 ++++ tools/perf/util/header.c | 44 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/header.h | 3 +++ 7 files changed, 99 insertions(+) create mode 100644 tools/perf/tests/event_update.c
tools/perf/tests/Build +1 -0
@@ -35,6 +35,7 @@ perf-y += llvm.o perf-y += topology.o perf-y += cpumap.o perf-y += stat.o +perf-y += event_update.o ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64)) perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
tools/perf/tests/builtin-test.c +4 -0
@@ -186,6 +186,10 @@ static struct test generic_tests[] = { .func = test__synthesize_stat_round, }, { + .desc = "Test attr update synthesize", + .func = test__event_update, + }, + { .func = NULL, }, };
tools/perf/tests/event_update.c new file +42 -0
42 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -72,6 +72,7 @@ int test__cpu_map_synthesize(void);int test__synthesize_stat_config (void );int test__synthesize_stat (void );int test__synthesize_stat_round (void ); +int test__event_update (void );#if defined(__arm__) || defined(__aarch64__)
tools/perf/util/event.h +4 -0
@@ -308,6 +308,10 @@ struct attr_event {u64 id[]; }; +enum { +PERF_EVENT_UPDATE__UNIT =0 , +}; +struct event_update_event {struct perf_event_header header;u64 type;
tools/perf/util/header.c +44 -0
56 lines not on this page · raw message
tools/perf/util/header.h +3 -0
@@ -105,6 +105,9 @@ int perf_event__synthesize_attr(struct perf_tool *tool,int perf_event__synthesize_attrs (struct perf_tool *tool,struct perf_session *session,perf_event__handler_t process); +int perf_event__synthesize_event_update_unit (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process);int perf_event__process_attr (struct perf_tool *tool,union perf_event *event,struct perf_evlist **pevlist); int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add event_update event unit type
perf tools: Add event_update event unit type
Commit-ID: a6e5281780d1da65c15ce529707f43eb4a6df856 Gitweb: http://git.kernel.org/tip/a6e5281780d1da65c15ce529707f43eb4a6df856 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:37 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 15:11:10 -0300
perf tools: Add event_update event unit type
Adding unit type 'event update' event, that stores/transfer events unit name. The unit name is part of the perf stat output data.
--- tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/event_update.c | 42 +++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/event.h | 4 ++++ tools/perf/util/header.c | 44 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/header.h | 3 +++ 7 files changed, 99 insertions(+)
tools/perf/tests/Build +1 -0
@@ -36,6 +36,7 @@ perf-y += bpf.o perf-y += topology.o perf-y += cpumap.o perf-y += stat.o +perf-y += event_update.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir)
tools/perf/tests/builtin-test.c +4 -0
@@ -200,6 +200,10 @@ static struct test generic_tests[] = { .func = test__synthesize_stat_round, }, { + .desc = "Test attr update synthesize", + .func = test__event_update, + }, + { .func = NULL, }, };
tools/perf/tests/event_update.c new file +42 -0
42 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -84,6 +84,7 @@ int test__cpu_map_synthesize(int subtest);int test__synthesize_stat_config (int subtest);int test__synthesize_stat (int subtest);int test__synthesize_stat_round (int subtest); +int test__event_update (int subtest);#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/util/event.h +4 -0
@@ -308,6 +308,10 @@ struct attr_event {u64 id[]; }; +enum { +PERF_EVENT_UPDATE__UNIT =0 , +}; +struct event_update_event {struct perf_event_header header;u64 type;
tools/perf/util/header.c +44 -0
56 lines not on this page · raw message
tools/perf/util/header.h +3 -0
@@ -105,6 +105,9 @@ int perf_event__synthesize_attr(struct perf_tool *tool,int perf_event__synthesize_attrs (struct perf_tool *tool,struct perf_session *session,perf_event__handler_t process); +int perf_event__synthesize_event_update_unit (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process);int perf_event__process_attr (struct perf_tool *tool,union perf_event *event,struct perf_evlist **pevlist); int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
Jiri Olsa
reviewerPATCH v5 22/52 perf tools: Add event_update event scale type
In reply to Jiri OlsaAdding scale type 'event update' event, that stores/transfer events scale value. The PMU events can define the scale value which is used to multiply events data.
--- tools/perf/tests/event_update.c | 21 +++++++++++++++++++++ tools/perf/util/event.h | 5 +++++ tools/perf/util/header.c | 26 ++++++++++++++++++++++++++ tools/perf/util/header.h | 3 +++ 4 files changed, 55 insertions(+)
tools/perf/tests/event_update.c +21 -0
@@ -18,6 +18,22 @@ static int process_event_unit(struct perf_tool *tool __maybe_unused,return 0 ; } +static int process_event_scale (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ +struct event_update_event *ev = (struct event_update_event *) event; +struct event_update_event_scale *ev_data; + + ev_data = (struct event_update_event_scale *) ev->data; + +TEST_ASSERT_VAL ("wrong id" , ev->id ==123 ); +TEST_ASSERT_VAL ("wrong id" , ev->type ==PERF_EVENT_UPDATE__SCALE ); +TEST_ASSERT_VAL ("wrong scale" , ev_data->scale =0.123 ); +return 0 ; +} +int test__event_update (void ) {struct perf_evlist *evlist;
@@ -38,5 +54,10 @@ int test__event_update(void)TEST_ASSERT_VAL ("failed to synthesize attr update unit" , !perf_event__synthesize_event_update_unit (NULL , evsel, process_event_unit)); + evsel->scale =0.123 ; + +TEST_ASSERT_VAL ("failed to synthesize attr update scale" , + !perf_event__synthesize_event_update_scale (NULL , evsel, process_event_scale)); +return 0 ; }
tools/perf/util/event.h +5 -0
@@ -310,6 +310,11 @@ struct attr_event {enum {PERF_EVENT_UPDATE__UNIT =0 , +PERF_EVENT_UPDATE__SCALE =1 , +}; + +struct event_update_event_scale { +double scale; };struct event_update_event {
tools/perf/util/header.c +26 -0
@@ -2723,6 +2723,27 @@ perf_event__synthesize_event_update_unit(struct perf_tool *tool,return err; } +int +perf_event__synthesize_event_update_scale (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process) +{ +struct event_update_event *ev; +struct event_update_event_scale *ev_data; +int err; + + ev =event_update_event__alloc (sizeof (*ev_data),PERF_EVENT_UPDATE__SCALE , evsel->id[0 ]); +if (ev ==NULL ) +return -ENOMEM ; + + ev_data = (struct event_update_event_scale *) ev->data; + ev_data->scale = evsel->scale; + err =process (tool, (union perf_event *) ev,NULL ,NULL ); +free (ev); +return err; +} + +int perf_event__synthesize_attrs (struct perf_tool *tool,struct perf_session *session,perf_event__handler_t process)
@@ -2787,6 +2808,7 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, struct perf_evlist **pevlist) {struct event_update_event *ev = &event->event_update; +struct event_update_event_scale *ev_scale;struct perf_evlist *evlist;struct perf_evsel *evsel;
@@ -2802,6 +2824,10 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,switch (ev->type) {case PERF_EVENT_UPDATE__UNIT : evsel->unit =strdup (ev->data); +break ; +case PERF_EVENT_UPDATE__SCALE : + ev_scale = (struct event_update_event_scale *) ev->data; + evsel->scale = ev_scale->scale;default :break ; }
tools/perf/util/header.h +3 -0
@@ -108,6 +108,9 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,int perf_event__synthesize_event_update_unit (struct perf_tool *tool,struct perf_evsel *evsel,perf_event__handler_t process); +int perf_event__synthesize_event_update_scale (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process);int perf_event__process_attr (struct perf_tool *tool,union perf_event *event,struct perf_evlist **pevlist); int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add event_update event scale type
perf tools: Add event_update event scale type
Commit-ID: daeecbc0c431f15f492fb8d704080a02de6e2918 Gitweb: http://git.kernel.org/tip/daeecbc0c431f15f492fb8d704080a02de6e2918 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:38 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 15:11:59 -0300
perf tools: Add event_update event scale type
A__allocdding scale type 'event update' event, that stores/transfer events scale value. The PMU events can define the scale value which is used to multiply events data.
--- tools/perf/tests/event_update.c | 21 +++++++++++++++++++++ tools/perf/util/event.h | 5 +++++ tools/perf/util/header.c | 26 ++++++++++++++++++++++++++ tools/perf/util/header.h | 3 +++ 4 files changed, 55 insertions(+)
tools/perf/tests/event_update.c +21 -0
@@ -18,6 +18,22 @@ static int process_event_unit(struct perf_tool *tool __maybe_unused,return 0 ; } +static int process_event_scale (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ +struct event_update_event *ev = (struct event_update_event *) event; +struct event_update_event_scale *ev_data; + + ev_data = (struct event_update_event_scale *) ev->data; + +TEST_ASSERT_VAL ("wrong id" , ev->id ==123 ); +TEST_ASSERT_VAL ("wrong id" , ev->type ==PERF_EVENT_UPDATE__SCALE ); +TEST_ASSERT_VAL ("wrong scale" , ev_data->scale =0.123 ); +return 0 ; +} +int test__event_update (int subtest__maybe_unused ) {struct perf_evlist *evlist;
@@ -38,5 +54,10 @@ int test__event_update(int subtest __maybe_unused)TEST_ASSERT_VAL ("failed to synthesize attr update unit" , !perf_event__synthesize_event_update_unit (NULL , evsel, process_event_unit)); + evsel->scale =0.123 ; + +TEST_ASSERT_VAL ("failed to synthesize attr update scale" , + !perf_event__synthesize_event_update_scale (NULL , evsel, process_event_scale)); +return 0 ; }
tools/perf/util/event.h +5 -0
@@ -310,6 +310,11 @@ struct attr_event {enum {PERF_EVENT_UPDATE__UNIT =0 , +PERF_EVENT_UPDATE__SCALE =1 , +}; + +struct event_update_event_scale { +double scale; };struct event_update_event {
tools/perf/util/header.c +26 -0
@@ -2723,6 +2723,27 @@ perf_event__synthesize_event_update_unit(struct perf_tool *tool,return err; } +int +perf_event__synthesize_event_update_scale (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process) +{ +struct event_update_event *ev; +struct event_update_event_scale *ev_data; +int err; + + ev =event_update_event__new (sizeof (*ev_data),PERF_EVENT_UPDATE__SCALE , evsel->id[0 ]); +if (ev ==NULL ) +return -ENOMEM ; + + ev_data = (struct event_update_event_scale *) ev->data; + ev_data->scale = evsel->scale; + err =process (tool, (union perf_event *) ev,NULL ,NULL ); +free (ev); +return err; +} + +int perf_event__synthesize_attrs (struct perf_tool *tool,struct perf_session *session,perf_event__handler_t process)
@@ -2787,6 +2808,7 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, struct perf_evlist **pevlist) {struct event_update_event *ev = &event->event_update; +struct event_update_event_scale *ev_scale;struct perf_evlist *evlist;struct perf_evsel *evsel;
@@ -2802,6 +2824,10 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,switch (ev->type) {case PERF_EVENT_UPDATE__UNIT : evsel->unit =strdup (ev->data); +break ; +case PERF_EVENT_UPDATE__SCALE : + ev_scale = (struct event_update_event_scale *) ev->data; + evsel->scale = ev_scale->scale;default :break ; }
tools/perf/util/header.h +3 -0
@@ -108,6 +108,9 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,int perf_event__synthesize_event_update_unit (struct perf_tool *tool,struct perf_evsel *evsel,perf_event__handler_t process); +int perf_event__synthesize_event_update_scale (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process);int perf_event__process_attr (struct perf_tool *tool,union perf_event *event,struct perf_evlist **pevlist); int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
Jiri Olsa
reviewerPATCH v5 23/52 perf tools: Add event_update event name type
In reply to Jiri OlsaAdding name type 'event update' event, that stores/transfer events name. Event's name is stored within perf.data's EVENT_DESC feature, but we don't have if we get report data from pipe.
--- tools/perf/tests/event_update.c | 25 +++++++++++++++++++++++++ tools/perf/util/event.h | 1 + tools/perf/util/header.c | 21 +++++++++++++++++++++ tools/perf/util/header.h | 3 +++ 4 files changed, 50 insertions(+)
tools/perf/tests/event_update.c +25 -0
@@ -34,10 +34,30 @@ static int process_event_scale(struct perf_tool *tool __maybe_unused,return 0 ; } +struct event_name { +struct perf_tool tool; +const char *name; +}; + +static int process_event_name (struct perf_tool *tool, +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ + struct event_name *tmp = container_of(tool, struct event_name, tool); +struct event_update_event *ev = (struct event_update_event *) event; + +TEST_ASSERT_VAL ("wrong id" , ev->id ==123 ); +TEST_ASSERT_VAL ("wrong id" , ev->type ==PERF_EVENT_UPDATE__NAME ); +TEST_ASSERT_VAL ("wrong name" , !strcmp (ev->data, tmp->name)); +return 0 ; +} +int test__event_update (void ) {struct perf_evlist *evlist;struct perf_evsel *evsel; +struct event_name tmp; evlist =perf_evlist__new_default ();TEST_ASSERT_VAL ("failed to get evlist" , evlist);
@@ -59,5 +79,10 @@ int test__event_update(void)TEST_ASSERT_VAL ("failed to synthesize attr update scale" , !perf_event__synthesize_event_update_scale (NULL , evsel, process_event_scale)); + tmp.name =perf_evsel__name (evsel); + +TEST_ASSERT_VAL ("failed to synthesize attr update name" , + !perf_event__synthesize_event_update_name (&tmp.tool, evsel, process_event_name)); +return 0 ; }
tools/perf/util/event.h +1 -0
@@ -311,6 +311,7 @@ struct attr_event {enum {PERF_EVENT_UPDATE__UNIT =0 ,PERF_EVENT_UPDATE__SCALE =1 , +PERF_EVENT_UPDATE__NAME =2 , };struct event_update_event_scale {
tools/perf/util/header.c +21 -0
@@ -2743,6 +2743,24 @@ perf_event__synthesize_event_update_scale(struct perf_tool *tool,return err; } +int +perf_event__synthesize_event_update_name (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process) +{ +struct event_update_event *ev; +size_t len =strlen (evsel->name); +int err; + + ev =event_update_event__alloc (len +1 ,PERF_EVENT_UPDATE__NAME , evsel->id[0 ]); +if (ev ==NULL ) +return -ENOMEM ; + +strncpy (ev->data, evsel->name, len); + err =process (tool, (union perf_event *) ev,NULL ,NULL ); +free (ev); +return err; +} int perf_event__synthesize_attrs(struct perf_tool *tool, struct perf_session *session,
@@ -2825,6 +2843,9 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,case PERF_EVENT_UPDATE__UNIT : evsel->unit =strdup (ev->data);break ; +case PERF_EVENT_UPDATE__NAME : + evsel->name =strdup (ev->data); +break ;case PERF_EVENT_UPDATE__SCALE : ev_scale = (struct event_update_event_scale *) ev->data; evsel->scale = ev_scale->scale;
tools/perf/util/header.h +3 -0
@@ -111,6 +111,9 @@ int perf_event__synthesize_event_update_unit(struct perf_tool *tool,int perf_event__synthesize_event_update_scale (struct perf_tool *tool,struct perf_evsel *evsel,perf_event__handler_t process); +int perf_event__synthesize_event_update_name (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process);int perf_event__process_attr (struct perf_tool *tool,union perf_event *event,struct perf_evlist **pevlist); int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add event_update event name type
perf tools: Add event_update event name type
Commit-ID: 802c9048b824eaa3c75d875e2d107460ad586439 Gitweb: http://git.kernel.org/tip/802c9048b824eaa3c75d875e2d107460ad586439 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:39 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 15:12:46 -0300
perf tools: Add event_update event name type
Adding name type 'event update' event, that stores/transfer events name. Event's name is stored within perf.data's EVENT_DESC feature, but we don't have it if we get the report data from pipe.
--- tools/perf/tests/event_update.c | 25 +++++++++++++++++++++++++ tools/perf/util/event.h | 1 + tools/perf/util/header.c | 21 +++++++++++++++++++++ tools/perf/util/header.h | 3 +++ 4 files changed, 50 insertions(+)
tools/perf/tests/event_update.c +25 -0
@@ -34,10 +34,30 @@ static int process_event_scale(struct perf_tool *tool __maybe_unused,return 0 ; } +struct event_name { +struct perf_tool tool; +const char *name; +}; + +static int process_event_name (struct perf_tool *tool, +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ + struct event_name *tmp = container_of(tool, struct event_name, tool); +struct event_update_event *ev = (struct event_update_event *) event; + +TEST_ASSERT_VAL ("wrong id" , ev->id ==123 ); +TEST_ASSERT_VAL ("wrong id" , ev->type ==PERF_EVENT_UPDATE__NAME ); +TEST_ASSERT_VAL ("wrong name" , !strcmp (ev->data, tmp->name)); +return 0 ; +} +int test__event_update (int subtest__maybe_unused ) {struct perf_evlist *evlist;struct perf_evsel *evsel; +struct event_name tmp; evlist =perf_evlist__new_default ();TEST_ASSERT_VAL ("failed to get evlist" , evlist);
@@ -59,5 +79,10 @@ int test__event_update(int subtest __maybe_unused)TEST_ASSERT_VAL ("failed to synthesize attr update scale" , !perf_event__synthesize_event_update_scale (NULL , evsel, process_event_scale)); + tmp.name =perf_evsel__name (evsel); + +TEST_ASSERT_VAL ("failed to synthesize attr update name" , + !perf_event__synthesize_event_update_name (&tmp.tool, evsel, process_event_name)); +return 0 ; }
tools/perf/util/event.h +1 -0
@@ -311,6 +311,7 @@ struct attr_event {enum {PERF_EVENT_UPDATE__UNIT =0 ,PERF_EVENT_UPDATE__SCALE =1 , +PERF_EVENT_UPDATE__NAME =2 , };struct event_update_event_scale {
tools/perf/util/header.c +21 -0
@@ -2743,6 +2743,24 @@ perf_event__synthesize_event_update_scale(struct perf_tool *tool,return err; } +int +perf_event__synthesize_event_update_name (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process) +{ +struct event_update_event *ev; +size_t len =strlen (evsel->name); +int err; + + ev =event_update_event__new (len +1 ,PERF_EVENT_UPDATE__NAME , evsel->id[0 ]); +if (ev ==NULL ) +return -ENOMEM ; + +strncpy (ev->data, evsel->name, len); + err =process (tool, (union perf_event *) ev,NULL ,NULL ); +free (ev); +return err; +} int perf_event__synthesize_attrs(struct perf_tool *tool, struct perf_session *session,
@@ -2825,6 +2843,9 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,case PERF_EVENT_UPDATE__UNIT : evsel->unit =strdup (ev->data);break ; +case PERF_EVENT_UPDATE__NAME : + evsel->name =strdup (ev->data); +break ;case PERF_EVENT_UPDATE__SCALE : ev_scale = (struct event_update_event_scale *) ev->data; evsel->scale = ev_scale->scale;
tools/perf/util/header.h +3 -0
@@ -111,6 +111,9 @@ int perf_event__synthesize_event_update_unit(struct perf_tool *tool,int perf_event__synthesize_event_update_scale (struct perf_tool *tool,struct perf_evsel *evsel,perf_event__handler_t process); +int perf_event__synthesize_event_update_name (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process);int perf_event__process_attr (struct perf_tool *tool,union perf_event *event,struct perf_evlist **pevlist); int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
Jiri Olsa
reviewerPATCH v5 24/52 perf tools: Add event_update event cpus type
In reply to Jiri OlsaAdding cpumask 'event update' event, that stores/transfer cpumask for event.
--- tools/perf/tests/event_update.c | 29 ++++++++++++++++++++++++++++ tools/perf/util/event.h | 5 +++++ tools/perf/util/header.c | 42 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/header.h | 3 +++ 4 files changed, 79 insertions(+)
tools/perf/tests/event_update.c +29 -0
@@ -53,6 +53,29 @@ static int process_event_name(struct perf_tool *tool,return 0 ; } +static int process_event_cpus (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ +struct event_update_event *ev = (struct event_update_event *) event; +struct event_update_event_cpus *ev_data; +struct cpu_map *map; + + ev_data = (struct event_update_event_cpus *) ev->data; + + map =cpu_map__new_data (&ev_data->cpus); + +TEST_ASSERT_VAL ("wrong id" , ev->id ==123 ); +TEST_ASSERT_VAL ("wrong type" , ev->type ==PERF_EVENT_UPDATE__CPUS ); +TEST_ASSERT_VAL ("wrong cpus" , map->nr ==3 ); +TEST_ASSERT_VAL ("wrong cpus" , map->map[0 ] ==1 ); +TEST_ASSERT_VAL ("wrong cpus" , map->map[1 ] ==2 ); +TEST_ASSERT_VAL ("wrong cpus" , map->map[2 ] ==3 ); +cpu_map__put (map); +return 0 ; +} +int test__event_update (void ) {struct perf_evlist *evlist;
@@ -84,5 +107,11 @@ int test__event_update(void)TEST_ASSERT_VAL ("failed to synthesize attr update name" , !perf_event__synthesize_event_update_name (&tmp.tool, evsel, process_event_name)); + evsel->own_cpus =cpu_map__new ("1,2,3" ); + +TEST_ASSERT_VAL ("failed to synthesize attr update cpus" , + !perf_event__synthesize_event_update_cpus (&tmp.tool, evsel, process_event_cpus)); + +cpu_map__put (evsel->own_cpus);return 0 ; }
tools/perf/util/event.h +5 -0
@@ -312,6 +312,11 @@ enum {PERF_EVENT_UPDATE__UNIT =0 ,PERF_EVENT_UPDATE__SCALE =1 ,PERF_EVENT_UPDATE__NAME =2 , + PERF_EVENT_UPDATE__CPUS = 3, +}; + +struct event_update_event_cpus { +struct cpu_map_data cpus; }; struct event_update_event_scale {
tools/perf/util/header.c +42 -0
62 lines not on this page · raw message
tools/perf/util/header.h +3 -0
@@ -114,6 +114,9 @@ int perf_event__synthesize_event_update_scale(struct perf_tool *tool,int perf_event__synthesize_event_update_name (struct perf_tool *tool,struct perf_evsel *evsel,perf_event__handler_t process); +int perf_event__synthesize_event_update_cpus (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process);int perf_event__process_attr (struct perf_tool *tool,union perf_event *event,struct perf_evlist **pevlist); int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add event_update event cpus type
perf tools: Add event_update event cpus type
Commit-ID: 86ebb09f96fe6886e1e5d53b648df5537ba859ca Gitweb: http://git.kernel.org/tip/86ebb09f96fe6886e1e5d53b648df5537ba859ca Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:40 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 15:13:38 -0300
perf tools: Add event_update event cpus type
Adding the cpumask 'event update' event, that stores/transfer the cpumask for a event.
--- tools/perf/tests/event_update.c | 29 ++++++++++++++++++++++++++++ tools/perf/util/event.h | 5 +++++ tools/perf/util/header.c | 42 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/header.h | 3 +++ 4 files changed, 79 insertions(+)
tools/perf/tests/event_update.c +29 -0
@@ -53,6 +53,29 @@ static int process_event_name(struct perf_tool *tool,return 0 ; } +static int process_event_cpus (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ +struct event_update_event *ev = (struct event_update_event *) event; +struct event_update_event_cpus *ev_data; +struct cpu_map *map; + + ev_data = (struct event_update_event_cpus *) ev->data; + + map =cpu_map__new_data (&ev_data->cpus); + +TEST_ASSERT_VAL ("wrong id" , ev->id ==123 ); +TEST_ASSERT_VAL ("wrong type" , ev->type ==PERF_EVENT_UPDATE__CPUS ); +TEST_ASSERT_VAL ("wrong cpus" , map->nr ==3 ); +TEST_ASSERT_VAL ("wrong cpus" , map->map[0 ] ==1 ); +TEST_ASSERT_VAL ("wrong cpus" , map->map[1 ] ==2 ); +TEST_ASSERT_VAL ("wrong cpus" , map->map[2 ] ==3 ); +cpu_map__put (map); +return 0 ; +} +int test__event_update (int subtest__maybe_unused ) {struct perf_evlist *evlist;
@@ -84,5 +107,11 @@ int test__event_update(int subtest __maybe_unused)TEST_ASSERT_VAL ("failed to synthesize attr update name" , !perf_event__synthesize_event_update_name (&tmp.tool, evsel, process_event_name)); + evsel->own_cpus =cpu_map__new ("1,2,3" ); + +TEST_ASSERT_VAL ("failed to synthesize attr update cpus" , + !perf_event__synthesize_event_update_cpus (&tmp.tool, evsel, process_event_cpus)); + +cpu_map__put (evsel->own_cpus);return 0 ; }
tools/perf/util/event.h +5 -0
@@ -312,6 +312,11 @@ enum {PERF_EVENT_UPDATE__UNIT =0 ,PERF_EVENT_UPDATE__SCALE =1 ,PERF_EVENT_UPDATE__NAME =2 , + PERF_EVENT_UPDATE__CPUS = 3, +}; + +struct event_update_event_cpus { +struct cpu_map_data cpus; }; struct event_update_event_scale {
tools/perf/util/header.c +42 -0
62 lines not on this page · raw message
tools/perf/util/header.h +3 -0
@@ -114,6 +114,9 @@ int perf_event__synthesize_event_update_scale(struct perf_tool *tool,int perf_event__synthesize_event_update_name (struct perf_tool *tool,struct perf_evsel *evsel,perf_event__handler_t process); +int perf_event__synthesize_event_update_cpus (struct perf_tool *tool, +struct perf_evsel *evsel, +perf_event__handler_t process);int perf_event__process_attr (struct perf_tool *tool,union perf_event *event,struct perf_evlist **pevlist); int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
Jiri Olsa
reviewerPATCH v5 25/52 perf tools: Add perf_event__fprintf_event_update function
In reply to Jiri OlsaTo display 'event update' event for raw dump.
--- tools/perf/util/header.c | 38 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/header.h | 1 + 2 files changed, 39 insertions(+)
tools/perf/util/header.c +38 -0
@@ -2793,6 +2793,44 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool,return err; } +size_t perf_event__fprintf_event_update (union perf_event *event,FILE *fp) +{ +struct event_update_event *ev = &event->event_update; +struct event_update_event_scale *ev_scale; +struct event_update_event_cpus *ev_cpus; +struct cpu_map *map; +size_t ret; + + ret =fprintf (fp,"\n... id: %" PRIu64"\n" , ev->id); + +switch (ev->type) { +case PERF_EVENT_UPDATE__SCALE : + ev_scale = (struct event_update_event_scale *) ev->data; + ret +=fprintf (fp,"... scale: %f\n" , ev_scale->scale); +break ; +case PERF_EVENT_UPDATE__UNIT : + ret +=fprintf (fp,"... unit: %s\n" , ev->data); +break ; +case PERF_EVENT_UPDATE__NAME : + ret +=fprintf (fp,"... name: %s\n" , ev->data); +break ; +case PERF_EVENT_UPDATE__CPUS : + ev_cpus = (struct event_update_event_cpus *) ev->data; + ret +=fprintf (fp,"... " ); + + map =cpu_map__new_data (&ev_cpus->cpus); +if (map) + ret +=cpu_map__fprintf (map, fp); +else + ret +=fprintf (fp,"failed to get cpus\n" ); +break ; +default : + ret +=fprintf (fp,"... unknown type\n" ); +break ; + } + +return ret; +} int perf_event__synthesize_attrs(struct perf_tool *tool, struct perf_session *session,
tools/perf/util/header.h +1 -0
@@ -122,6 +122,7 @@ int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,int perf_event__process_event_update (struct perf_tool *tool__maybe_unused ,union perf_event *event,struct perf_evlist **pevlist); +size_t perf_event__fprintf_event_update (union perf_event *event,FILE *fp); int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct perf_evlist *evlist,
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Add perf_event__fprintf_event_update function
perf tools: Add perf_event__fprintf_event_update function
Commit-ID: c853f9394b7bc189632673cac802bdbf6537463b Gitweb: http://git.kernel.org/tip/c853f9394b7bc189632673cac802bdbf6537463b Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:41 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 15:14:36 -0300
perf tools: Add perf_event__fprintf_event_update function
To display a 'event update' event for raw dump.
--- tools/perf/util/header.c | 38 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/header.h | 1 + 2 files changed, 39 insertions(+)
tools/perf/util/header.c +38 -0
@@ -2793,6 +2793,44 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool,return err; } +size_t perf_event__fprintf_event_update (union perf_event *event,FILE *fp) +{ +struct event_update_event *ev = &event->event_update; +struct event_update_event_scale *ev_scale; +struct event_update_event_cpus *ev_cpus; +struct cpu_map *map; +size_t ret; + + ret =fprintf (fp,"\n... id: %" PRIu64"\n" , ev->id); + +switch (ev->type) { +case PERF_EVENT_UPDATE__SCALE : + ev_scale = (struct event_update_event_scale *) ev->data; + ret +=fprintf (fp,"... scale: %f\n" , ev_scale->scale); +break ; +case PERF_EVENT_UPDATE__UNIT : + ret +=fprintf (fp,"... unit: %s\n" , ev->data); +break ; +case PERF_EVENT_UPDATE__NAME : + ret +=fprintf (fp,"... name: %s\n" , ev->data); +break ; +case PERF_EVENT_UPDATE__CPUS : + ev_cpus = (struct event_update_event_cpus *) ev->data; + ret +=fprintf (fp,"... " ); + + map =cpu_map__new_data (&ev_cpus->cpus); +if (map) + ret +=cpu_map__fprintf (map, fp); +else + ret +=fprintf (fp,"failed to get cpus\n" ); +break ; +default : + ret +=fprintf (fp,"... unknown type\n" ); +break ; + } + +return ret; +} int perf_event__synthesize_attrs(struct perf_tool *tool, struct perf_session *session,
tools/perf/util/header.h +1 -0
@@ -122,6 +122,7 @@ int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,int perf_event__process_event_update (struct perf_tool *tool__maybe_unused ,union perf_event *event,struct perf_evlist **pevlist); +size_t perf_event__fprintf_event_update (union perf_event *event,FILE *fp); int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct perf_evlist *evlist,
Jiri Olsa
reviewerPATCH v5 26/52 perf report: Display newly added events in raw dump
In reply to Jiri OlsaThe 'perf report -D' command will now display dump and detailed output for newly added events:
event_update
thread_map
cpu_map
stat
stat_config
stat_round
--- tools/perf/util/session.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
tools/perf/util/session.c +19 -0
@@ -17,6 +17,7 @@#include "asm/bug.h" #include "auxtrace.h" #include "thread-stack.h" +#include "stat.h" static int perf_session__deliver_event(struct perf_session *session, union perf_event *event,
@@ -210,6 +211,9 @@ static int process_event_synth_event_update_stub(struct perf_tool *tool __maybe_struct perf_evlist **pevlist __maybe_unused) { +if (dump_trace) +perf_event__fprintf_event_update (event, stdout); +dump_printf (": unhandled!\n" );return 0 ; }
@@ -311,6 +315,9 @@ int process_event_thread_map_stub(struct perf_tool *tool __maybe_unused,union perf_event *event__maybe_unused , struct perf_session *session __maybe_unused) { + if (dump_trace) + perf_event__fprintf_thread_map(event, stdout); + dump_printf(": unhandled!\n");return 0 ; }
@@ -320,6 +327,9 @@ int process_event_cpu_map_stub(struct perf_tool *tool __maybe_unused,union perf_event *event__maybe_unused , struct perf_session *session __maybe_unused) { + if (dump_trace) + perf_event__fprintf_cpu_map(event, stdout); + dump_printf(": unhandled!\n");return 0 ; }
@@ -329,6 +339,9 @@ int process_event_stat_config_stub(struct perf_tool *tool __maybe_unused,union perf_event *event__maybe_unused , struct perf_session *session __maybe_unused) { + if (dump_trace) + perf_event__fprintf_stat_config(event, stdout); + dump_printf(": unhandled!\n");return 0 ; }
@@ -338,6 +351,9 @@ static int process_stat_stub(struct perf_tool *tool __maybe_unused,struct perf_session *perf_session __maybe_unused) { +if (dump_trace) +perf_event__fprintf_stat (event, stdout); +dump_printf (": unhandled!\n" );return 0 ; }
@@ -347,6 +363,9 @@ static int process_stat_round_stub(struct perf_tool *tool __maybe_unused,struct perf_session *perf_session __maybe_unused) { +if (dump_trace) +perf_event__fprintf_stat_round (event, stdout); +dump_printf (": unhandled!\n" );return 0 ; }
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf report: Display newly added events in raw dump
perf report: Display newly added events in raw dump
Commit-ID: 2d2aea6ae736503d3896c4997b494760ed8febc1 Gitweb: http://git.kernel.org/tip/2d2aea6ae736503d3896c4997b494760ed8febc1 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:42 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 15:15:13 -0300
perf report: Display newly added events in raw dump
The 'perf report -D' command will now display detailed output for these newly added events:
event_update
thread_map
cpu_map
stat
stat_config
stat_round
--- tools/perf/util/session.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
tools/perf/util/session.c +19 -0
@@ -17,6 +17,7 @@#include "asm/bug.h" #include "auxtrace.h" #include "thread-stack.h" +#include "stat.h" static int perf_session__deliver_event(struct perf_session *session, union perf_event *event,
@@ -210,6 +211,9 @@ static int process_event_synth_event_update_stub(struct perf_tool *tool __maybe_struct perf_evlist **pevlist __maybe_unused) { +if (dump_trace) +perf_event__fprintf_event_update (event, stdout); +dump_printf (": unhandled!\n" );return 0 ; }
@@ -311,6 +315,9 @@ int process_event_thread_map_stub(struct perf_tool *tool __maybe_unused,union perf_event *event__maybe_unused , struct perf_session *session __maybe_unused) { + if (dump_trace) + perf_event__fprintf_thread_map(event, stdout); + dump_printf(": unhandled!\n");return 0 ; }
@@ -320,6 +327,9 @@ int process_event_cpu_map_stub(struct perf_tool *tool __maybe_unused,union perf_event *event__maybe_unused , struct perf_session *session __maybe_unused) { + if (dump_trace) + perf_event__fprintf_cpu_map(event, stdout); + dump_printf(": unhandled!\n");return 0 ; }
@@ -329,6 +339,9 @@ int process_event_stat_config_stub(struct perf_tool *tool __maybe_unused,union perf_event *event__maybe_unused , struct perf_session *session __maybe_unused) { + if (dump_trace) + perf_event__fprintf_stat_config(event, stdout); + dump_printf(": unhandled!\n");return 0 ; }
@@ -338,6 +351,9 @@ static int process_stat_stub(struct perf_tool *tool __maybe_unused,struct perf_session *perf_session __maybe_unused) { +if (dump_trace) +perf_event__fprintf_stat (event, stdout); +dump_printf (": unhandled!\n" );return 0 ; }
@@ -347,6 +363,9 @@ static int process_stat_round_stub(struct perf_tool *tool __maybe_unused,struct perf_session *perf_session __maybe_unused) { +if (dump_trace) +perf_event__fprintf_stat_round (event, stdout); +dump_printf (": unhandled!\n" );return 0 ; }
Jiri Olsa
reviewerPATCH v5 27/52 perf tools: Introduce stat feature
In reply to Jiri OlsaIntroducing stat feature to mark perf.data as created by perf stat record command. It contains no data.
It's needed for report tools (report/script) to differentiate sampling data from stat data, because they need to be treated in a different way.
In future it might be used to store version of the stat storage system we used.
--- tools/perf/builtin-record.c | 2 ++ tools/perf/util/header.c | 14 ++++++++++++++ tools/perf/util/header.h | 1 + 3 files changed, 17 insertions(+)
tools/perf/builtin-record.c +2 -0
@@ -451,6 +451,8 @@ static void record__init_features(struct record *rec)if (!rec->opts.full_auxtrace)perf_header__clear_feat (&session->header,HEADER_AUXTRACE ); + +perf_header__clear_feat (&session->header,HEADER_STAT ); }static volatile int workload_exec_errno;
tools/perf/util/header.c +14 -0
@@ -868,6 +868,13 @@ static int write_auxtrace(int fd, struct perf_header *h,return err; } +static int write_stat (int fd__maybe_unused , +struct perf_header *h__maybe_unused , +struct perf_evlist *evlist__maybe_unused ) +{ +return 0 ; +} +static void print_hostname (struct perf_header *ph,int fd__maybe_unused ,FILE *fp) {
@@ -1159,6 +1166,12 @@ static void print_auxtrace(struct perf_header *ph __maybe_unused,fprintf (fp,"# contains AUX area data (e.g. instruction trace)\n" ); } +static void print_stat (struct perf_header *ph__maybe_unused , +int fd__maybe_unused ,FILE *fp) +{ +fprintf (fp,"# contains stat data\n" ); +} +static void print_pmu_mappings (struct perf_header *ph,int fd__maybe_unused ,FILE *fp) {
@@ -1948,6 +1961,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {FEAT_OPP (HEADER_PMU_MAPPINGS , pmu_mappings),FEAT_OPP (HEADER_GROUP_DESC , group_desc),FEAT_OPP (HEADER_AUXTRACE , auxtrace), + FEAT_OPA(HEADER_STAT, stat), }; struct header_print_data {
tools/perf/util/header.h +1 -0
@@ -31,6 +31,7 @@ enum {HEADER_PMU_MAPPINGS ,HEADER_GROUP_DESC ,HEADER_AUXTRACE , +HEADER_STAT ,HEADER_LAST_FEATURE , HEADER_FEAT_BITS = 256, };
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Introduce stat perf.data header feature
perf tools: Introduce stat perf.data header feature
Commit-ID: ffa517adf625fa6a6c168285534e1ff7344fa2f1 Gitweb: http://git.kernel.org/tip/ffa517adf625fa6a6c168285534e1ff7344fa2f1 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:43 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 17 Dec 2015 15:15:14 -0300
perf tools: Introduce stat perf.data header feature
Introducing the 'stat' feature to mark a perf.data as created by the 'perf stat record' command. It contains no data.
It's needed so that the report tools (report/script) can differentiate sampling data from counting data, because they need to be treated in a different way.
In the future it might be used to store the version of the stat storage system used.
--- tools/perf/builtin-record.c | 2 ++ tools/perf/util/header.c | 14 ++++++++++++++ tools/perf/util/header.h | 1 + 3 files changed, 17 insertions(+)
tools/perf/builtin-record.c +2 -0
@@ -452,6 +452,8 @@ static void record__init_features(struct record *rec)if (!rec->opts.full_auxtrace)perf_header__clear_feat (&session->header,HEADER_AUXTRACE ); + +perf_header__clear_feat (&session->header,HEADER_STAT ); }static volatile int workload_exec_errno;
tools/perf/util/header.c +14 -0
@@ -868,6 +868,13 @@ static int write_auxtrace(int fd, struct perf_header *h,return err; } +static int write_stat (int fd__maybe_unused , +struct perf_header *h__maybe_unused , +struct perf_evlist *evlist__maybe_unused ) +{ +return 0 ; +} +static void print_hostname (struct perf_header *ph,int fd__maybe_unused ,FILE *fp) {
@@ -1159,6 +1166,12 @@ static void print_auxtrace(struct perf_header *ph __maybe_unused,fprintf (fp,"# contains AUX area data (e.g. instruction trace)\n" ); } +static void print_stat (struct perf_header *ph__maybe_unused , +int fd__maybe_unused ,FILE *fp) +{ +fprintf (fp,"# contains stat data\n" ); +} +static void print_pmu_mappings (struct perf_header *ph,int fd__maybe_unused ,FILE *fp) {
@@ -1948,6 +1961,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {FEAT_OPP (HEADER_PMU_MAPPINGS , pmu_mappings),FEAT_OPP (HEADER_GROUP_DESC , group_desc),FEAT_OPP (HEADER_AUXTRACE , auxtrace), + FEAT_OPA(HEADER_STAT, stat), }; struct header_print_data {
tools/perf/util/header.h +1 -0
@@ -31,6 +31,7 @@ enum {HEADER_PMU_MAPPINGS ,HEADER_GROUP_DESC ,HEADER_AUXTRACE , +HEADER_STAT ,HEADER_LAST_FEATURE , HEADER_FEAT_BITS = 256, };
Jiri Olsa
reviewerPATCH v5 28/52 perf tools: Move id_offset out of struct perf_evsel union
In reply to Jiri OlsaBecause following stat patches use id_offset together with priv pointer.
--- tools/perf/util/evsel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/evsel.h +1 -1
@@ -90,9 +90,9 @@ struct perf_evsel {double scale;const char *unit;struct event_format *tp_format; +off_t id_offset;union {void *priv; -off_t id_offset;u64 db_id; };struct cgroup_sel *cgrp;
Signature · 1 line
2.4.3
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf evsel: Move id_offset out of struct perf_evsel union member
perf evsel: Move id_offset out of struct perf_evsel union member
Commit-ID: af3399817428d8adc2c87c91df23fde77dbcdb35 Gitweb: http://git.kernel.org/tip/af3399817428d8adc2c87c91df23fde77dbcdb35 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 25 Oct 2015 15:51:44 +0100 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Tue, 27 Oct 2015 15:04:29 -0300
perf evsel: Move id_offset out of struct perf_evsel union member
Because the 'perf stat record' patches will use the id_offset member together with the priv pointer.
--- tools/perf/util/evsel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/evsel.h +1 -1
@@ -90,9 +90,9 @@ struct perf_evsel {double scale;const char *unit;struct event_format *tp_format; +off_t id_offset;union {void *priv; -off_t id_offset;u64 db_id; };struct cgroup_sel *cgrp;
Jiri Olsa
reviewerPATCH v5 29/52 perf stat record: Add record command
In reply to Jiri OlsaAdd 'perf stat record' command support. It creates simple (header only) perf.data file ATM.
--- tools/perf/Documentation/perf-stat.txt | 12 ++++++ tools/perf/builtin-stat.c | 74 +++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-)
tools/perf/Documentation/perf-stat.txt +12 -0
@@ -10,6 +10,7 @@ SYNOPSIS [verse] 'perf stat' [-e <EVENT> | --event=EVENT] [-a] <command> 'perf stat' [-e <EVENT> | --event=EVENT] [-a] -- <command> [<options>] +'perf stat' [-e <EVENT> | --event=EVENT] [-a] record [-o file] -- <command> [<options>] DESCRIPTION -----------
@@ -22,6 +23,8 @@ OPTIONS <command>...:: Any command you can specify in a shell. +record:: + See STAT RECORD. -e:: --event=::
@@ -159,6 +162,15 @@ filter out the startup phase of the program, which is often very different. Print statistics of transactional execution if supported. +STAT RECORD +----------- +Stores stat data into perf data file. + +-o file:: +--output file:: +Output file name. + + EXAMPLES --------
tools/perf/builtin-stat.c +72 -2
116 lines not on this page · raw message
Signature · 1 line
2.4.3
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 29/52] perf stat record: Add record command
Em Sun, Oct 25, 2015 at 03:51:45PM +0100, Jiri Olsa escreveu:
Quoted 2 lines
Add 'perf stat record' command support. It creates simple (header only) perf.data file ATM.
Huh? Couldn't we have the tools providing a sensible message at this point?
[root@zoo linux]# rm -f perf.data
[root@zoo linux]# perf stat record usleep 1
Performance counter stats for 'usleep 1':
0.575678 task-clock (msec) # 0.508 CPUs utilized
1 context-switches # 0.002 M/sec
0 cpu-migrations # 0.000 K/sec
52 page-faults # 0.090 M/sec
905601 cycles # 1.573 GHz
608259 stalled-cycles-frontend # 67.17% frontend cycles idle
<not supported> stalled-cycles-backend
616889 instructions # 0.68 insns per cycle # 0.99 stalled cycles per insn
125710 branches # 218.369 M/sec
7589 branch-misses # 6.04% of all branches
0.001134076 seconds time elapsed
[root@zoo linux]# perf evlist
WARNING: The perf.data file's data size field is 0 which is unexpected. Was the 'perf record' command properly terminated?
non matching sample_type[root@zoo linux]#
[root@zoo linux]# perf report --stdio
WARNING: The perf.data file's data size field is 0 which is unexpected. Was the 'perf record' command properly terminated?
non matching sample_type[root@zoo linux]#
---------------------------------------------------------------------------------------
Can't we make it so that older tools will juts state that there are no samples, i.e.:
[root@zoo linux]# perf record -e alignment-faults usleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.018 MB perf.data ]
[root@zoo linux]# perf evlist
alignment-faults
[root@zoo linux]# perf report --stdio
Error:
The perf.data file has no samples!
# To display the perf.data header info, please use --header/--header-only options. #
[root@zoo linux]#
--------------------------------------------------------------------------------
This looks a friendlier message, as the 'perf stat record' file really has no samples, by definition :-)
This is not a show stopper tho, to make progress, I'll continue processing the patches here, but please consider changing this patch to improve the output produced by older tools.
- Arnaldo
Quoted 173 lines
Signed-off-by Jiri Olsa <[email protected]>--- tools/perf/Documentation/perf-stat.txt | 12 ++++++ tools/perf/builtin-stat.c | 74 +++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-)tools/perf/Documentation/perf-stat.txt +12
-0@@ -10,6 +10,7 @@ SYNOPSIS [verse] 'perf stat' [-e <EVENT> | --event=EVENT] [-a] <command> 'perf stat' [-e <EVENT> | --event=EVENT] [-a] -- <command> [<options>] +'perf stat' [-e <EVENT> | --event=EVENT] [-a] record [-o file] -- <command> [<options>] DESCRIPTION -----------@@ -22,6 +23,8 @@ OPTIONS <command>...:: Any command you can specify in a shell. +record:: + See STAT RECORD. -e:: --event=::@@ -159,6 +162,15 @@ filter out the startup phase of the program, which is often very different. Print statistics of transactional execution if supported. +STAT RECORD +----------- +Stores stat data into perf data file. + +-o file:: +--output file:: +Output file name. + + EXAMPLES --------tools/perf/builtin-stat.c +72
-2@@ -59,6 +59,7 @@#include "util/thread.h" #include "util/thread_map.h" #include "util/counts.h" +#include "util/session.h" #include <stdlib.h> #include <sys/prctl.h> @@ -123,6 +124,16 @@ static struct timespec ref_time;static struct cpu_map *aggr_map;static aggr_get_id_t aggr_get_id; +struct perf_stat { +bool record; +struct perf_data_file file; +struct perf_session *session; +u64 bytes_written; +}; + +static struct perf_stat perf_stat; +#define STAT_RECORD perf_stat.record +static volatile int done =0 ;static struct perf_stat_config stat_config = {@@ -341,6 +352,15 @@ static int __run_perf_stat(int argc, const char **argv)return -1 ; } +if (STAT_RECORD ) { +int err, fd =perf_data_file__fd (&perf_stat.file); + + err =perf_session__write_header (perf_stat.session, evsel_list, + fd, false); +if (err <0 ) +return err; + } +/* * Enable counters and exec the command: */ @@ -1192,6 +1212,39 @@ static int add_default_attributes(void)return perf_evlist__add_default_attrs (evsel_list, very_very_detailed_attrs); } +static const char *const recort_usage[] = { +"perf stat record [<options>]" , +NULL , +}; + +static int __cmd_record (int argc,const char **argv) +{ +struct perf_session *session; +struct perf_data_file *file = &perf_stat.file; +const struct option options[] = { +OPT_STRING ('o' ,"output" , &perf_stat.file.path,"file" ,"output file name" ), +OPT_END () + }; + + argc =parse_options (argc, argv, options, record_usage, +PARSE_OPT_STOP_AT_NON_OPTION ); + + session =perf_session__new (file, false,NULL ); +if (session ==NULL ) { +pr_err ("Perf session creation failed.\n" ); +return -1 ; + } + +/* No pipe support ATM */ +if (perf_stat.file.is_pipe) +return -EINVAL ; + + session->evlist = evsel_list; + perf_stat.session = session; + perf_stat.record = true; +return argc; +} +int cmd_stat (int argc,const char **argv,const char *prefix__maybe_unused ) {bool append_file = false;@@ -1265,6 +1318,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)const char *mode;FILE *output = stderr;unsigned int interval; +const char *const stat_subcommands[] = {"record" };setlocale (LC_ALL ,"" );@@ -1272,8 +1326,15 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)if (evsel_list ==NULL )return -ENOMEM ; - argc =parse_options (argc, argv, options, stat_usage, -PARSE_OPT_STOP_AT_NON_OPTION ); + argc =parse_options_subcommand (argc, argv, options, stat_subcommands, + (const char **) stat_usage, +PARSE_OPT_STOP_AT_NON_OPTION ); + +if (argc && !strncmp (argv[0 ],"rec" ,3 )) { + argc =__cmd_record (argc, argv); +if (argc <0 ) +return -1 ; + } interval = stat_config.interval;@@ -1444,6 +1505,15 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)if (!forever && status !=-1 && !interval)print_counters (NULL , argc, argv); +if (STAT_RECORD ) { +int fd =perf_data_file__fd (&perf_stat.file); + + perf_stat.session->header.data_size += perf_stat.bytes_written; +perf_session__write_header (perf_stat.session, evsel_list, fd, true); + +perf_session__delete (perf_stat.session); + } +perf_evlist__free_stats (evsel_list); out:perf_evlist__delete (evsel_list);Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 30/52 perf stat record: Initialize record features
In reply to Jiri OlsaDisabling all non stat related features.
--- tools/perf/builtin-stat.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
tools/perf/builtin-stat.c +15 -0
@@ -1217,6 +1217,19 @@ static const char * const recort_usage[] = { NULL, }; +static void init_features (struct perf_session *session) +{ +int feat; + +for (feat =HEADER_FIRST_FEATURE ; feat <HEADER_LAST_FEATURE ; feat++) +perf_header__set_feat (&session->header, feat); + +perf_header__clear_feat (&session->header,HEADER_BUILD_ID ); +perf_header__clear_feat (&session->header,HEADER_TRACING_DATA ); +perf_header__clear_feat (&session->header,HEADER_BRANCH_STACK ); +perf_header__clear_feat (&session->header,HEADER_AUXTRACE ); +} +static int __cmd_record (int argc,const char **argv) {struct perf_session *session;
@@ -1239,6 +1252,8 @@ static int __cmd_record(int argc, const char **argv)if (perf_stat.file.is_pipe)return -EINVAL ; +init_features (session); + session->evlist = evsel_list; perf_stat.session = session; perf_stat.record = true;
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 31/52 perf stat record: Synthesize stat record data
In reply to Jiri OlsaSynthesizing needed stat record data for report/script:
- cpu/thread maps
- stat config
--- tools/perf/builtin-stat.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
tools/perf/builtin-stat.c +47 -0
@@ -193,6 +193,20 @@ static inline int nsec_counter(struct perf_evsel *evsel)return 0 ; } +static int process_synthesized_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_sample *sample__maybe_unused , +struct machine *machine__maybe_unused ) +{ +if (perf_data_file__write (&perf_stat.file, event, event->header.size) <0 ) { +pr_err ("failed to write perf data, error: %m\n" ); +return -1 ; + } + + perf_stat.bytes_written += event->header.size; +return 0 ; +} +/* * Read out the results of a single counter: * do not aggregate counts across CPUs in system-wide mode
@@ -279,6 +293,35 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf workload_exec_errno = info->si_value.sival_int; } +static int perf_stat_synthesize_config (void ) +{ +int err; + + err =perf_event__synthesize_thread_map2 (NULL , evsel_list->threads, + process_synthesized_event, +NULL ); +if (err <0 ) { +pr_err ("Couldn't synthesize thread map.\n" ); +return err; + } + + err =perf_event__synthesize_cpu_map (NULL , evsel_list->cpus, + process_synthesized_event,NULL ); +if (err <0 ) { +pr_err ("Couldn't synthesize thread map.\n" ); +return err; + } + + err =perf_event__synthesize_stat_config (NULL , &stat_config, + process_synthesized_event,NULL ); +if (err <0 ) { +pr_err ("Couldn't synthesize config.\n" ); +return err; + } + +return 0 ; +} +static int __run_perf_stat (int argc,const char **argv) {int interval = stat_config.interval;
@@ -359,6 +402,10 @@ static int __run_perf_stat(int argc, const char **argv) fd, false);if (err <0 )return err; + + err =perf_stat_synthesize_config (); +if (err <0 ) +return err; }/*
Signature · 1 line
2.4.3
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 31/52] perf stat record: Synthesize stat record data
Em Sun, Oct 25, 2015 at 03:51:47PM +0100, Jiri Olsa escreveu:
Quoted 3 lines
Synthesizing needed stat record data for report/script:
- cpu/thread maps
- stat config
After this it gets a bit better, but then I expected that to specify an event I would be able to use:
[root@zoo linux]# perf stat record -e cycles usleep 1
Error: unknown switch `e'
Usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]
-o, --output <file> output file name
But I need to do it as:
[root@zoo linux]# perf stat -e cycles record usleep 1
Performance counter stats for 'usleep 1':
948417 cycles
0.000749965 seconds time elapsed[root@zoo linux]#
--------------------------------------------------
This is confusing...
Anyway, now the perf.data file doesn't produce that many confusing messages, just one, and the error reporting continues needing a newline, oops just noticed another problem:
[root@zoo linux]# perf stat record usleep 1
Performance counter stats for 'usleep 1':
0.520959 task-clock (msec) # 0.504 CPUs utilized
1 context-switches # 0.002 M/sec
0 cpu-migrations # 0.000 K/sec
51 page-faults # 0.098 M/sec
929738 cycles # 1.785 GHz
625885 stalled-cycles-frontend # 67.32% frontend cycles idle
<not supported> stalled-cycles-backend
634514 instructions # 0.68 insns per cycle # 0.99 stalled cycles per insn
128859 branches # 247.350 M/sec
7602 branch-misses # 5.90% of all branches
0.001034675 seconds time elapsed
[root@zoo linux]# perf evlist
non matching sample_type[root@zoo linux]#
But, if I specify an event:
[root@zoo linux]# perf stat -e cycles record usleep 1
Performance counter stats for 'usleep 1':
876987 cycles
0.001285050 seconds time elapsed[root@zoo linux]# perf evlist
cycles
[root@zoo linux]# perf evlist -v
cycles: size: 112, read_format: TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING, disabled: 1, inherit: 1, enable_on_exec: 1, exclude_guest: 1 [root@zoo linux]#
-------------------------
It then works as expected, lists the event collected, no confusing message about 'sample_type' stuff is emitted.
Ditto for 'perf report'
[root@zoo linux]# perf report --stdio
Warning:
Kernel address maps (/proc/{kallsyms,modules}) were restricted.
Check /proc/sys/kernel/kptr_restrict before running 'perf record'.
As no suitable kallsyms nor vmlinux was found, kernel samples can't be resolved.
Samples in kernel modules can't be resolved as well.
Error:
The perf.data file has no samples!
# To display the perf.data header info, please use --header/--header-only options. #
[root@zoo linux]#
------------------------------------------------
I.e. when I explicitely state what events should be collected, it behaves nicely, modulo this message about kernel address maps being restricted in 'report', so it looks like just some fix is needed to make it work like that when no events are specified.
So, I'm creating a perf/stat branch and putting what I processed so far, with the changelog edits and changes in some function/struct names I partially mentioned, please try to continue from there, ok?
- Arnaldo
Re: [PATCH 31/52] perf stat record: Synthesize stat record data
On Tue, Oct 27, 2015 at 11:42:44AM -0300, Arnaldo Carvalho de Melo wrote:
SNIP
Quoted 4 lines
So, I'm creating a perf/stat branch and putting what I processed so far, with the changelog edits and changes in some function/struct names I partially mentioned, please try to continue from there, ok?
ok, I'll rebase the rest on yours perf/stat
thanks,
jirka
Re: [PATCH 31/52] perf stat record: Synthesize stat record data
In reply to Arnaldo Carvalho de MeloQuoted 27 lines · Arnaldo Carvalho de Melo
Em Sun, Oct 25, 2015 at 03:51:47PM +0100, Jiri Olsa escreveu:
Quoted 3 lines
Synthesizing needed stat record data for report/script:
- cpu/thread maps
- stat configAfter this it gets a bit better, but then I expected that to specify an event I would be able to use:
[root@zoo linux]# perf stat record -e cycles usleep 1
Error: unknown switch `e'Usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]-o, --output <file> output file name
But I need to do it as:
[root@zoo linux]# perf stat -e cycles record usleep 1
Performance counter stats for 'usleep 1':
948417 cycles 0.000749965 seconds time elapsed
Quoted 5 lines
[root@zoo linux]#
--------------------------------------------------
This is confusing...
yep, the thing is that we need to have all the options supported by perf stat to work under perf stat record.
you basically let user use perf stat with 'record' that just says 'store the data I'm monitoring'
I'll try to find some way to move the options under perf stat record without too many changes.. but not sure
jirka
Re: [PATCH 31/52] perf stat record: Synthesize stat record data
In reply to Arnaldo Carvalho de MeloOn Tue, Oct 27, 2015 at 11:42:44AM -0300, Arnaldo Carvalho de Melo wrote:
SNIP
Quoted 18 lines
This is confusing...
Anyway, now the perf.data file doesn't produce that many confusing messages, just one, and the error reporting continues needing a newline, oops just noticed another problem:
[root@zoo linux]# perf stat record usleep 1
Performance counter stats for 'usleep 1':
0.520959 task-clock (msec) # 0.504 CPUs utilized 1 context-switches # 0.002 M/sec 0 cpu-migrations # 0.000 K/sec 51 page-faults # 0.098 M/sec 929738 cycles # 1.785 GHz 625885 stalled-cycles-frontend # 67.32% frontend cycles idle <not supported> stalled-cycles-backend 634514 instructions # 0.68 insns per cycle
Quoted 8 lines
# 0.99 stalled cycles per insn
128859 branches # 247.350 M/sec
7602 branch-misses # 5.90% of all branches0.001034675 seconds time elapsed
[root@zoo linux]# perf evlist
non matching sample_type[root@zoo linux]#
will check, thanks,
jirka
Jiri Olsa
reviewerPATCH v5 32/52 perf stat record: Store events IDs in perf data file
In reply to Jiri OlsaStore event IDs in evlist object so it get stored
into perf.data file.
Also making perf_evlist__id_add_fd global.
--- tools/perf/builtin-stat.c | 35 +++++++++++++++++++++++++++++++++++ tools/perf/util/evlist.c | 6 +++--- tools/perf/util/evlist.h | 3 +++ 3 files changed, 41 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +35 -0
@@ -322,6 +322,38 @@ static int perf_stat_synthesize_config(void)return 0 ; } +#define FD (e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) + +static int __store_counter_ids (struct perf_evsel *counter, +struct cpu_map *cpus, +struct thread_map *threads) +{ +int cpu, thread; + +for (cpu =0 ; cpu < cpus->nr; cpu++) { +for (thread =0 ; thread < threads->nr; thread++) { +int fd =FD (counter, cpu, thread); + +if (perf_evlist__id_add_fd (evsel_list, counter, + cpu, thread, fd) <0 ) +return -1 ; + } + } + +return 0 ; +} + +static int store_counter_ids (struct perf_evsel *counter) +{ +struct cpu_map *cpus = counter->cpus; +struct thread_map *threads = counter->threads; + +if (perf_evsel__alloc_id (counter, cpus->nr, threads->nr)) +return -ENOMEM ; + +return __store_counter_ids (counter, cpus, threads); +} +static int __run_perf_stat (int argc,const char **argv) {int interval = stat_config.interval;
@@ -386,6 +418,9 @@ static int __run_perf_stat(int argc, const char **argv) l =strlen (counter->unit);if (l > unit_width) unit_width = l; + +if (STAT_RECORD &&store_counter_ids (counter)) +return -1 ; }if (perf_evlist__apply_filters (evsel_list, &counter)) {
tools/perf/util/evlist.c +3 -3
@@ -550,9 +550,9 @@ void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, evsel->id[evsel->ids++] = id; } -static int perf_evlist__id_add_fd (struct perf_evlist *evlist, -struct perf_evsel *evsel, -int cpu,int thread,int fd) +int perf_evlist__id_add_fd (struct perf_evlist *evlist, +struct perf_evsel *evsel, +int cpu,int thread,int fd) {u64 read_data[4 ] = {0 , };int id_idx =1 ;/* The first entry is the counter value */
tools/perf/util/evlist.h +3 -0
@@ -97,6 +97,9 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,void perf_evlist__id_add (struct perf_evlist *evlist,struct perf_evsel *evsel,int cpu,int thread,u64 id); +int perf_evlist__id_add_fd (struct perf_evlist *evlist, +struct perf_evsel *evsel, +int cpu,int thread,int fd);int perf_evlist__add_pollfd (struct perf_evlist *evlist,int fd);int perf_evlist__alloc_pollfd (struct perf_evlist *evlist);
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 33/52 perf stat record: Add pipe support for record command
In reply to Jiri OlsaAllowing storing stat record data into pipe, so report tools (report/script) could read data directly from record.
--- tools/perf/builtin-stat.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-)
tools/perf/builtin-stat.c +28 -11
@@ -293,10 +293,19 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf workload_exec_errno = info->si_value.sival_int; } -static int perf_stat_synthesize_config (void ) +static int perf_stat_synthesize_config (bool is_pipe) {int err; +if (is_pipe) { + err =perf_event__synthesize_attrs (NULL , perf_stat.session, + process_synthesized_event); +if (err <0 ) { +pr_err ("Couldn't synthesize attrs.\n" ); +return err; + } + } + err =perf_event__synthesize_thread_map2 (NULL , evsel_list->threads, process_synthesized_event,NULL );
@@ -364,6 +373,7 @@ static int __run_perf_stat(int argc, const char **argv)size_t l;int status =0 ;const bool forks = (argc >0 ); +bool is_pipe =STAT_RECORD ? perf_stat.file.is_pipe : false;if (interval) { ts.tv_sec = interval /1000 ;
@@ -374,7 +384,7 @@ static int __run_perf_stat(int argc, const char **argv) }if (forks) { -if (perf_evlist__prepare_workload (evsel_list, &target, argv, false, +if (perf_evlist__prepare_workload (evsel_list, &target, argv, is_pipe, workload_exec_failed_signal) <0 ) {perror ("failed to prepare workload" );return -1 ;
@@ -433,12 +443,17 @@ static int __run_perf_stat(int argc, const char **argv)if (STAT_RECORD ) {int err, fd =perf_data_file__fd (&perf_stat.file); - err =perf_session__write_header (perf_stat.session, evsel_list, - fd, false); +if (is_pipe) { + err =perf_header__write_pipe (perf_data_file__fd (&perf_stat.file)); + }else { + err =perf_session__write_header (perf_stat.session, evsel_list, + fd, false); + } +if (err <0 )return err; - err =perf_stat_synthesize_config (); + err =perf_stat_synthesize_config (is_pipe);if (err <0 )return err; }
@@ -965,6 +980,10 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)struct perf_evsel *counter;char buf[64 ], *prefix =NULL ; +/* Do not print anything if we record to the pipe. */ +if (STAT_RECORD && perf_stat.file.is_pipe) +return ; +if (interval)print_interval (prefix = buf, ts);else
@@ -1330,10 +1349,6 @@ static int __cmd_record(int argc, const char **argv)return -1 ; } -/* No pipe support ATM */ -if (perf_stat.file.is_pipe) -return -EINVAL ; -init_features (session); session->evlist = evsel_list;
@@ -1605,8 +1620,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)if (STAT_RECORD ) {int fd =perf_data_file__fd (&perf_stat.file); - perf_stat.session->header.data_size += perf_stat.bytes_written; -perf_session__write_header (perf_stat.session, evsel_list, fd, true); +if (!perf_stat.file.is_pipe) { + perf_stat.session->header.data_size += perf_stat.bytes_written; +perf_session__write_header (perf_stat.session, evsel_list, fd, true); + }perf_session__delete (perf_stat.session); }
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 34/52 perf stat record: Write stat events on record
In reply to Jiri OlsaWriting stat events on 'perf stat record' at the time we read counter values from kernel.
--- tools/perf/builtin-stat.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
tools/perf/builtin-stat.c +19 -0
@@ -207,6 +207,18 @@ static int process_synthesized_event(struct perf_tool *tool __maybe_unused,return 0 ; } +#define SID (e, x, y) xyarray__entry(e->sample_id, x, y) + +static int +perf_evsel__write_stat_event (struct perf_evsel *counter,u32 cpu,u32 thread, +struct perf_counts_values *count) +{ +struct perf_sample_id *sid =SID (counter, cpu, thread); + +return perf_event__synthesize_stat (NULL , cpu, thread, sid->id, count, + process_synthesized_event,NULL ); +} +/* * Read out the results of a single counter: * do not aggregate counts across CPUs in system-wide mode
@@ -230,6 +242,13 @@ static int read_counter(struct perf_evsel *counter) count =perf_counts (counter->counts, cpu, thread);if (perf_evsel__read (counter, cpu, thread, count))return -1 ; + +if (STAT_RECORD ) { +if (perf_evsel__write_stat_event (counter, cpu, thread, count)) { +pr_err ("failed to write stat event\n" ); +return -1 ; + } + } } }
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 35/52 perf stat record: Write stat round events on record
In reply to Jiri OlsaWriting stat round events on 'perf stat record' for each interval round. In non interval mode we store round event after the last stat event.
--- tools/perf/builtin-stat.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
tools/perf/builtin-stat.c +20 -0
@@ -207,6 +207,16 @@ static int process_synthesized_event(struct perf_tool *tool __maybe_unused,return 0 ; } +static int write_stat_round_event (u64 time,u64 type) +{ +return perf_event__synthesize_stat_round (NULL , time, type, + process_synthesized_event, +NULL ); +} + +#define WRITE_STAT_ROUND_EVENT (time, interval) \ + write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval) +#define SID (e, x, y) xyarray__entry(e->sample_id, x, y) static int
@@ -282,6 +292,11 @@ static void process_interval(void)clock_gettime (CLOCK_MONOTONIC , &ts);diff_timespec (&rs, &ts, &ref_time); +if (STAT_RECORD ) { +if (WRITE_STAT_ROUND_EVENT (rs.tv_sec *NSECS_PER_SEC + rs.tv_nsec,INTERVAL )) +pr_err ("failed to write stat round event\n" ); + } +print_counters (&rs,0 ,NULL ); }
@@ -1639,6 +1654,11 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)if (STAT_RECORD ) {int fd =perf_data_file__fd (&perf_stat.file); +if (!interval) { +if (WRITE_STAT_ROUND_EVENT (walltime_nsecs_stats.max,FINAL )) +pr_err ("failed to write stat round event\n" ); + } +if (!perf_stat.file.is_pipe) { perf_stat.session->header.data_size += perf_stat.bytes_written;perf_session__write_header (perf_stat.session, evsel_list, fd, true);
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 36/52 perf stat record: Do not allow record with multiple runs mode
In reply to Jiri OlsaWe currently don't support storing multiple session in perf.data, so we can't allow -r option in stat record.
$ perf stat -e cycles -r 2 record ls Cannot use -r option with perf stat record.
--- tools/perf/builtin-stat.c | 5 +++++ 1 file changed, 5 insertions(+)
tools/perf/builtin-stat.c +5 -0
@@ -1377,6 +1377,11 @@ static int __cmd_record(int argc, const char **argv) argc =parse_options (argc, argv, options, record_usage,PARSE_OPT_STOP_AT_NON_OPTION ); +if (run_count !=1 || forever) { +pr_err ("Cannot use -r option with perf stat record.\n" ); +return -1 ; + } + session =perf_session__new (file, false,NULL );if (session ==NULL ) {pr_err ("Perf session creation failed.\n" );
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 37/52 perf stat record: Synthesize event update events
In reply to Jiri OlsaSynthesize other events stuff not carried within
attr event - unit, scale, name.
--- tools/perf/builtin-stat.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+)
tools/perf/builtin-stat.c +59 -0
@@ -327,8 +327,19 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf workload_exec_errno = info->si_value.sival_int; } +static bool has_unit (struct perf_evsel *counter) +{ +return counter->unit && *counter->unit; +} + +static bool has_scale (struct perf_evsel *counter) +{ +return counter->scale !=1 ; +} +static int perf_stat_synthesize_config (bool is_pipe) { +struct perf_evsel *counter;int err;if (is_pipe) {
@@ -340,6 +351,54 @@ static int perf_stat_synthesize_config(bool is_pipe) } } +/* +* Synthesize other events stuff not carried within +* attr event - unit, scale, name +*/ +evlist__for_each (evsel_list, counter) { +if (!counter->supported) +continue ; + +/* +* Synthesize unit and scale only if it's defined. +*/ +if (has_unit (counter)) { + err =perf_event__synthesize_event_update_unit (NULL , counter, process_synthesized_event); +if (err <0 ) { +pr_err ("Couldn't synthesize evsel unit.\n" ); +return err; + } + } + +if (has_scale (counter)) { + err =perf_event__synthesize_event_update_scale (NULL , counter, process_synthesized_event); +if (err <0 ) { +pr_err ("Couldn't synthesize evsel scale.\n" ); +return err; + } + } + +if (counter->own_cpus) { + err =perf_event__synthesize_event_update_cpus (NULL , counter, process_synthesized_event); +if (err <0 ) { +pr_err ("Couldn't synthesize evsel scale.\n" ); +return err; + } + } + +/* +* Name is needed only for pipe output, +* perf.data carries event names. +*/ +if (is_pipe) { + err =perf_event__synthesize_event_update_name (NULL , counter, process_synthesized_event); +if (err <0 ) { +pr_err ("Couldn't synthesize evsel name.\n" ); +return err; + } + } + } + err =perf_event__synthesize_thread_map2 (NULL , evsel_list->threads, process_synthesized_event,NULL );
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 38/52 perf stat report: Add report command
In reply to Jiri OlsaAdding 'perf stat report' command support. ATM it only processes attr events and display nothing.
--- tools/perf/Documentation/perf-stat.txt | 12 +++++++ tools/perf/builtin-stat.c | 61 +++++++++++++++++++++++++++++++--- tools/perf/util/session.c | 3 ++ 3 files changed, 72 insertions(+), 4 deletions(-)
tools/perf/Documentation/perf-stat.txt +12 -0
@@ -11,6 +11,7 @@ SYNOPSIS 'perf stat' [-e <EVENT> | --event=EVENT] [-a] <command> 'perf stat' [-e <EVENT> | --event=EVENT] [-a] -- <command> [<options>] 'perf stat' [-e <EVENT> | --event=EVENT] [-a] record [-o file] -- <command> [<options>] +'perf stat' report [-i file] DESCRIPTION -----------
@@ -26,6 +27,9 @@ OPTIONS record:: See STAT RECORD. +report:: + See STAT REPORT. + -e:: --event=:: Select the PMU event. Selection can be:
@@ -170,6 +174,14 @@ Stores stat data into perf data file. --output file:: Output file name. +STAT REPORT +----------- +Reads and reports stat data from perf data file. + +-i file:: +--input file:: +Input file name. + EXAMPLES --------
tools/perf/builtin-stat.c +57 -4
97 lines not on this page · raw message
tools/perf/util/session.c +3 -0
@@ -37,6 +37,9 @@ static int perf_session__open(struct perf_session *session)if (perf_data_file__is_pipe (file))return 0 ; +if (perf_header__has_feat (&session->header,HEADER_STAT )) +return 0 ; +if (!perf_evlist__valid_sample_type (session->evlist)) {pr_err ("non matching sample_type" );return -1 ;
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 39/52 perf stat report: Process cpu/threads maps
In reply to Jiri OlsaAdding processing of cpu/threads maps. Configuring session's evlist with these maps.
--- tools/perf/builtin-stat.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+)
tools/perf/builtin-stat.c +62 -0
@@ -132,6 +132,9 @@ struct perf_stat {struct perf_session *session;u64 bytes_written;struct perf_tool tool; +bool maps_allocated; +struct cpu_map *cpus; +struct thread_map *threads; };static struct perf_stat perf_stat;
@@ -1458,6 +1461,63 @@ static int __cmd_record(int argc, const char **argv)return argc; } +static int set_maps (struct perf_stat *stat) +{ +if (!stat->cpus || !stat->threads) +return 0 ; + +if (WARN_ONCE (stat->maps_allocated,"stats double allocation\n" )) +return -EINVAL ; + +perf_evlist__set_maps (evsel_list, stat->cpus, stat->threads); + +if (perf_evlist__alloc_stats (evsel_list, true)) +return -ENOMEM ; + + stat->maps_allocated = true; +return 0 ; +} + +static +int process_thread_map_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_session *session__maybe_unused ) +{ + struct perf_stat *stat = container_of(tool, struct perf_stat, tool); + +if (stat->threads) { +pr_warning ("Extra thread map event, ignoring.\n" ); +return 0 ; + } + + stat->threads =thread_map__new_event (&event->thread_map); +if (!stat->threads) +return -ENOMEM ; + +return set_maps (stat); +} + +static +int process_cpu_map_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_session *session__maybe_unused ) +{ + struct perf_stat *stat = container_of(tool, struct perf_stat, tool); +struct cpu_map *cpus; + +if (stat->cpus) { +pr_warning ("Extra cpu map event, ignoring.\n" ); +return 0 ; + } + + cpus =cpu_map__new_data (&event->cpu_map.data); +if (!cpus) +return -ENOMEM ; + + stat->cpus = cpus; +return set_maps (stat); +} +static const char *const report_usage[] = {"perf stat report [<options>]" ,NULL ,
@@ -1466,6 +1526,8 @@ static const char * const report_usage[] = {static struct perf_stat perf_stat = { .tool = { .attr = perf_event__process_attr, + .thread_map = process_thread_map_event, + .cpu_map = process_cpu_map_event, }, };
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 40/52 perf stat report: Process stat config event
In reply to Jiri OlsaAdding processing of stat config event and initialize stat_config object.
--- tools/perf/builtin-stat.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
tools/perf/builtin-stat.c +10 -0
@@ -1461,6 +1461,15 @@ static int __cmd_record(int argc, const char **argv)return argc; } +static +int process_stat_config_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_session *session__maybe_unused ) +{ +perf_event__read_stat_config (&stat_config, &event->stat_config); +return 0 ; +} +static int set_maps (struct perf_stat *stat) {if (!stat->cpus || !stat->threads)
@@ -1528,6 +1537,7 @@ static struct perf_stat perf_stat = { .attr = perf_event__process_attr, .thread_map = process_thread_map_event, .cpu_map = process_cpu_map_event, + .stat_config = process_stat_config_event, }, };
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 41/52 perf stat report: Add support to initialize aggr_map from file
In reply to Jiri OlsaUsing perf.data's perf_env data to initialize
aggregate config.
--- tools/perf/builtin-stat.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+)
tools/perf/builtin-stat.c +103 -0
@@ -1253,6 +1253,101 @@ static int perf_stat_init_aggr_mode(void)return cpus_aggr_map ?0 : -ENOMEM ; } +static inline int perf_env__get_cpu (struct perf_env *env,struct cpu_map *map,int idx) +{ +int cpu; + +if (idx > map->nr) +return -1 ; + + cpu = map->map[idx]; + +if (cpu >= env->nr_cpus_online) +return -1 ; + +return cpu; +} + +static int perf_env__get_socket (struct cpu_map *map,int idx,void *data) +{ +struct perf_env *env = data; +int cpu =perf_env__get_cpu (env, map, idx); + +return cpu ==-1 ?-1 : env->cpu[cpu].socket_id; +} + +static int perf_env__get_core (struct cpu_map *map,int idx,void *data) +{ +struct perf_env *env = data; +int core =-1 , cpu =perf_env__get_cpu (env, map, idx); + +if (cpu !=-1 ) { +int socket = env->cpu[cpu].socket_id; + +/* +* Encode socket in upper 16 bits +* core_id is relative to socket, and +* we need a global id. So we combine +* socket + core id. +*/ + core = (socket <<16 ) | (env->cpu[cpu].core_id &0xffff ); + } + +return core; +} + +static int perf_env__build_socket_map (struct perf_env *env,struct cpu_map *cpus, +struct cpu_map **sockp) +{ +return cpu_map__build_map (cpus, sockp, perf_env__get_socket, env); +} + +static int perf_env__build_core_map (struct perf_env *env,struct cpu_map *cpus, +struct cpu_map **corep) +{ +return cpu_map__build_map (cpus, corep, perf_env__get_core, env); +} + +static int perf_stat__get_socket_file (struct cpu_map *map,int idx) +{ +return perf_env__get_socket (map, idx, &perf_stat.session->header.env); +} + +static int perf_stat__get_core_file (struct cpu_map *map,int idx) +{ +return perf_env__get_core (map, idx, &perf_stat.session->header.env); +} + +static int perf_stat_init_aggr_mode_file (struct perf_stat *stat) +{ +struct perf_env *env = &stat->session->header.env; + +switch (stat_config.aggr_mode) { +case AGGR_SOCKET : +if (perf_env__build_socket_map (env, evsel_list->cpus, &aggr_map)) { +perror ("cannot build socket map" ); +return -1 ; + } + aggr_get_id = perf_stat__get_socket_file; +break ; +case AGGR_CORE : +if (perf_env__build_core_map (env, evsel_list->cpus, &aggr_map)) { +perror ("cannot build core map" ); +return -1 ; + } + aggr_get_id = perf_stat__get_core_file; +break ; +case AGGR_NONE : +case AGGR_GLOBAL : +case AGGR_THREAD : +case AGGR_UNSET : +default : +break ; + } + +return 0 ; +} +/* * Add default attributes, if there were no attributes specified or * if -d/--detailed, -d -d or -d -d -d is used:
@@ -1466,7 +1561,15 @@ int process_stat_config_event(struct perf_tool *tool __maybe_unused,union perf_event *event, struct perf_session *session __maybe_unused) { + struct perf_stat *stat = container_of(tool, struct perf_stat, tool); +perf_event__read_stat_config (&stat_config, &event->stat_config); + +if (perf_stat.file.is_pipe) +perf_stat_init_aggr_mode (); +else +perf_stat_init_aggr_mode_file (stat); +return 0 ; }
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 42/52 perf stat report: Process stat and stat round events
In reply to Jiri OlsaAdding processing of stat and stat round events.
The stat data com in stat events, using generic function process_stat_round_event to store data under perf_evsel object.
The stat-round events comes each interval or as last event in non interval mode. The function process_stat_round_event process stored data for each perf_evsel object and print it out.
--- tools/perf/builtin-stat.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
tools/perf/builtin-stat.c +28 -0
@@ -1556,6 +1556,32 @@ static int __cmd_record(int argc, const char **argv)return argc; } +static int process_stat_round_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_session *session) +{ +struct stat_round_event *round = &event->stat_round; +struct perf_evsel *counter; +struct timespec tsh, *ts =NULL ; +const char **argv = session->header.env.cmdline_argv; +int argc = session->header.env.nr_cmdline; + +evlist__for_each (evsel_list, counter) +perf_stat_process_counter (&stat_config, counter); + +if (round->type ==PERF_STAT_ROUND_TYPE__FINAL ) +update_stats (&walltime_nsecs_stats, round->time); + +if (stat_config.interval && round->time) { + tsh.tv_sec = round->time /NSECS_PER_SEC ; + tsh.tv_nsec = round->time %NSECS_PER_SEC ; + ts = &tsh; + } + +print_counters (ts, argc, argv); +return 0 ; +} + static int process_stat_config_event(struct perf_tool *tool __maybe_unused, union perf_event *event,
@@ -1641,6 +1667,8 @@ static struct perf_stat perf_stat = { .thread_map = process_thread_map_event, .cpu_map = process_cpu_map_event, .stat_config = process_stat_config_event, + .stat = perf_event__process_stat_event, + .stat_round = process_stat_round_event, }, };
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 43/52 perf stat report: Process event update events
In reply to Jiri OlsaAdding processing of event update events, so perf stat report can store additional info for events - unit,scale,name.
--- tools/perf/builtin-stat.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/builtin-stat.c +1 -0
@@ -1664,6 +1664,7 @@ static const char * const report_usage[] = {static struct perf_stat perf_stat = { .tool = { .attr = perf_event__process_attr, + .event_update = perf_event__process_event_update, .thread_map = process_thread_map_event, .cpu_map = process_cpu_map_event, .stat_config = process_stat_config_event,
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 44/52 perf stat report: Move csv_sep initialization before report command
In reply to Jiri OlsaSo we have csv_sep properly initialized before
report command leg.
--- tools/perf/builtin-stat.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
tools/perf/builtin-stat.c +7 -7
@@ -1796,6 +1796,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) (const char **) stat_usage, PARSE_OPT_STOP_AT_NON_OPTION); +if (csv_sep) { + csv_output = true; +if (!strcmp (csv_sep,"\\t" )) + csv_sep ="\t" ; + }else + csv_sep =DEFAULT_SEPARATOR ; +if (argc && !strncmp (argv[0 ],"rec" ,3 )) { argc =__cmd_record (argc, argv);if (argc <0 )
@@ -1843,13 +1850,6 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) stat_config.output = output; -if (csv_sep) { - csv_output = true; -if (!strcmp (csv_sep,"\\t" )) - csv_sep ="\t" ; - }else - csv_sep =DEFAULT_SEPARATOR ; -/* * let the spreadsheet do the pretty-printing */
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 45/52 perf stat report: Allow to override aggr_mode
In reply to Jiri OlsaAllowing to override record aggr_mode. It's possible to use perf stat like:
$ perf stat report -A $ perf stat report --per-core $ perf stat report --per-socket
To customize the recorded aggregate mode regardless what was used during the stat record command.
--- tools/perf/Documentation/perf-stat.txt | 10 ++++++++++ tools/perf/builtin-stat.c | 17 +++++++++++++++++ 2 files changed, 27 insertions(+)
tools/perf/Documentation/perf-stat.txt +10 -0
@@ -182,6 +182,16 @@ Reads and reports stat data from perf data file. --input file:: Input file name. +--per-socket:: +Aggregate counts per processor socket for system-wide mode measurements. + +--per-core:: +Aggregate counts per physical processor for system-wide mode measurements. + +-A:: +--no-aggr:: +Do not aggregate counts across all monitored CPUs. + EXAMPLES --------
tools/perf/builtin-stat.c +17 -0
@@ -135,6 +135,7 @@ struct perf_stat {bool maps_allocated;struct cpu_map *cpus;struct thread_map *threads; +enum aggr_mode aggr_mode; };static struct perf_stat perf_stat;
@@ -1591,6 +1592,15 @@ int process_stat_config_event(struct perf_tool *tool __maybe_unused,perf_event__read_stat_config (&stat_config, &event->stat_config); +if (cpu_map__empty (stat->cpus)) { +if (stat->aggr_mode !=AGGR_UNSET ) +pr_warning ("warning: processing task data, aggregation mode not set\n" ); +return 0 ; + } + +if (stat->aggr_mode !=AGGR_UNSET ) + stat_config.aggr_mode = stat->aggr_mode; +if (perf_stat.file.is_pipe)perf_stat_init_aggr_mode ();else
@@ -1671,6 +1681,7 @@ static struct perf_stat perf_stat = { .stat = perf_event__process_stat_event, .stat_round = process_stat_round_event, }, + .aggr_mode = AGGR_UNSET, };static int __cmd_report (int argc,const char **argv)
@@ -1678,6 +1689,12 @@ static int __cmd_report(int argc, const char **argv)struct perf_session *session;const struct option options[] = {OPT_STRING ('i' ,"input" , &input_name,"file" ,"input file name" ), +OPT_SET_UINT (0 ,"per-socket" , &perf_stat.aggr_mode, +"aggregate counts per processor socket" ,AGGR_SOCKET ), +OPT_SET_UINT (0 ,"per-core" , &perf_stat.aggr_mode, +"aggregate counts per physical processor core" ,AGGR_CORE ), +OPT_SET_UINT ('A' ,"no-aggr" , &perf_stat.aggr_mode, +"disable CPU count aggregation" ,AGGR_NONE ),OPT_END () };struct stat st;
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 46/52 perf script: Process cpu/threads maps
In reply to Jiri OlsaAdding processing of cpu/threads maps. Configuring session's evlist with these maps.
--- tools/perf/builtin-script.c | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
tools/perf/builtin-script.c +67 -0
@@ -18,7 +18,11 @@#include "util/sort.h" #include "util/data.h" #include "util/auxtrace.h" +#include "util/cpumap.h" +#include "util/thread_map.h" +#include "util/stat.h" #include <linux/bitmap.h> +#include "asm/bug.h" static char const *script_name;static char const *generate_script_lang;
@@ -659,6 +663,9 @@ struct perf_script {bool show_task_events;bool show_mmap_events;bool show_switch_events; +bool allocated; +struct cpu_map *cpus; +struct thread_map *threads; }; static int process_attr(struct perf_tool *tool, union perf_event *event,
@@ -1615,6 +1622,63 @@ static void script__setup_sample_type(struct perf_script *script) } } +static int set_maps (struct perf_script *script) +{ +struct perf_evlist *evlist = script->session->evlist; + +if (!script->cpus || !script->threads) +return 0 ; + +if (WARN_ONCE (script->allocated,"stats double allocation\n" )) +return -EINVAL ; + +perf_evlist__set_maps (evlist, script->cpus, script->threads); + +if (perf_evlist__alloc_stats (evlist, true)) +return -ENOMEM ; + + script->allocated = true; +return 0 ; +} + +static +int process_thread_map_event (struct perf_tool *tool, +union perf_event *event, +struct perf_session *session__maybe_unused ) +{ + struct perf_script *script = container_of(tool, struct perf_script, tool); + +if (script->threads) { +pr_warning ("Extra thread map event, ignoring.\n" ); +return 0 ; + } + + script->threads =thread_map__new_event (&event->thread_map); +if (!script->threads) +return -ENOMEM ; + +return set_maps (script); +} + +static +int process_cpu_map_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_session *session__maybe_unused ) +{ + struct perf_script *script = container_of(tool, struct perf_script, tool); + +if (script->cpus) { +pr_warning ("Extra cpu map event, ignoring.\n" ); +return 0 ; + } + + script->cpus =cpu_map__new_data (&event->cpu_map.data); +if (!script->cpus) +return -ENOMEM ; + +return set_maps (script); +} +int cmd_script (int argc,const char **argv,const char *prefix__maybe_unused ) {bool show_full_info = false;
@@ -1643,6 +1707,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) .auxtrace_info = perf_event__process_auxtrace_info, .auxtrace = perf_event__process_auxtrace, .auxtrace_error = perf_event__process_auxtrace_error, + .thread_map = process_thread_map_event, + .cpu_map = process_cpu_map_event, .ordered_events = true, .ordering_requires_timestamps = true, },
@@ -1996,6 +2062,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)flush_scripting (); out_delete: +perf_evlist__free_stats (session->evlist);perf_session__delete (session);if (script_started)
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 47/52 perf script: Process stat config event
In reply to Jiri OlsaAdding processing of stat config event and initialize stat_config object.
--- tools/perf/builtin-script.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
tools/perf/builtin-script.c +10 -0
@@ -36,6 +36,7 @@ static bool print_flags;static bool nanosecs;static const char *cpu_list; static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); +static struct perf_stat_config stat_config;unsigned int scripting_max_stack =PERF_MAX_STACK_DEPTH ;
@@ -1622,6 +1623,14 @@ static void script__setup_sample_type(struct perf_script *script) } } +static int process_stat_config_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_session *session__maybe_unused ) +{ +perf_event__read_stat_config (&stat_config, &event->stat_config); +return 0 ; +} +static int set_maps (struct perf_script *script) {struct perf_evlist *evlist = script->session->evlist;
@@ -1707,6 +1716,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) .auxtrace_info = perf_event__process_auxtrace_info, .auxtrace = perf_event__process_auxtrace, .auxtrace_error = perf_event__process_auxtrace_error, + .stat_config = process_stat_config_event, .thread_map = process_thread_map_event, .cpu_map = process_cpu_map_event, .ordered_events = true,
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 48/52 perf script: Add process_stat/process_stat_interval scripting interface
In reply to Jiri OlsaPython and perl scripting code will define those
callbacks and get stat data.
--- tools/perf/util/trace-event.h | 4 ++++ 1 file changed, 4 insertions(+)
tools/perf/util/trace-event.h +4 -0
@@ -65,6 +65,7 @@ int tracing_data_put(struct tracing_data *tdata);struct addr_location ;struct perf_session ; +struct perf_stat_config ;struct scripting_ops {const char *name;
@@ -75,6 +76,9 @@ struct scripting_ops {struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al); +void (*process_stat) (struct perf_stat_config *config, +struct perf_evsel *evsel,u64 time); +void (*process_stat_interval) (u64 time);int (*generate_script) (struct pevent *pevent,const char *outfile); };
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 49/52 perf script: Add stat default handlers
In reply to Jiri OlsaImplement struct scripting_ops::(process_stat|process_stat_interval) handlers - calling scripting handlers from stat events handlers.
--- tools/perf/builtin-script.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
tools/perf/builtin-script.c +31 -0
@@ -205,6 +205,9 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,struct perf_event_attr *attr = &evsel->attr;bool allow_user_set; +if (perf_header__has_feat (&session->header,HEADER_STAT )) +return 0 ; + allow_user_set =perf_header__has_feat (&session->header,HEADER_AUXTRACE );
@@ -568,6 +571,14 @@ static void process_event(union perf_event *event, struct perf_sample *sample,printf ("\n" ); } +static void process_stat (struct perf_stat_config *config__maybe_unused , +struct perf_evsel *evsel__maybe_unused , +u64 time__maybe_unused ) +{ +} + +static void process_stat_interval (u64 time__maybe_unused ) { } +static int default_start_script (const char *script__maybe_unused ,int argc__maybe_unused ,const char **argv__maybe_unused )
@@ -596,6 +607,8 @@ static struct scripting_ops default_scripting_ops = { .flush_script = default_flush_script, .stop_script = default_stop_script, .process_event = process_event, + .process_stat = process_stat, + .process_stat_interval = process_stat_interval, .generate_script = default_generate_script, };
@@ -1623,6 +1636,22 @@ static void script__setup_sample_type(struct perf_script *script) } } +static int process_stat_round_event (struct perf_tool *tool__maybe_unused , +union perf_event *event, +struct perf_session *session) +{ +struct stat_round_event *round = &event->stat_round; +struct perf_evsel *counter; + +evlist__for_each (session->evlist, counter) { +perf_stat_process_counter (&stat_config, counter); + scripting_ops->process_stat (&stat_config, counter, round->time); + } + + scripting_ops->process_stat_interval (round->time); +return 0 ; +} +static int process_stat_config_event (struct perf_tool *tool__maybe_unused ,union perf_event *event,struct perf_session *session__maybe_unused )
@@ -1716,6 +1745,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) .auxtrace_info = perf_event__process_auxtrace_info, .auxtrace = perf_event__process_auxtrace, .auxtrace_error = perf_event__process_auxtrace_error, + .stat = perf_event__process_stat_event, + .stat_round = process_stat_round_event, .stat_config = process_stat_config_event, .thread_map = process_thread_map_event, .cpu_map = process_cpu_map_event,
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 50/52 perf script: Display stat events by default
In reply to Jiri OlsaIf no script is specified for stat data, display
stat events in raw form.
$ perf stat record ls
SNIP
Performance counter stats for 'ls':
0.851585 task-clock (msec) # 0.717 CPUs utilized
0 context-switches # 0.000 K/sec
0 cpu-migrations # 0.000 K/sec
114 page-faults # 0.134 M/sec
2,620,918 cycles # 3.078 GHz
<not supported> stalled-cycles-frontend
<not supported> stalled-cycles-backend
2,714,111 instructions # 1.04 insns per cycle
542,434 branches # 636.970 M/sec
15,946 branch-misses # 2.94% of all branches0.001186954 seconds time elapsed
$ perf script CPU THREAD VAL ENA RUN TIME EVENT -1 26185 851585 851585 851585 1186954 task-clock -1 26185 0 851585 851585 1186954 context-switches -1 26185 0 851585 851585 1186954 cpu-migrations -1 26185 114 851585 851585 1186954 page-faults -1 26185 2620918 853340 853340 1186954 cycles -1 26185 0 0 0 1186954 stalled-cycles-frontend -1 26185 0 0 0 1186954 stalled-cycles-backend -1 26185 2714111 853340 853340 1186954 instructions -1 26185 542434 853340 853340 1186954 branches -1 26185 15946 853340 853340 1186954 branch-misses
--- tools/perf/builtin-script.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-)
tools/perf/builtin-script.c +33 -2
@@ -572,9 +572,40 @@ static void process_event(union perf_event *event, struct perf_sample *sample, }static void process_stat (struct perf_stat_config *config__maybe_unused , -struct perf_evsel *evsel__maybe_unused , -u64 time__maybe_unused ) +struct perf_evsel *counter,u64 time) { +int nthreads =thread_map__nr (counter->threads); +int ncpus =perf_evsel__nr_cpus (counter); +int cpu, thread; +static int header_printed; + +if (counter->system_wide) + nthreads =1 ; + +if (!header_printed) { +printf ("%3s %8s %15s %15s %15s %15s %s\n" , +"CPU" ,"THREAD" ,"VAL" ,"ENA" ,"RUN" ,"TIME" ,"EVENT" ); + header_printed =1 ; + } + +for (thread =0 ; thread < nthreads; thread++) { +for (cpu =0 ; cpu < ncpus; cpu++) { +struct perf_counts_values *counts; + + counts =perf_counts (counter->counts, cpu, thread); + +printf ("%3d %8d %15" PRIu64" %15" PRIu64" %15" PRIu64" %15" PRIu64" %s\n" , + counter->cpus->map[cpu], +thread_map__pid (counter->threads, thread), + counts->val, + counts->ena, + counts->run, + time, +perf_evsel__name (counter)); + } + } + +return ; }static void process_stat_interval (u64 time__maybe_unused ) { }
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 51/52 perf script: Add python support for stat events
In reply to Jiri OlsaAdd support to get stat events data in perf python scripts.
The python script shall implement following
new interface to process stat data:
def stat__<event_name>_[<modifier>](cpu, thread, time, val, ena, run):
- is called for every stat event for given counter, if user monitors 'cycles,instructions:u" following callbacks should be defined:
def stat__cycles(cpu, thread, time, val, ena, run):
def stat__instructions_u(cpu, thread, time, val, ena, run):
def stat__interval(time):
- is called for every interval with its time,
in non interval mode it's called after last
stat event with total meassured time in ns
The rest of the current interface stays untouched..
Please check example CPI metrics script in following patch with command line examples in changelogs.
--- .../util/scripting-engines/trace-event-python.c | 114 +++++++++++++++++++-- 1 file changed, 108 insertions(+), 6 deletions(-)
tools/perf/util/scripting-engines/trace-event-python.c +108 -6
@@ -41,6 +41,9 @@#include "../thread-stack.h" #include "../trace-event.h" #include "../machine.h" +#include "thread_map.h" +#include "cpumap.h" +#include "stat.h" PyMODINIT_FUNC initperf_trace_context (void );
@@ -859,6 +862,103 @@ static void python_process_event(union perf_event *event, } } +static void get_handler_name (char *str,size_t size, +struct perf_evsel *evsel) +{ +char *p = str; + +scnprintf (str, size,"stat__%s" ,perf_evsel__name (evsel)); + +while ((p =strchr (p,':' ))) { + *p ='_' ; + p++; + } +} + +static void +process_stat (struct perf_evsel *counter,int cpu,int thread,u64 time, +struct perf_counts_values *count) +{ +PyObject *handler, *t; +static char handler_name[256 ]; +int n =0 ; + + t =PyTuple_New (MAX_FIELDS ); +if (!t) +Py_FatalError ("couldn't create Python tuple" ); + +get_handler_name (handler_name,sizeof (handler_name), + counter); + + handler =get_handler (handler_name); +if (!handler) { +pr_debug ("can't find python handler %s\n" , handler_name); +return ; + } + +PyTuple_SetItem (t, n++,PyInt_FromLong (cpu)); +PyTuple_SetItem (t, n++,PyInt_FromLong (thread)); +PyTuple_SetItem (t, n++,PyLong_FromLong (time)); +PyTuple_SetItem (t, n++,PyLong_FromLong (count->val)); +PyTuple_SetItem (t, n++,PyLong_FromLong (count->ena)); +PyTuple_SetItem (t, n++,PyLong_FromLong (count->run)); + +if (_PyTuple_Resize (&t, n) ==-1 ) +Py_FatalError ("error resizing Python tuple" ); + +call_object (handler, t, handler_name); + +Py_DECREF (t); +} + +static void python_process_stat (struct perf_stat_config *config, +struct perf_evsel *counter,u64 time) +{ +struct thread_map *threads = counter->threads; +struct cpu_map *cpus = counter->cpus; +int cpu, thread; + +if (config->aggr_mode ==AGGR_GLOBAL ) { +process_stat (counter,-1 ,-1 , time, + &counter->counts->aggr); +return ; + } + +for (thread =0 ; thread < threads->nr; thread++) { +for (cpu =0 ; cpu < cpus->nr; cpu++) { +process_stat (counter, cpus->map[cpu], +thread_map__pid (threads, thread), time, +perf_counts (counter->counts, cpu, thread)); + } + } +} + +static void python_process_stat_interval (u64 time) +{ +PyObject *handler, *t; +static const char handler_name[] ="stat__interval" ; +int n =0 ; + + t =PyTuple_New (MAX_FIELDS ); +if (!t) +Py_FatalError ("couldn't create Python tuple" ); + + handler =get_handler (handler_name); +if (!handler) { +pr_debug ("can't find python handler %s\n" , handler_name); +return ; + } + +PyTuple_SetItem (t, n++,PyLong_FromLong (time)); + +if (_PyTuple_Resize (&t, n) ==-1 ) +Py_FatalError ("error resizing Python tuple" ); + +call_object (handler, t, handler_name); + +Py_DECREF (t); +} +static int run_start_sub (void ) { main_module =PyImport_AddModule ("__main__" );
@@ -1201,10 +1301,12 @@ static int python_generate_script(struct pevent *pevent, const char *outfile) }struct scripting_ops python_scripting_ops = { - .name ="Python" , - .start_script = python_start_script, - .flush_script = python_flush_script, - .stop_script = python_stop_script, - .process_event = python_process_event, - .generate_script = python_generate_script, + .name ="Python" , + .start_script = python_start_script, + .flush_script = python_flush_script, + .stop_script = python_stop_script, + .process_event = python_process_event, + .process_stat = python_process_stat, + .process_stat_interval = python_process_stat_interval, + .generate_script = python_generate_script, };
Signature · 1 line
2.4.3
Jiri Olsa
reviewerPATCH v5 52/52 perf script: Add stat-cpi.py script
In reply to Jiri OlsaAdding stat-cpi.py as an example of how to do stat scripting. It computes the CPI metrics from cycles and instructions events.
Following stat record/report/script combinations could be used:
- get CPI for given workload
$ perf stat -e cycles,instructions record ls
SNIP
Performance counter stats for 'ls':
2,904,431 cycles
3,346,878 instructions # 1.15 insns per cycle
0.001782686 seconds time elapsed
$ perf script -s ./scripts/python/stat-cpi.py
0.001783: cpu -1, thread -1 -> cpi 0.867803 (2904431/3346878)
$ perf stat -e cycles,instructions record ls | perf script -s ./scripts/python/stat-cpi.py
SNIP
0.001730: cpu -1, thread -1 -> cpi 0.869026 (2928292/3369627)
- get CPI systemwide:
$ perf stat -e cycles,instructions -a -I 1000 record sleep 3
# time counts unit events
1.000158618 594,274,711 cycles (100.00%)
1.000158618 441,898,250 instructions
2.000350973 567,649,705 cycles (100.00%)
2.000350973 432,669,206 instructions
3.000559210 561,940,430 cycles (100.00%)
3.000559210 420,403,465 instructions
3.000670798 780,105 cycles (100.00%)
3.000670798 326,516 instructions $ perf script -s ./scripts/python/stat-cpi.py
1.000159: cpu -1, thread -1 -> cpi 1.344823 (594274711/441898250)
2.000351: cpu -1, thread -1 -> cpi 1.311972 (567649705/432669206)
3.000559: cpu -1, thread -1 -> cpi 1.336669 (561940430/420403465)
3.000671: cpu -1, thread -1 -> cpi 2.389178 (780105/326516) $ perf stat -e cycles,instructions -a -I 1000 record sleep 3 | perf script -s ./scripts/python/stat-cpi.py
1.000202: cpu -1, thread -1 -> cpi 1.035091 (940778881/908885530)
2.000392: cpu -1, thread -1 -> cpi 1.442600 (627493992/434974455)
3.000545: cpu -1, thread -1 -> cpi 1.353612 (741463930/547766890)
3.000622: cpu -1, thread -1 -> cpi 2.642110 (784083/296764)--- tools/perf/scripts/python/stat-cpi.py | 74 +++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tools/perf/scripts/python/stat-cpi.py
tools/perf/scripts/python/stat-cpi.py new file +74 -0
@@ -0,0 +1,74 @@ +#!/bin/python + +data = {} +times = [] +threads = [] +cpus = [] + +def get_key(time, event, cpu, thread): + return "%d-%s-%d-%d" % (time, event, cpu, thread) + +def store_key(time, cpu, thread): + if (time not in times): + times.append(time) + + if (cpu not in cpus): + cpus.append(cpu) + + if (thread not in threads): + threads.append(thread) + +def store(time, event, cpu, thread, val, ena, run): + #print "event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % \ + # (event, cpu, thread, time, val, ena, run) + + store_key(time, cpu, thread) + key = get_key(time, event, cpu, thread) + data[key] = [ val, ena, run] + +def get(time, event, cpu, thread): + key = get_key(time, event, cpu, thread) + return data[key][0] + +def stat__cycles_k(cpu, thread, time, val, ena, run): + store(time, "cycles", cpu, thread, val, ena, run); + +def stat__instructions_k(cpu, thread, time, val, ena, run): + store(time, "instructions", cpu, thread, val, ena, run); + +def stat__cycles_u(cpu, thread, time, val, ena, run): + store(time, "cycles", cpu, thread, val, ena, run); + +def stat__instructions_u(cpu, thread, time, val, ena, run): + store(time, "instructions", cpu, thread, val, ena, run); + +def stat__cycles(cpu, thread, time, val, ena, run): + store(time, "cycles", cpu, thread, val, ena, run); + +def stat__instructions(cpu, thread, time, val, ena, run): + store(time, "instructions", cpu, thread, val, ena, run); + +def stat__interval(time): + for cpu in cpus: + for thread in threads: + cyc = get(time, "cycles", cpu, thread) + ins = get(time, "instructions", cpu, thread) + cpi = 0 + + if ins != 0: + cpi = cyc/float(ins) + + print "%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins) + +def trace_end(): + pass +# for time in times: +# for cpu in cpus: +# for thread in threads: +# cyc = get(time, "cycles", cpu, thread) +# ins = get(time, "instructions", cpu, thread) +# +# if ins != 0: +# cpi = cyc/float(ins) +# +# print "time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi)
Signature · 1 line
2.4.3
Arnaldo Carvalho de Melo
maintainerEm Sun, Oct 25, 2015 at 03:51:16PM +0100, Jiri Olsa escreveu:
Quoted 9 lines
hi,
sending another version of stat scripting.v5 changes:
- several patches from v4 already taken
- using u16 for cpu number incpu_map_event
- renamedPERF_RECORD_HEADER_ATTR_UPDATEtoPERF_RECORD_EVENT_UPDATE
- moved low hanging fuits patches to the start of the patchset
- patchset tested by Kan Liang, thanks!
So, next time please add the Tested-by: tag for the patches you haven't changed since Kan (or any other tester, I guess) said he tested.
I'm not adding it now, since I'm not checking one by one the patches to see the ones that changed, only re-reviewing them on their own.
If Kan could provide retest, I can go on and add the Tested-by tags,
Thanks,
- Arnaldo
Quoted 296 lines
v4 changes:
- added attr update event for event's cpumask
- forbig aggregation on task workloads
- some minor reorders and changelog fixesv3 changes:
- added attr update event to handle unit,scale,name for event it fixed the uncore_imc_1/cas_count_read/ record/report
- perf report -D now displays stat related events
- some minor and changelog fixesv2 changes:
- rebased to latest Arnaldo's perf/core
- patches 1 to 11 already merged in
- added --per-core/--per-socket/-A options for perf stat report command to allow custom aggregation in stat report, please check new examples below
- couple changelogs changesThe initial attempt defined its own formula lang and allowed triggering user's script on the end of the stat command:
http://marc.info/?l=linux-kernel&m=136742146322273&w=2This patchset abandons the idea of new formula language and rather adds support to:
- store stat data into perf.data file
- add python support to process stat eventsBasically it allows to store stat data into perf.data and post process it with python scripts in a similar way we do for sampling data.
The stat data are stored in new stat, stat-round, stat-config user events.
stat - stored for each read syscall of the counter
stat round - stored for each interval or end of the command invocation stat config - stores all the config information needed to process data
so report tool could restore the same output as recordThe python script can now define 'stat__<eventname>_<modifier>' functions to get stat events data and '
stat__interval' to get stat-round data.See CPI script example in
scripts/python/stat-cpi.py.Also available in:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/stat_scriptthanks,
jirkaExamples:
- To record data for command stat workload:
$ perf stat record kill ...Performance counter stats for 'kill':
0.372007 task-clock (msec) # 0.613 CPUs utilized 3 context-switches # 0.008 M/sec 0 cpu-migrations # 0.000 K/sec 62 page-faults # 0.167 M/sec 1,129,973 cycles # 3.038 GHz <not supported> stalled-cycles-frontend <not supported> stalled-cycles-backend 813,313 instructions # 0.72 insns per cycle 166,161 branches # 446.661 M/sec 8,747 branch-misses # 5.26% of all branches0.000607287 seconds time elapsed- To report perf stat data:
$ perf stat reportPerformance counter stats for '
/home/jolsa/bin/perfstat record kill':0.372007 task-clock (msec) # inf CPUs utilized 3 context-switches # 0.008 M/sec 0 cpu-migrations # 0.000 K/sec 62 page-faults # 0.167 M/sec 1,129,973 cycles # 3.038 GHz <not supported> stalled-cycles-frontend <not supported> stalled-cycles-backend 813,313 instructions # 0.72 insns per cycle 166,161 branches # 446.661 M/sec 8,747 branch-misses # 5.26% of all branches0.000000000 seconds time elapsed- To store system-wide period stat data:
$ perf stat -e cycles:u,instructions:u -a -I 1000 record # time counts unit events 1.000265471 462,311,482 cycles:u (100.00%) 1.000265471 590,037,440 instructions:u 2.000483453 722,532,336 cycles:u (100.00%) 2.000483453 848,678,197 instructions:u 3.000759876 75,990,880 cycles:u (100.00%) 3.000759876 86,187,813 instructions:u ^C 3.213960893 85,329,533 cycles:u (100.00%) 3.213960893 135,954,296 instructions:u- To report perf stat data:
$ perf stat report # time counts unit events 1.000265471 462,311,482 cycles:u (100.00%) 1.000265471 590,037,440 instructions:u 2.000483453 722,532,336 cycles:u (100.00%) 2.000483453 848,678,197 instructions:u 3.000759876 75,990,880 cycles:u (100.00%) 3.000759876 86,187,813 instructions:u 3.213960893 85,329,533 cycles:u (100.00%) 3.213960893 135,954,296 instructions:u- To run
stat-cpi.pyscript over perf.data:$ perf script -s scripts/python/stat-cpi.py 1.000265: cpu -1, thread -1 -> cpi 0.783529 (462311482/590037440) 2.000483: cpu -1, thread -1 -> cpi 0.851362 (722532336/848678197) 3.000760: cpu -1, thread -1 -> cpi 0.881689 (75990880/86187813) 3.213961: cpu -1, thread -1 -> cpi 0.627634 (85329533/135954296)- To pipe data from stat to stat-cpi script:
$ perf stat -e cycles:u,instructions:u -A -C 0 -I 1000 record | perf script -s scripts/python/stat-cpi.py 1.000192: cpu 0, thread -1 -> cpi 0.739535 (23921908/32347236) 2.000376: cpu 0, thread -1 -> cpi 1.663482 (2519340/1514498) 3.000621: cpu 0, thread -1 -> cpi 1.396308 (16162767/11575362) 4.000700: cpu 0, thread -1 -> cpi 1.092246 (20077258/18381624) 5.000867: cpu 0, thread -1 -> cpi 0.473816 (45157586/95306156) 6.001034: cpu 0, thread -1 -> cpi 0.532792 (43701668/82023818) 7.001195: cpu 0, thread -1 -> cpi 1.122059 (29890042/26638561)- Raw script stat data output:
$ perf stat -e cycles:u,instructions:u -A -C 0 -I 1000 record | perf --no-pager script CPU THREAD VAL ENA RUN TIME EVENT 0 -1 12302059 1000811347 1000810712 1000198821 cycles:u 0 -1 2565362 1000823218 1000823218 1000198821 instructions:u 0 -1 14453353 1000812704 1000812704 2000382283 cycles:u 0 -1 4600932 1000799342 1000799342 2000382283 instructions:u 0 -1 15245106 1000774425 1000774425 3000538255 cycles:u 0 -1 2624324 1000769310 1000769310 3000538255 instructions:u- To display different aggregation in report:
$ perf stat -e cycles -a -I 1000 record sleep 3 # time counts unit events 1.000223609 703,427,617 cycles 2.000443651 609,975,307 cycles 3.000569616 668,479,597 cycles 3.000735323 1,155,816 cycles$ perf stat report # time counts unit events 1.000223609 703,427,617 cycles 2.000443651 609,975,307 cycles 3.000569616 668,479,597 cycles 3.000735323 1,155,816 cycles$ perf stat report --per-core # time core cpus counts unit events 1.000223609 S0-C0 2 327,612,412 cycles 1.000223609 S0-C1 2 375,815,205 cycles 2.000443651 S0-C0 2 287,462,177 cycles 2.000443651 S0-C1 2 322,513,130 cycles 3.000569616 S0-C0 2 271,571,908 cycles 3.000569616 S0-C1 2 396,907,689 cycles 3.000735323 S0-C0 2 694,977 cycles 3.000735323 S0-C1 2 460,839 cycles$ perf stat report --per-socket # time socket cpus counts unit events 1.000223609 S0 4 703,427,617 cycles 2.000443651 S0 4 609,975,307 cycles 3.000569616 S0 4 668,479,597 cycles 3.000735323 S0 4 1,155,816 cycles$ perf stat report -A # time CPU counts unit events 1.000223609 CPU0 205,431,505 cycles 1.000223609 CPU1 122,180,907 cycles 1.000223609 CPU2 176,649,682 cycles 1.000223609 CPU3 199,165,523 cycles 2.000443651 CPU0 148,447,922 cycles 2.000443651 CPU1 139,014,255 cycles 2.000443651 CPU2 204,436,559 cycles 2.000443651 CPU3 118,076,571 cycles 3.000569616 CPU0 149,788,954 cycles 3.000569616 CPU1 121,782,954 cycles 3.000569616 CPU2 247,277,700 cycles 3.000569616 CPU3 149,629,989 cycles 3.000735323 CPU0 269,675 cycles 3.000735323 CPU1 425,302 cycles 3.000735323 CPU2 364,169 cycles 3.000735323 CPU3 96,670 cyclesCc Andi Kleen <[email protected]>Cc Ulrich Drepper <[email protected]>Cc Will Deacon <[email protected]>Cc Stephane Eranian <[email protected]>Cc Don Zickus <[email protected]>Tested-by Kan Liang <[email protected]>---
Jiri Olsa (52):
perfcpu_map: Addcpu_map__empty_newfunction
perf stat: Cache aggregated map entries in extra cpumap perf tools: Addthread_mapevent
perf tools: Addthread_mapevent sythesize function
perf tools: Addthread_map__new_eventfunction
perf tools: Addperf_event__fprintf_thread_mapfunction perf tools: Addcpu_mapevent
perf tools: Addcpu_mapevent synthesize function
perf tools: Addcpu_map__new_eventfunction
perf tools: Addperf_event__fprintf_cpu_mapfunction
perf tools: Add stat config event
perf tools: Add stat config event synthesize function
perf tools: Add stat config event read function
perf tools: Add stat event
perf tools: Add stat event synthesize function
perf tools: Add stat event read function
perf tools: Add stat round event
perf tools: Add stat round event synthesize function
perf tools: Add stat events fprintf functions
perf tools: Addevent_updateevent
perf tools: Addevent_updateevent unit type
perf tools: Addevent_updateevent scale type
perf tools: Addevent_updateevent name type
perf tools: Addevent_updateevent cpus type
perf tools: Addperf_event__fprintf_event_updatefunction perf report: Display newly added events in raw dump
perf tools: Introduce stat feature
perf tools: Moveid_offsetout of structperf_evselunion perf stat record: Add record command
perf stat record: Initialize record features
perf stat record: Synthesize stat record data
perf stat record: Store events IDs in perf data file
perf stat record: Add pipe support for record command
perf stat record: Write stat events on record
perf stat record: Write stat round events on record
perf stat record: Do not allow record with multiple runs mode perf stat record: Synthesize event update events
perf stat report: Add report command
perf stat report: Process cpu/threads maps
perf stat report: Process stat config event
perf stat report: Add support to initializeaggr_mapfrom file perf stat report: Process stat and stat round events
perf stat report: Process event update events
perf stat report: Movecsv_sepinitialization before report command perf stat report: Allow to overrideaggr_mode
perf script: Process cpu/threads maps
perf script: Process stat config event
perf script: Add process_stat/process_stat_interval scripting interface perf script: Add stat default handlers
perf script: Display stat events by default
perf script: Add python support for stat events
perf script: Addstat-cpi.pyscripttools/perf/Documentation/perf-stat.txt | 34 ++ tools/perf/builtin-record.c | 2 + tools/perf/builtin-script.c | 139 +++++ tools/perf/builtin-stat.c | 643 ++++++++++++++++++++- tools/perf/scripts/python/stat-cpi.py | 74 +++ tools/perf/tests/Build | 3 + tools/perf/tests/builtin-test.c | 24 + tools/perf/tests/cpumap.c | 88 +++ tools/perf/tests/event_update.c | 117 ++++ tools/perf/tests/stat.c | 111 ++++ tools/perf/tests/tests.h | 7 + tools/perf/tests/thread-map.c | 43 ++ tools/perf/util/cpumap.c | 59 ++ tools/perf/util/cpumap.h | 2 + tools/perf/util/event.c | 308 ++++++++++ tools/perf/util/event.h | 150 ++++- tools/perf/util/evlist.c | 6 +- tools/perf/util/evlist.h | 3 + tools/perf/util/evsel.h | 2 +- tools/perf/util/header.c | 205 +++++++ tools/perf/util/header.h | 17 + .../util/scripting-engines/trace-event-python.c | 114 +++- tools/perf/util/session.c | 189 ++++++ tools/perf/util/stat.c | 62 ++ tools/perf/util/stat.h | 10 + tools/perf/util/thread_map.c | 27 + tools/perf/util/thread_map.h | 3 + tools/perf/util/tool.h | 8 +- tools/perf/util/trace-event.h | 4 + 29 files changed, 2427 insertions(+), 27 deletions(-) create mode 100644 tools/perf/scripts/python/stat-cpi.py create mode 100644 tools/perf/tests/cpumap.c create mode 100644 tools/perf/tests/event_update.c create mode 100644 tools/perf/tests/stat.c
Liang, Kan
Tested-byQuoted 15 lines
Em Sun, Oct 25, 2015 at 03:51:16PM +0100, Jiri Olsa escreveu:
Quoted 7 lines
hi,
sending another version of stat scripting.v5 changes:
- several patches from v4 already taken
- using u16 for cpu number incpu_map_event
- renamedPERF_RECORD_HEADER_ATTR_UPDATEto
PERF_RECORD_EVENT_UPDATEQuoted 2 lines
- moved low hanging fuits patches to the start of the patchset
- patchset tested by Kan Liang, thanks!
Quoted 8 lines
So, next time please add the Tested-by: tag for the patches you haven't changed since Kan (or any other tester, I guess) said he tested.
I'm not adding it now, since I'm not checking one by one the patches to see the ones that changed, only re-reviewing them on their own.
If Kan could provide retest, I can go on and add the Tested-by tags,
Redo the test for V5. It looks good to me.
Thanks,
Kan
Quoted 310 lines
Thanks,
- Arnaldo
Quoted 31 lines
v4 changes:
- added attr update event for event's cpumask
- forbig aggregation on task workloads
- some minor reorders and changelog fixesv3 changes:
- added attr update event to handle unit,scale,name for event it fixed the uncore_imc_1/cas_count_read/ record/report
- perf report -D now displays stat related events
- some minor and changelog fixesv2 changes:
- rebased to latest Arnaldo's perf/core
- patches 1 to 11 already merged in
- added --per-core/--per-socket/-A options for perf stat report command to allow custom aggregation in stat report, please check new examples below
- couple changelogs changesThe initial attempt defined its own formula lang and allowed triggering user's script on the end of the stat command:
http://marc.info/?l=linux-kernel&m=136742146322273&w=2This patchset abandons the idea of new formula language and rather adds support to:
- store stat data into perf.data file
- add python support to process stat eventsBasically it allows to store stat data into perf.data and post process it with python scripts in a similar way we do for sampling data.
Quoted 8 lines
The stat data are stored in new stat, stat-round, stat-config user events.
stat - stored for each read syscall of the counter
stat round - stored for each interval or end of the command invocation stat config - stores all the config information needed to process data
so report tool could restore the same output as recordThe python script can now define 'stat__<eventname>_<modifier>' functions to get stat events data and '
stat__interval' to get stat-rounddata.
Quoted 86 lines
See CPI script example in
scripts/python/stat-cpi.py.Also available in:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/stat_scriptthanks,
jirkaExamples:
- To record data for command stat workload:
$ perf stat record kill ...Performance counter stats for 'kill':
0.372007 task-clock (msec) # 0.613 CPUs utilized 3 context-switches # 0.008 M/sec 0 cpu-migrations # 0.000 K/sec 62 page-faults # 0.167 M/sec 1,129,973 cycles # 3.038 GHz <not supported> stalled-cycles-frontend <not supported> stalled-cycles-backend 813,313 instructions # 0.72 insns per cycle 166,161 branches # 446.661 M/sec 8,747 branch-misses # 5.26% of all branches0.000607287 seconds time elapsed- To report perf stat data:
$ perf stat reportPerformance counter stats for '
/home/jolsa/bin/perfstat record kill':0.372007 task-clock (msec) # inf CPUs utilized 3 context-switches # 0.008 M/sec 0 cpu-migrations # 0.000 K/sec 62 page-faults # 0.167 M/sec 1,129,973 cycles # 3.038 GHz <not supported> stalled-cycles-frontend <not supported> stalled-cycles-backend 813,313 instructions # 0.72 insns per cycle 166,161 branches # 446.661 M/sec 8,747 branch-misses # 5.26% of all branches0.000000000 seconds time elapsed- To store system-wide period stat data:
$ perf stat -e cycles:u,instructions:u -a -I 1000 record # time counts unit events 1.000265471 462,311,482 cycles:u (100.00%) 1.000265471 590,037,440 instructions:u 2.000483453 722,532,336 cycles:u (100.00%) 2.000483453 848,678,197 instructions:u 3.000759876 75,990,880 cycles:u (100.00%) 3.000759876 86,187,813 instructions:u ^C 3.213960893 85,329,533 cycles:u (100.00%) 3.213960893 135,954,296 instructions:u- To report perf stat data:
$ perf stat report # time counts unit events 1.000265471 462,311,482 cycles:u (100.00%) 1.000265471 590,037,440 instructions:u 2.000483453 722,532,336 cycles:u (100.00%) 2.000483453 848,678,197 instructions:u 3.000759876 75,990,880 cycles:u (100.00%) 3.000759876 86,187,813 instructions:u 3.213960893 85,329,533 cycles:u (100.00%) 3.213960893 135,954,296 instructions:u- To run
stat-cpi.pyscript over perf.data:$ perf script -s scripts/python/stat-cpi.py 1.000265: cpu -1, thread -1 -> cpi 0.783529 (462311482/590037440) 2.000483: cpu -1, thread -1 -> cpi 0.851362 (722532336/848678197) 3.000760: cpu -1, thread -1 -> cpi 0.881689 (75990880/86187813) 3.213961: cpu -1, thread -1 -> cpi 0.627634 (85329533/135954296)Quoted 3 lines
- To pipe data from stat to stat-cpi script:
$ perf stat -e cycles:u,instructions:u -A -C 0 -I 1000 record | perf script -s
scripts/python/stat-cpi.pyQuoted 7 lines
1.000192: cpu 0, thread -1 -> cpi 0.739535 (23921908/32347236) 2.000376: cpu 0, thread -1 -> cpi 1.663482 (2519340/1514498) 3.000621: cpu 0, thread -1 -> cpi 1.396308 (16162767/11575362) 4.000700: cpu 0, thread -1 -> cpi 1.092246 (20077258/18381624) 5.000867: cpu 0, thread -1 -> cpi 0.473816 (45157586/95306156) 6.001034: cpu 0, thread -1 -> cpi 0.532792 (43701668/82023818) 7.001195: cpu 0, thread -1 -> cpi 1.122059Quoted 5 lines
(29890042/26638561)
- Raw script stat data output:
$ perf stat -e cycles:u,instructions:u -A -C 0 -I 1000 record | perf --no-pager script
Quoted 2 lines
CPU THREAD VAL ENA RUN TIME EVENT
0 -1 12302059 1000811347 1000810712 1000198821cycles:u
Quoted 1 line
0 -1 2565362 1000823218 1000823218 1000198821instructions:u
Quoted 1 line
0 -1 14453353 1000812704 1000812704 2000382283cycles:u
Quoted 1 line
0 -1 4600932 1000799342 1000799342 2000382283instructions:u
Quoted 1 line
0 -1 15245106 1000774425 1000774425 3000538255cycles:u
Quoted 1 line
0 -1 2624324 1000769310 1000769310 3000538255instructions:u
Quoted 150 lines
- To display different aggregation in report:
$ perf stat -e cycles -a -I 1000 record sleep 3 # time counts unit events 1.000223609 703,427,617 cycles 2.000443651 609,975,307 cycles 3.000569616 668,479,597 cycles 3.000735323 1,155,816 cycles$ perf stat report # time counts unit events 1.000223609 703,427,617 cycles 2.000443651 609,975,307 cycles 3.000569616 668,479,597 cycles 3.000735323 1,155,816 cycles$ perf stat report --per-core # time core cpus counts unit events 1.000223609 S0-C0 2 327,612,412 cycles 1.000223609 S0-C1 2 375,815,205 cycles 2.000443651 S0-C0 2 287,462,177 cycles 2.000443651 S0-C1 2 322,513,130 cycles 3.000569616 S0-C0 2 271,571,908 cycles 3.000569616 S0-C1 2 396,907,689 cycles 3.000735323 S0-C0 2 694,977 cycles 3.000735323 S0-C1 2 460,839 cycles$ perf stat report --per-socket # time socket cpus counts unit events 1.000223609 S0 4 703,427,617 cycles 2.000443651 S0 4 609,975,307 cycles 3.000569616 S0 4 668,479,597 cycles 3.000735323 S0 4 1,155,816 cycles$ perf stat report -A # time CPU counts unit events 1.000223609 CPU0 205,431,505 cycles 1.000223609 CPU1 122,180,907 cycles 1.000223609 CPU2 176,649,682 cycles 1.000223609 CPU3 199,165,523 cycles 2.000443651 CPU0 148,447,922 cycles 2.000443651 CPU1 139,014,255 cycles 2.000443651 CPU2 204,436,559 cycles 2.000443651 CPU3 118,076,571 cycles 3.000569616 CPU0 149,788,954 cycles 3.000569616 CPU1 121,782,954 cycles 3.000569616 CPU2 247,277,700 cycles 3.000569616 CPU3 149,629,989 cycles 3.000735323 CPU0 269,675 cycles 3.000735323 CPU1 425,302 cycles 3.000735323 CPU2 364,169 cycles 3.000735323 CPU3 96,670 cyclesCc Andi Kleen <[email protected]>Cc Ulrich Drepper <[email protected]>Cc Will Deacon <[email protected]>Cc Stephane Eranian <[email protected]>Cc Don Zickus <[email protected]>Tested-by Kan Liang <[email protected]>---
Jiri Olsa (52):
perfcpu_map: Addcpu_map__empty_newfunction
perf stat: Cache aggregated map entries in extra cpumap perf tools: Addthread_mapevent
perf tools: Addthread_mapevent sythesize function
perf tools: Addthread_map__new_eventfunction
perf tools: Addperf_event__fprintf_thread_mapfunction perf tools: Addcpu_mapevent
perf tools: Addcpu_mapevent synthesize function
perf tools: Addcpu_map__new_eventfunction
perf tools: Addperf_event__fprintf_cpu_mapfunction
perf tools: Add stat config event
perf tools: Add stat config event synthesize function
perf tools: Add stat config event read function
perf tools: Add stat event
perf tools: Add stat event synthesize function
perf tools: Add stat event read function
perf tools: Add stat round event
perf tools: Add stat round event synthesize function
perf tools: Add stat events fprintf functions
perf tools: Addevent_updateevent
perf tools: Addevent_updateevent unit type
perf tools: Addevent_updateevent scale type
perf tools: Addevent_updateevent name type
perf tools: Addevent_updateevent cpus type
perf tools: Addperf_event__fprintf_event_updatefunction perf report: Display newly added events in raw dump
perf tools: Introduce stat feature
perf tools: Moveid_offsetout of structperf_evselunion perf stat record: Add record command
perf stat record: Initialize record features
perf stat record: Synthesize stat record data
perf stat record: Store events IDs in perf data file
perf stat record: Add pipe support for record command
perf stat record: Write stat events on record
perf stat record: Write stat round events on record
perf stat record: Do not allow record with multiple runs mode perf stat record: Synthesize event update events
perf stat report: Add report command
perf stat report: Process cpu/threads maps
perf stat report: Process stat config event
perf stat report: Add support to initializeaggr_mapfrom file perf stat report: Process stat and stat round events
perf stat report: Process event update events
perf stat report: Movecsv_sepinitialization before report command perf stat report: Allow to overrideaggr_mode
perf script: Process cpu/threads maps
perf script: Process stat config event
perf script: Add process_stat/process_stat_interval scripting interface perf script: Add stat default handlers
perf script: Display stat events by default
perf script: Add python support for stat events
perf script: Addstat-cpi.pyscripttools/perf/Documentation/perf-stat.txt | 34 ++ tools/perf/builtin-record.c | 2 + tools/perf/builtin-script.c | 139 +++++ tools/perf/builtin-stat.c | 643 ++++++++++++++++++++- tools/perf/scripts/python/stat-cpi.py | 74 +++ tools/perf/tests/Build | 3 + tools/perf/tests/builtin-test.c | 24 + tools/perf/tests/cpumap.c | 88 +++ tools/perf/tests/event_update.c | 117 ++++ tools/perf/tests/stat.c | 111 ++++ tools/perf/tests/tests.h | 7 + tools/perf/tests/thread-map.c | 43 ++ tools/perf/util/cpumap.c | 59 ++ tools/perf/util/cpumap.h | 2 + tools/perf/util/event.c | 308 ++++++++++ tools/perf/util/event.h | 150 ++++- tools/perf/util/evlist.c | 6 +- tools/perf/util/evlist.h | 3 + tools/perf/util/evsel.h | 2 +- tools/perf/util/header.c | 205 +++++++ tools/perf/util/header.h | 17 + .../util/scripting-engines/trace-event-python.c | 114 +++- tools/perf/util/session.c | 189 ++++++ tools/perf/util/stat.c | 62 ++ tools/perf/util/stat.h | 10 + tools/perf/util/thread_map.c | 27 + tools/perf/util/thread_map.h | 3 + tools/perf/util/tool.h | 8 +- tools/perf/util/trace-event.h | 4 + 29 files changed, 2427 insertions(+), 27 deletions(-) create mode 100644 tools/perf/scripts/python/stat-cpi.py create mode 100644 tools/perf/tests/cpumap.c create mode 100644
tools/perf/tests/event_update.ccreate mode 100644tools/perf/tests/stat.c
Arnaldo Carvalho de Melo
maintainerEm Tue, Oct 27, 2015 at 02:24:03PM +0000, Liang, Kan escreveu:
Quoted 21 lines
Quoted 21 lines
Em Sun, Oct 25, 2015 at 03:51:16PM +0100, Jiri Olsa escreveu:
Quoted 7 lines
hi,
sending another version of stat scripting.v5 changes:
- several patches from v4 already taken
- using u16 for cpu number incpu_map_event
- renamedPERF_RECORD_HEADER_ATTR_UPDATEto
PERF_RECORD_EVENT_UPDATEQuoted 2 lines
- moved low hanging fuits patches to the start of the patchset
- patchset tested by Kan Liang, thanks!So, next time please add the Tested-by: tag for the patches you haven't changed since Kan (or any other tester, I guess) said he tested.
I'm not adding it now, since I'm not checking one by one the patches to see the ones that changed, only re-reviewing them on their own.
Quoted 6 lines
Quoted 2 lines
If Kan could provide retest, I can go on and add the Tested-by tags,
Redo the test for V5. It looks good to me.
Tested-by Kan Liang <[email protected]>
Thanks, adding this tag to the patches I processed so far, then repushing to the perf/stat branch.
- Arnaldo