perf/core improvements and fixes
Arnaldo Carvalho de Melo
maintainerFrom: Arnaldo Carvalho de Melo <[email protected]>
Hi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit 6eedf416429a32e0216f61b8b690d25577b2b91e:
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent (2015-06-26 10:38:11 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo
for you to fetch changes up to 36c8bb56a9f718a9a5f35d1834ca9dcec95deb4a:
perf symbols: Check access permission when reading symbol files (2015-06-26 12:11:53 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
User visible:
- Validate syscall list passed via -e argument to 'perf trace' (Arnaldo Carvalho de Melo)
- Introduce 'perf stat --per-thread' (Jiri Olsa)
- Check access permission for --kallsyms and --vmlinux (Li Zhang)
Infrastructure:
- Move stuff out of 'perf stat' and into the lib for further use (Jiri Olsa)
----------------------------------------------------------------
Arnaldo Carvalho de Melo (1):
perf trace: Validate syscall list passed via -e argument
Jiri Olsa (22):
perf thread_map: Introduce thread_map__reset function
perf thrad_map: Add comm string into array
perf tests: Add thread_map object tests
perf stat: Introduce perf_counts function
perf stat: Use xyarray for cpu evsel counts
perf stat: Make stats work over the thread dimension
perf stat: Rename struct perf_counts::cpu member to values perf stat: Introduce perf_evlist__reset_stats
perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into stat object perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into stat object perf stat: Move perf_evlist__(alloc|free|reset)_stats into stat object perf stat: Introduce perf_evsel__alloc_stats function
perf stat: Introduce perf_evsel__read function
perf stat: Introduce read_counters function
perf stat: Separate counters reading and processing
perf stat: Move zero_per_pkg into counter process code
perf stat: Move perf_stat initialization counter process code perf stat: Remove perf_evsel__read_cb function
perf stat: Rename print_interval to process_interval
perf stat: Using init_stats instead of memset
perf stat: Introduce print_counters function
perf stat: Introduce --per-thread option
Li Zhang (1):
perf symbols: Check access permission when reading symbol files
tools/perf/Documentation/perf-stat.txt | 4 + tools/perf/builtin-report.c | 11 + tools/perf/builtin-stat.c | 402 +++++++++++++++-------------- tools/perf/builtin-trace.c | 32 +++ tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/openat-syscall-all-cpus.c | 6 +- tools/perf/tests/openat-syscall.c | 4 +- tools/perf/tests/tests.h | 1 + tools/perf/tests/thread-map.c | 38 +++ tools/perf/util/evlist.h | 1 - tools/perf/util/evsel.c | 24 +- tools/perf/util/evsel.h | 28 +- tools/perf/util/python-ext-sources | 1 + tools/perf/util/stat.c | 132 +++++++++- tools/perf/util/stat.h | 47 +++- tools/perf/util/symbol.c | 5 +- tools/perf/util/thread_map.c | 76 +++++- tools/perf/util/thread_map.h | 8 + 19 files changed, 570 insertions(+), 255 deletions(-) create mode 100644 tools/perf/tests/thread-map.c
Arnaldo Carvalho de Melo
maintainerPATCH 1/24 perf trace: Validate syscall list passed via -e argument
From: Arnaldo Carvalho de Melo <[email protected]>
The 'trace' tool was accepting any names passed and just looking if syscalls returned via the raw_syscalls:* tracepoints were in that list, leading to it accepting perf events and then never finding any, as those are not valid syscall names, confusing users.
Fix it by checking each entry in the list using audit_name_to_syscall, telling the user which entries are invalid and suggesting where to look for valid syscall names.
E.g:
[root@zoo ~]# trace -e open,foo,bar,close,baz
Error: Invalid syscall bar, baz, foo
Hint: try 'perf list syscalls:sys_enter_*'
Hint: and: 'man syscalls'
[root@zoo ~]#
--- tools/perf/builtin-trace.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
tools/perf/builtin-trace.c +32 -0
@@ -1617,6 +1617,34 @@ static int trace__read_syscall_info(struct trace *trace, int id)return syscall__set_arg_fmts (sc); } +static int trace__validate_ev_qualifier (struct trace *trace) +{ +int err =0 ; +struct str_node *pos; + +strlist__for_each (pos, trace->ev_qualifier) { +const char *sc = pos->s; + +if (audit_name_to_syscall (sc, trace->audit.machine) <0 ) { +if (err ==0 ) { +fputs ("Error:\tInvalid syscall " , trace->output); + err = -EINVAL ; + }else { +fputs (", " , trace->output); + } + +fputs (sc, trace->output); + } + } + +if (err <0 ) { +fputs ("\nHint:\ttry 'perf list syscalls:sys_enter_*'" +"\nHint:\tand: 'man syscalls'\n" , trace->output); + } + +return err; +} +/* * args is to be interpreted as a series of longs but we need to handle * 8-byte unaligned accesses. args points to raw_data within the event
@@ -2862,6 +2890,10 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) err = -ENOMEM ; goto out_close; } + + err =trace__validate_ev_qualifier (&trace); +if (err) + goto out_close; } err =target__validate (&trace.opts.target);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 2/24 perf thread_map: Introduce thread_map__reset function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
We need to reset newly allocated 'struct thread_map_data' entries, because we will introduce new comm memeber, which will get set later or not at all.
--- tools/perf/util/thread_map.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
tools/perf/util/thread_map.c +16 -1
@@ -21,11 +21,26 @@ static int filter(const struct dirent *dir)return 1 ; } +static void thread_map__reset (struct thread_map *map,int start,int nr) +{ +size_t size = (nr - start) *sizeof (map->map[0 ]); + +memset (&map->map[start],0 , size); +} +static struct thread_map *thread_map__realloc (struct thread_map *map,int nr) {size_t size =sizeof (*map) +sizeof (map->map[0 ]) * nr; +int start = map ? map->nr :0 ; -return realloc (map, size); + map =realloc (map, size); +/* +* We only realloc to add more items, let's reset new items. +*/ +if (map) +thread_map__reset (map, start, nr); + +return map; }#define thread_map__alloc (__nr) thread_map__realloc(NULL, __nr)
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 3/24 perf thrad_map: Add comm string into array
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Adding support to hold comm name together with pids in 'struct thread_map'. It will be useful for --per-thread option to display task pid together with task name.
Adding thread_map__read_comms function that reads/set comm string for the 'struct thread_map'.
Getting the task name from /proc/$pid/comm.
--- tools/perf/util/python-ext-sources | 1 + tools/perf/util/thread_map.c | 59 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/thread_map.h | 8 ++++++ 3 files changed, 68 insertions(+)
tools/perf/util/python-ext-sources +1 -0
@@ -20,3 +20,4 @@ util/stat.c util/strlist.c util/trace-event.c ../../lib/rbtree.c +util/string.c
tools/perf/util/thread_map.c +59 -0
79 lines not on this page · raw message
tools/perf/util/thread_map.h +8 -0
@@ -7,6 +7,7 @@struct thread_map_data {pid_t pid; +char *comm; };struct thread_map {
@@ -44,4 +45,11 @@ thread_map__set_pid(struct thread_map *map, int thread, pid_t pid) { map->map[thread].pid = pid; } + +static inline char *thread_map__comm (struct thread_map *map,int thread) +{ +return map->map[thread].comm; +} + +void thread_map__read_comms (struct thread_map *threads);#endif /* __PERF_THREAD_MAP_H */
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 4/24 perf tests: Add thread_map object tests
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Adding thread_map object tests for comm name values.
--- tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/tests.h | 1 + tools/perf/tests/thread-map.c | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 tools/perf/tests/thread-map.c
tools/perf/tests/Build +1 -0
@@ -31,6 +31,7 @@ perf-y += code-reading.o perf-y += sample-parsing.o perf-y += parse-no-sample-id-all.o perf-y += kmod-path.o +perf-y += thread-map.o perf-$(CONFIG_X86) += perf-time-to-tsc.o
tools/perf/tests/builtin-test.c +4 -0
@@ -171,6 +171,10 @@ static struct test { .func = test__kmod_path__parse, }, { + .desc = "Test thread map", + .func = test__thread_map, + }, + { .func = NULL, }, };
tools/perf/tests/tests.h +1 -0
@@ -61,6 +61,7 @@ int test__switch_tracking(void);int test__fdarray__filter (void );int test__fdarray__add (void );int test__kmod_path__parse (void ); +int test__thread_map (void );#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/tests/thread-map.c new file +38 -0
@@ -0,0 +1,38 @@ +#include <sys/types.h> +#include <unistd.h> +#include "tests.h" +#include "thread_map.h" +#include "debug.h" + +int test__thread_map (void ) +{ +struct thread_map *map; + +/* test map on current pid */ + map =thread_map__new_by_pid (getpid ()); +TEST_ASSERT_VAL ("failed to alloc map" , map); + +thread_map__read_comms (map); + +TEST_ASSERT_VAL ("wrong nr" , map->nr ==1 ); +TEST_ASSERT_VAL ("wrong pid" , +thread_map__pid (map,0 ) ==getpid ()); +TEST_ASSERT_VAL ("wrong comm" , +thread_map__comm (map,0 ) && + !strcmp (thread_map__comm (map,0 ),"perf" )); +thread_map__put (map); + +/* test dummy pid */ + map =thread_map__new_dummy (); +TEST_ASSERT_VAL ("failed to alloc map" , map); + +thread_map__read_comms (map); + +TEST_ASSERT_VAL ("wrong nr" , map->nr ==1 ); +TEST_ASSERT_VAL ("wrong pid" ,thread_map__pid (map,0 ) ==-1 ); +TEST_ASSERT_VAL ("wrong comm" , +thread_map__comm (map,0 ) && + !strcmp (thread_map__comm (map,0 ),"dummy" )); +thread_map__put (map); +return 0 ; +}
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 5/24 perf stat: Introduce perf_counts function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Introducing perf_counts function, that returns 'struct perf_counts_values' pointer for given cpu.
Also moving perf_counts* structures into stat.h.
--- tools/perf/builtin-stat.c | 14 +++++++------- tools/perf/tests/openat-syscall-all-cpus.c | 4 ++-- tools/perf/tests/openat-syscall.c | 2 +- tools/perf/util/evsel.c | 6 +++--- tools/perf/util/evsel.h | 18 +----------------- tools/perf/util/stat.h | 23 +++++++++++++++++++++++ 6 files changed, 37 insertions(+), 30 deletions(-)
tools/perf/builtin-stat.c +7 -7
@@ -316,7 +316,7 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,if (!evsel->snapshot)perf_evsel__compute_deltas (evsel, cpu, count);perf_counts_values__scale (count, scale,NULL ); - evsel->counts->cpu[cpu] = *count; + *perf_counts (evsel->counts, cpu) = *count;if (aggr_mode ==AGGR_NONE )perf_stat__update_shadow_stats (evsel, count->values, cpu);break ;
@@ -805,9 +805,9 @@ static void print_aggr(char *prefix) s2 =aggr_get_id (evsel_list->cpus, cpu2);if (s2 != id)continue ; - val += counter->counts->cpu[cpu].val; - ena += counter->counts->cpu[cpu].ena; - run += counter->counts->cpu[cpu].run; + val +=perf_counts (counter->counts, cpu)->val; + ena +=perf_counts (counter->counts, cpu)->ena; + run +=perf_counts (counter->counts, cpu)->run; nr++; }if (prefix)
@@ -915,9 +915,9 @@ static void print_counter(struct perf_evsel *counter, char *prefix)int cpu;for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { - val = counter->counts->cpu[cpu].val; - ena = counter->counts->cpu[cpu].ena; - run = counter->counts->cpu[cpu].run; + val =perf_counts (counter->counts, cpu)->val; + ena =perf_counts (counter->counts, cpu)->ena; + run =perf_counts (counter->counts, cpu)->run;if (prefix)fprintf (output,"%s" , prefix);
tools/perf/tests/openat-syscall-all-cpus.c +2 -2
@@ -98,9 +98,9 @@ int test__openat_syscall_event_on_all_cpus(void) } expected = nr_openat_calls + cpu; -if (evsel->counts->cpu[cpu].val != expected) { +if (perf_counts (evsel->counts, cpu)->val != expected) {pr_debug ("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64"\n" , - expected, cpus->map[cpu], evsel->counts->cpu[cpu].val); + expected, cpus->map[cpu],perf_counts (evsel->counts, cpu)->val); err =-1 ; } }
tools/perf/tests/openat-syscall.c +1 -1
@@ -44,7 +44,7 @@ int test__openat_syscall_event(void) goto out_close_fd; } -if (evsel->counts->cpu[0 ].val != nr_openat_calls) { +if (perf_counts (evsel->counts,0 )->val != nr_openat_calls) {pr_debug ("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64"\n" , nr_openat_calls, evsel->counts->cpu[0 ].val); goto out_close_fd;
tools/perf/util/evsel.c +3 -3
@@ -910,8 +910,8 @@ void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu, tmp = evsel->prev_raw_counts->aggr; evsel->prev_raw_counts->aggr = *count; }else { - tmp = evsel->prev_raw_counts->cpu[cpu]; - evsel->prev_raw_counts->cpu[cpu] = *count; + tmp = *perf_counts (evsel->prev_raw_counts, cpu); + *perf_counts (evsel->prev_raw_counts, cpu) = *count; } count->val = count->val - tmp.val;
@@ -972,7 +972,7 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,perf_evsel__compute_deltas (evsel, cpu, &count);perf_counts_values__scale (&count, scale,NULL ); - evsel->counts->cpu[cpu] = count; + *perf_counts (evsel->counts, cpu) = count;return 0 ; }
tools/perf/util/evsel.h +1 -17
@@ -9,23 +9,7 @@#include "xyarray.h" #include "symbol.h" #include "cpumap.h" - -struct perf_counts_values { -union { -struct { -u64 val; -u64 ena; -u64 run; - }; -u64 values[3 ]; - }; -}; - -struct perf_counts { -s8 scaled; -struct perf_counts_values aggr; -struct perf_counts_values cpu[]; -}; +#include "stat.h" struct perf_evsel ;
tools/perf/util/stat.h +23 -0
@@ -31,6 +31,29 @@ enum aggr_mode { AGGR_CORE, }; +struct perf_counts_values { +union { +struct { +u64 val; +u64 ena; +u64 run; + }; +u64 values[3 ]; + }; +}; + +struct perf_counts { +s8 scaled; +struct perf_counts_values aggr; +struct perf_counts_values cpu[]; +}; + +static inline struct perf_counts_values * +perf_counts (struct perf_counts *counts,int cpu) +{ +return &counts->cpu[cpu]; +} +void update_stats (struct stats *stats,u64 val);double avg_stats (struct stats *stats);double stddev_stats (struct stats *stats);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 6/24 perf stat: Use xyarray for cpu evsel counts
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Switching single dimensional array of 'struct perf_counts_values' with xyarray object, so we could store thread dimension counts.
--- tools/perf/builtin-stat.c | 2 +- tools/perf/tests/openat-syscall.c | 2 +- tools/perf/util/stat.c | 31 ++++++++++++++++++++++--------- tools/perf/util/stat.h | 7 ++++--- 4 files changed, 28 insertions(+), 14 deletions(-)
tools/perf/builtin-stat.c +1 -1
@@ -218,7 +218,7 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)evlist__for_each (evlist, evsel) {perf_evsel__reset_stat_priv (evsel); -perf_evsel__reset_counts (evsel,perf_evsel__nr_cpus (evsel)); +perf_evsel__reset_counts (evsel); }perf_stat__reset_shadow_stats ();
tools/perf/tests/openat-syscall.c +1 -1
@@ -46,7 +46,7 @@ int test__openat_syscall_event(void)if (perf_counts (evsel->counts,0 )->val != nr_openat_calls) {pr_debug ("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64"\n" , - nr_openat_calls, evsel->counts->cpu[0 ].val); + nr_openat_calls,perf_counts (evsel->counts,0 )->val); goto out_close_fd; }
tools/perf/util/stat.c +22 -9
@@ -97,26 +97,39 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)struct perf_counts *perf_counts__new (int ncpus) { -int size =sizeof (struct perf_counts ) + - ncpus *sizeof (struct perf_counts_values ); +struct perf_counts *counts =zalloc (sizeof (*counts)); -return zalloc (size); +if (counts) { +struct xyarray *cpu; + + cpu =xyarray__new (ncpus,1 ,sizeof (struct perf_counts_values )); +if (!cpu) { +free (counts); +return NULL ; + } + + counts->cpu = cpu; + } + +return counts; }void perf_counts__delete (struct perf_counts *counts) { -free (counts); +if (counts) { +xyarray__delete (counts->cpu); +free (counts); + } } -static void perf_counts__reset (struct perf_counts *counts,int ncpus) +static void perf_counts__reset (struct perf_counts *counts) { -memset (counts,0 , (sizeof (*counts) + - (ncpus *sizeof (struct perf_counts_values )))); +xyarray__reset (counts->cpu); } -void perf_evsel__reset_counts (struct perf_evsel *evsel,int ncpus) +void perf_evsel__reset_counts (struct perf_evsel *evsel) { -perf_counts__reset (evsel->counts, ncpus); +perf_counts__reset (evsel->counts); }int perf_evsel__alloc_counts (struct perf_evsel *evsel,int ncpus)
tools/perf/util/stat.h +4 -3
@@ -3,6 +3,7 @@#include <linux/types.h> #include <stdio.h> +#include "xyarray.h" struct stats {
@@ -45,13 +46,13 @@ struct perf_counts_values {struct perf_counts {s8 scaled;struct perf_counts_values aggr; -struct perf_counts_values cpu[]; +struct xyarray *cpu; };static inline struct perf_counts_values *perf_counts (struct perf_counts *counts,int cpu) { -return &counts->cpu[cpu]; +return xyarray__entry (counts->cpu, cpu,0 ); }void update_stats (struct stats *stats,u64 val);
@@ -88,7 +89,7 @@ void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,struct perf_counts *perf_counts__new (int ncpus);void perf_counts__delete (struct perf_counts *counts); -void perf_evsel__reset_counts (struct perf_evsel *evsel,int ncpus); +void perf_evsel__reset_counts (struct perf_evsel *evsel);int perf_evsel__alloc_counts (struct perf_evsel *evsel,int ncpus);void perf_evsel__free_counts (struct perf_evsel *evsel);#endif
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 7/24 perf stat: Make stats work over the thread dimension
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Now that we have space for thread dimension counts, let's store it.
--- tools/perf/builtin-stat.c | 32 +++++++++++++++++------------- tools/perf/tests/openat-syscall-all-cpus.c | 6 +++--- tools/perf/tests/openat-syscall.c | 4 ++-- tools/perf/util/evsel.c | 12 +++++------ tools/perf/util/evsel.h | 2 +- tools/perf/util/stat.c | 8 ++++---- tools/perf/util/stat.h | 8 ++++---- 7 files changed, 38 insertions(+), 34 deletions(-)
tools/perf/builtin-stat.c +18 -14
@@ -166,11 +166,12 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)zfree (&evsel->priv); } -static int perf_evsel__alloc_prev_raw_counts (struct perf_evsel *evsel) +static int perf_evsel__alloc_prev_raw_counts (struct perf_evsel *evsel, +int ncpus,int nthreads) {struct perf_counts *counts; - counts =perf_counts__new (perf_evsel__nr_cpus (evsel)); + counts =perf_counts__new (ncpus, nthreads);if (counts) evsel->prev_raw_counts = counts;
@@ -197,11 +198,14 @@ static void perf_evlist__free_stats(struct perf_evlist *evlist)static int perf_evlist__alloc_stats (struct perf_evlist *evlist,bool alloc_raw) {struct perf_evsel *evsel; +int nthreads =thread_map__nr (evsel_list->threads);evlist__for_each (evlist, evsel) { +int ncpus =perf_evsel__nr_cpus (evsel); +if (perf_evsel__alloc_stat_priv (evsel) <0 || -perf_evsel__alloc_counts (evsel,perf_evsel__nr_cpus (evsel)) <0 || - (alloc_raw &&perf_evsel__alloc_prev_raw_counts (evsel) <0 )) +perf_evsel__alloc_counts (evsel, ncpus, nthreads) <0 || + (alloc_raw &&perf_evsel__alloc_prev_raw_counts (evsel, ncpus, nthreads) <0 )) goto out_free; }
@@ -294,7 +298,7 @@ static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)return 0 ; } -static int read_cb (struct perf_evsel *evsel,int cpu,int thread__maybe_unused , +static int read_cb (struct perf_evsel *evsel,int cpu,int thread,struct perf_counts_values *count) {struct perf_counts_values *aggr = &evsel->counts->aggr;
@@ -314,9 +318,9 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,case AGGR_SOCKET :case AGGR_NONE :if (!evsel->snapshot) -perf_evsel__compute_deltas (evsel, cpu, count); +perf_evsel__compute_deltas (evsel, cpu, thread, count);perf_counts_values__scale (count, scale,NULL ); - *perf_counts (evsel->counts, cpu) = *count; + *perf_counts (evsel->counts, cpu, thread) = *count;if (aggr_mode ==AGGR_NONE )perf_stat__update_shadow_stats (evsel, count->values, cpu);break ;
@@ -352,7 +356,7 @@ static int read_counter_aggr(struct perf_evsel *counter)return -1 ;if (!counter->snapshot) -perf_evsel__compute_deltas (counter,-1 , aggr); +perf_evsel__compute_deltas (counter,-1 ,-1 , aggr);perf_counts_values__scale (aggr, scale, &counter->counts->scaled);for (i =0 ; i <3 ; i++)
@@ -805,9 +809,9 @@ static void print_aggr(char *prefix) s2 =aggr_get_id (evsel_list->cpus, cpu2);if (s2 != id)continue ; - val +=perf_counts (counter->counts, cpu)->val; - ena +=perf_counts (counter->counts, cpu)->ena; - run +=perf_counts (counter->counts, cpu)->run; + val +=perf_counts (counter->counts, cpu,0 )->val; + ena +=perf_counts (counter->counts, cpu,0 )->ena; + run +=perf_counts (counter->counts, cpu,0 )->run; nr++; }if (prefix)
@@ -915,9 +919,9 @@ static void print_counter(struct perf_evsel *counter, char *prefix)int cpu;for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { - val =perf_counts (counter->counts, cpu)->val; - ena =perf_counts (counter->counts, cpu)->ena; - run =perf_counts (counter->counts, cpu)->run; + val =perf_counts (counter->counts, cpu,0 )->val; + ena =perf_counts (counter->counts, cpu,0 )->ena; + run =perf_counts (counter->counts, cpu,0 )->run;if (prefix)fprintf (output,"%s" , prefix);
tools/perf/tests/openat-syscall-all-cpus.c +3 -3
@@ -78,7 +78,7 @@ int test__openat_syscall_event_on_all_cpus(void)* we use the auto allocation it will allocate just for 1 cpu, * as we start by cpu 0. */ -if (perf_evsel__alloc_counts (evsel, cpus->nr) <0 ) { +if (perf_evsel__alloc_counts (evsel, cpus->nr,1 ) <0 ) {pr_debug ("perf_evsel__alloc_counts(ncpus=%d)\n" , cpus->nr); goto out_close_fd; }
@@ -98,9 +98,9 @@ int test__openat_syscall_event_on_all_cpus(void) } expected = nr_openat_calls + cpu; -if (perf_counts (evsel->counts, cpu)->val != expected) { +if (perf_counts (evsel->counts, cpu,0 )->val != expected) {pr_debug ("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64"\n" , - expected, cpus->map[cpu],perf_counts (evsel->counts, cpu)->val); + expected, cpus->map[cpu],perf_counts (evsel->counts, cpu,0 )->val); err =-1 ; } }
tools/perf/tests/openat-syscall.c +2 -2
@@ -44,9 +44,9 @@ int test__openat_syscall_event(void) goto out_close_fd; } -if (perf_counts (evsel->counts,0 )->val != nr_openat_calls) { +if (perf_counts (evsel->counts,0 ,0 )->val != nr_openat_calls) {pr_debug ("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64"\n" , - nr_openat_calls,perf_counts (evsel->counts,0 )->val); + nr_openat_calls,perf_counts (evsel->counts,0 ,0 )->val); goto out_close_fd; }
tools/perf/util/evsel.c +6 -6
@@ -898,7 +898,7 @@ void perf_evsel__delete(struct perf_evsel *evsel)free (evsel); } -void perf_evsel__compute_deltas (struct perf_evsel *evsel,int cpu, +void perf_evsel__compute_deltas (struct perf_evsel *evsel,int cpu,int thread,struct perf_counts_values *count) {struct perf_counts_values tmp;
@@ -910,8 +910,8 @@ void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu, tmp = evsel->prev_raw_counts->aggr; evsel->prev_raw_counts->aggr = *count; }else { - tmp = *perf_counts (evsel->prev_raw_counts, cpu); - *perf_counts (evsel->prev_raw_counts, cpu) = *count; + tmp = *perf_counts (evsel->prev_raw_counts, cpu, thread); + *perf_counts (evsel->prev_raw_counts, cpu, thread) = *count; } count->val = count->val - tmp.val;
@@ -964,15 +964,15 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,if (FD (evsel, cpu, thread) <0 )return -EINVAL ; -if (evsel->counts ==NULL &&perf_evsel__alloc_counts (evsel, cpu +1 ) <0 ) +if (evsel->counts ==NULL &&perf_evsel__alloc_counts (evsel, cpu +1 , thread +1 ) <0 )return -ENOMEM ;if (readn (FD (evsel, cpu, thread), &count, nv *sizeof (u64)) <0 )return -errno; -perf_evsel__compute_deltas (evsel, cpu, &count); +perf_evsel__compute_deltas (evsel, cpu, thread, &count);perf_counts_values__scale (&count, scale,NULL ); - *perf_counts (evsel->counts, cpu) = count; + *perf_counts (evsel->counts, cpu, thread) = count;return 0 ; }
tools/perf/util/evsel.h +1 -1
@@ -112,7 +112,7 @@ static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)void perf_counts_values__scale (struct perf_counts_values *count,bool scale,s8 *pscaled); -void perf_evsel__compute_deltas (struct perf_evsel *evsel,int cpu, +void perf_evsel__compute_deltas (struct perf_evsel *evsel,int cpu,int thread,struct perf_counts_values *count); int perf_evsel__object_config(size_t object_size,
tools/perf/util/stat.c +4 -4
@@ -95,14 +95,14 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel) } } -struct perf_counts *perf_counts__new (int ncpus) +struct perf_counts *perf_counts__new (int ncpus,int nthreads) {struct perf_counts *counts =zalloc (sizeof (*counts));if (counts) {struct xyarray *cpu; - cpu =xyarray__new (ncpus,1 ,sizeof (struct perf_counts_values )); + cpu =xyarray__new (ncpus, nthreads,sizeof (struct perf_counts_values ));if (!cpu) {free (counts);return NULL ;
@@ -132,9 +132,9 @@ void perf_evsel__reset_counts(struct perf_evsel *evsel)perf_counts__reset (evsel->counts); } -int perf_evsel__alloc_counts (struct perf_evsel *evsel,int ncpus) +int perf_evsel__alloc_counts (struct perf_evsel *evsel,int ncpus,int nthreads) { - evsel->counts =perf_counts__new (ncpus); + evsel->counts =perf_counts__new (ncpus, nthreads);return evsel->counts !=NULL ?0 : -ENOMEM ; }
tools/perf/util/stat.h +4 -4
@@ -50,9 +50,9 @@ struct perf_counts { };static inline struct perf_counts_values * -perf_counts (struct perf_counts *counts,int cpu) +perf_counts (struct perf_counts *counts,int cpu,int thread) { -return xyarray__entry (counts->cpu, cpu,0 ); +return xyarray__entry (counts->cpu, cpu, thread); }void update_stats (struct stats *stats,u64 val);
@@ -86,10 +86,10 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,void perf_stat__print_shadow_stats (FILE *out,struct perf_evsel *evsel,double avg,int cpu,enum aggr_mode aggr); -struct perf_counts *perf_counts__new (int ncpus); +struct perf_counts *perf_counts__new (int ncpus,int nthreads);void perf_counts__delete (struct perf_counts *counts);void perf_evsel__reset_counts (struct perf_evsel *evsel); -int perf_evsel__alloc_counts (struct perf_evsel *evsel,int ncpus); +int perf_evsel__alloc_counts (struct perf_evsel *evsel,int ncpus,int nthreads);void perf_evsel__free_counts (struct perf_evsel *evsel);#endif
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 8/24 perf stat: Rename struct perf_counts::cpu member to values
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Renaming 'struct xyarray *cpu' pointer to more fitting/generic values, because now we store both cpu and thread values.
--- tools/perf/util/stat.c | 12 ++++++------ tools/perf/util/stat.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-)
tools/perf/util/stat.c +6 -6
@@ -100,15 +100,15 @@ struct perf_counts *perf_counts__new(int ncpus, int nthreads)struct perf_counts *counts =zalloc (sizeof (*counts));if (counts) { -struct xyarray *cpu; +struct xyarray *values; - cpu =xyarray__new (ncpus, nthreads,sizeof (struct perf_counts_values )); -if (!cpu) { + values =xyarray__new (ncpus, nthreads,sizeof (struct perf_counts_values )); +if (!values) {free (counts);return NULL ; } - counts->cpu = cpu; + counts->values = values; }return counts;
@@ -117,14 +117,14 @@ struct perf_counts *perf_counts__new(int ncpus, int nthreads)void perf_counts__delete (struct perf_counts *counts) {if (counts) { -xyarray__delete (counts->cpu); +xyarray__delete (counts->values);free (counts); } }static void perf_counts__reset (struct perf_counts *counts) { -xyarray__reset (counts->cpu); +xyarray__reset (counts->values); }void perf_evsel__reset_counts (struct perf_evsel *evsel)
tools/perf/util/stat.h +2 -2
@@ -46,13 +46,13 @@ struct perf_counts_values {struct perf_counts {s8 scaled;struct perf_counts_values aggr; -struct xyarray *cpu; +struct xyarray *values; };static inline struct perf_counts_values *perf_counts (struct perf_counts *counts,int cpu,int thread) { -return xyarray__entry (counts->cpu, cpu, thread); +return xyarray__entry (counts->values, cpu, thread); }void update_stats (struct stats *stats,u64 val);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 9/24 perf stat: Introduce perf_evlist__reset_stats
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
To fit in with the rest of the helpers (alloc and free).
--- tools/perf/builtin-stat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
tools/perf/builtin-stat.c +6 -2
@@ -216,7 +216,7 @@ out_free:return -1 ; } -static void perf_stat__reset_stats (struct perf_evlist *evlist) +static void perf_evlist__reset_stats (struct perf_evlist *evlist) {struct perf_evsel *evsel;
@@ -224,7 +224,11 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)perf_evsel__reset_stat_priv (evsel);perf_evsel__reset_counts (evsel); } +} +static void perf_stat__reset_stats (void ) +{ +perf_evlist__reset_stats (evsel_list);perf_stat__reset_shadow_stats (); }
@@ -1473,7 +1477,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) status =run_perf_stat (argc, argv);if (forever && status !=-1 ) {print_stat (argc, argv); -perf_stat__reset_stats (evsel_list); +perf_stat__reset_stats (); } }
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 10/24 perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into stat object
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Moving perf_evsel__(alloc|free|reset)_stat_priv into stat object, so it could be used outside stat command in following patches.
--- tools/perf/builtin-stat.c | 25 ------------------------- tools/perf/util/stat.c | 25 +++++++++++++++++++++++++ tools/perf/util/stat.h | 4 ++++ 3 files changed, 29 insertions(+), 25 deletions(-)
tools/perf/builtin-stat.c +0 -25
@@ -141,31 +141,6 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a, } } -static void perf_evsel__reset_stat_priv (struct perf_evsel *evsel) -{ -int i; -struct perf_stat *ps = evsel->priv; - -for (i =0 ; i <3 ; i++) -init_stats (&ps->res_stats[i]); - -perf_stat_evsel_id_init (evsel); -} - -static int perf_evsel__alloc_stat_priv (struct perf_evsel *evsel) -{ - evsel->priv =zalloc (sizeof (struct perf_stat )); -if (evsel->priv ==NULL ) -return -ENOMEM ; -perf_evsel__reset_stat_priv (evsel); -return 0 ; -} - -static void perf_evsel__free_stat_priv (struct perf_evsel *evsel) -{ -zfree (&evsel->priv); -} -static int perf_evsel__alloc_prev_raw_counts (struct perf_evsel *evsel,int ncpus,int nthreads) {
tools/perf/util/stat.c +25 -0
@@ -143,3 +143,28 @@ void perf_evsel__free_counts(struct perf_evsel *evsel)perf_counts__delete (evsel->counts); evsel->counts =NULL ; } + +void perf_evsel__reset_stat_priv (struct perf_evsel *evsel) +{ +int i; +struct perf_stat *ps = evsel->priv; + +for (i =0 ; i <3 ; i++) +init_stats (&ps->res_stats[i]); + +perf_stat_evsel_id_init (evsel); +} + +int perf_evsel__alloc_stat_priv (struct perf_evsel *evsel) +{ + evsel->priv =zalloc (sizeof (struct perf_stat )); +if (evsel->priv ==NULL ) +return -ENOMEM ; +perf_evsel__reset_stat_priv (evsel); +return 0 ; +} + +void perf_evsel__free_stat_priv (struct perf_evsel *evsel) +{ +zfree (&evsel->priv); +}
tools/perf/util/stat.h +4 -0
@@ -92,4 +92,8 @@ void perf_counts__delete(struct perf_counts *counts);void perf_evsel__reset_counts (struct perf_evsel *evsel);int perf_evsel__alloc_counts (struct perf_evsel *evsel,int ncpus,int nthreads);void perf_evsel__free_counts (struct perf_evsel *evsel); + +void perf_evsel__reset_stat_priv (struct perf_evsel *evsel); +int perf_evsel__alloc_stat_priv (struct perf_evsel *evsel); +void perf_evsel__free_stat_priv (struct perf_evsel *evsel);#endif
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 11/24 perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into stat object
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Moving perf_evsel__(alloc|free)_prev_raw_counts into stat object, so it could be used in following patches.
--- tools/perf/builtin-stat.c | 18 ------------------ tools/perf/util/stat.c | 18 ++++++++++++++++++ tools/perf/util/stat.h | 4 ++++ 3 files changed, 22 insertions(+), 18 deletions(-)
tools/perf/builtin-stat.c +0 -18
@@ -141,24 +141,6 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a, } } -static int perf_evsel__alloc_prev_raw_counts (struct perf_evsel *evsel, -int ncpus,int nthreads) -{ -struct perf_counts *counts; - - counts =perf_counts__new (ncpus, nthreads); -if (counts) - evsel->prev_raw_counts = counts; - -return counts ?0 : -ENOMEM ; -} - -static void perf_evsel__free_prev_raw_counts (struct perf_evsel *evsel) -{ -perf_counts__delete (evsel->prev_raw_counts); - evsel->prev_raw_counts =NULL ; -} -static void perf_evlist__free_stats (struct perf_evlist *evlist) {struct perf_evsel *evsel;
tools/perf/util/stat.c +18 -0
@@ -168,3 +168,21 @@ void perf_evsel__free_stat_priv(struct perf_evsel *evsel) {zfree (&evsel->priv); } + +int perf_evsel__alloc_prev_raw_counts (struct perf_evsel *evsel, +int ncpus,int nthreads) +{ +struct perf_counts *counts; + + counts =perf_counts__new (ncpus, nthreads); +if (counts) + evsel->prev_raw_counts = counts; + +return counts ?0 : -ENOMEM ; +} + +void perf_evsel__free_prev_raw_counts (struct perf_evsel *evsel) +{ +perf_counts__delete (evsel->prev_raw_counts); + evsel->prev_raw_counts =NULL ; +}
tools/perf/util/stat.h +4 -0
@@ -96,4 +96,8 @@ void perf_evsel__free_counts(struct perf_evsel *evsel);void perf_evsel__reset_stat_priv (struct perf_evsel *evsel);int perf_evsel__alloc_stat_priv (struct perf_evsel *evsel);void perf_evsel__free_stat_priv (struct perf_evsel *evsel); + +int perf_evsel__alloc_prev_raw_counts (struct perf_evsel *evsel, +int ncpus,int nthreads); +void perf_evsel__free_prev_raw_counts (struct perf_evsel *evsel);#endif
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 12/24 perf stat: Move perf_evlist__(alloc|free|reset)_stats into stat object
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Moving perf_evlist__(alloc|free|reset)_stats into stat object, so it could be used in following patches.
--- tools/perf/builtin-stat.c | 42 ------------------------------------------ tools/perf/util/evlist.h | 1 - tools/perf/util/stat.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 6 ++++++ 4 files changed, 50 insertions(+), 43 deletions(-)
tools/perf/builtin-stat.c +0 -42
@@ -141,48 +141,6 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a, } } -static void perf_evlist__free_stats (struct perf_evlist *evlist) -{ -struct perf_evsel *evsel; - -evlist__for_each (evlist, evsel) { -perf_evsel__free_stat_priv (evsel); -perf_evsel__free_counts (evsel); -perf_evsel__free_prev_raw_counts (evsel); - } -} - -static int perf_evlist__alloc_stats (struct perf_evlist *evlist,bool alloc_raw) -{ -struct perf_evsel *evsel; -int nthreads =thread_map__nr (evsel_list->threads); - -evlist__for_each (evlist, evsel) { -int ncpus =perf_evsel__nr_cpus (evsel); - -if (perf_evsel__alloc_stat_priv (evsel) <0 || -perf_evsel__alloc_counts (evsel, ncpus, nthreads) <0 || - (alloc_raw &&perf_evsel__alloc_prev_raw_counts (evsel, ncpus, nthreads) <0 )) - goto out_free; - } - -return 0 ; - -out_free: -perf_evlist__free_stats (evlist); -return -1 ; -} - -static void perf_evlist__reset_stats (struct perf_evlist *evlist) -{ -struct perf_evsel *evsel; - -evlist__for_each (evlist, evsel) { -perf_evsel__reset_stat_priv (evsel); -perf_evsel__reset_counts (evsel); - } -} -static void perf_stat__reset_stats (void ) {perf_evlist__reset_stats (evsel_list);
tools/perf/util/evlist.h +0 -1
@@ -289,5 +289,4 @@ void perf_evlist__to_front(struct perf_evlist *evlist,void perf_evlist__set_tracking_event (struct perf_evlist *evlist,struct perf_evsel *tracking_evsel); -#endif /* __PERF_EVLIST_H */
tools/perf/util/stat.c +44 -0
53 lines not on this page · raw message
tools/perf/util/stat.h +6 -0
@@ -70,6 +70,8 @@ static inline void init_stats(struct stats *stats) }struct perf_evsel ; +struct perf_evlist ; +bool __perf_evsel_stat__is (struct perf_evsel *evsel,enum perf_stat_evsel_id id);
@@ -100,4 +102,8 @@ void perf_evsel__free_stat_priv(struct perf_evsel *evsel);int perf_evsel__alloc_prev_raw_counts (struct perf_evsel *evsel,int ncpus,int nthreads);void perf_evsel__free_prev_raw_counts (struct perf_evsel *evsel); + +int perf_evlist__alloc_stats (struct perf_evlist *evlist,bool alloc_raw); +void perf_evlist__free_stats (struct perf_evlist *evlist); +void perf_evlist__reset_stats (struct perf_evlist *evlist);#endif
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 13/24 perf stat: Introduce perf_evsel__alloc_stats function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Move all stat allocation logic related to stat object under single function. This way we can use it separately for stat object out of evlist object.
--- tools/perf/util/stat.c | 20 ++++++++++++++------ tools/perf/util/stat.h | 2 ++ 2 files changed, 16 insertions(+), 6 deletions(-)
tools/perf/util/stat.c +14 -6
@@ -189,17 +189,25 @@ void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel) evsel->prev_raw_counts =NULL ; } +int perf_evsel__alloc_stats (struct perf_evsel *evsel,bool alloc_raw) +{ +int ncpus =perf_evsel__nr_cpus (evsel); +int nthreads =thread_map__nr (evsel->threads); + +if (perf_evsel__alloc_stat_priv (evsel) <0 || +perf_evsel__alloc_counts (evsel, ncpus, nthreads) <0 || + (alloc_raw &&perf_evsel__alloc_prev_raw_counts (evsel, ncpus, nthreads) <0 )) +return -ENOMEM ; + +return 0 ; +} +int perf_evlist__alloc_stats (struct perf_evlist *evlist,bool alloc_raw) {struct perf_evsel *evsel; -int nthreads =thread_map__nr (evlist->threads);evlist__for_each (evlist, evsel) { -int ncpus =perf_evsel__nr_cpus (evsel); - -if (perf_evsel__alloc_stat_priv (evsel) <0 || -perf_evsel__alloc_counts (evsel, ncpus, nthreads) <0 || - (alloc_raw &&perf_evsel__alloc_prev_raw_counts (evsel, ncpus, nthreads) <0 )) +if (perf_evsel__alloc_stats (evsel, alloc_raw)) goto out_free; }
tools/perf/util/stat.h +2 -0
@@ -103,6 +103,8 @@ int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel, int ncpus, int nthreads);void perf_evsel__free_prev_raw_counts (struct perf_evsel *evsel); +int perf_evsel__alloc_stats (struct perf_evsel *evsel,bool alloc_raw); +int perf_evlist__alloc_stats (struct perf_evlist *evlist,bool alloc_raw);void perf_evlist__free_stats (struct perf_evlist *evlist);void perf_evlist__reset_stats (struct perf_evlist *evlist);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 14/24 perf stat: Introduce perf_evsel__read function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Adding simple read function that reads/store data into given struct perf_counts_values *count object.
--- tools/perf/util/evsel.c | 14 ++++++++++++++ tools/perf/util/evsel.h | 3 +++ 2 files changed, 17 insertions(+)
tools/perf/util/evsel.c +14 -0
@@ -955,6 +955,20 @@ int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,return cb (evsel, cpu, thread, &count); } +int perf_evsel__read (struct perf_evsel *evsel,int cpu,int thread, +struct perf_counts_values *count) +{ +memset (count,0 ,sizeof (*count)); + +if (FD (evsel, cpu, thread) <0 ) +return -EINVAL ; + +if (readn (FD (evsel, cpu, thread), count,sizeof (*count)) <0 ) +return -errno; + +return 0 ; +} +int __perf_evsel__read_on_cpu (struct perf_evsel *evsel,int cpu,int thread,bool scale) {
tools/perf/util/evsel.h +3 -0
@@ -236,6 +236,9 @@ typedef int (perf_evsel__read_cb_t)(struct perf_evsel *evsel,int perf_evsel__read_cb (struct perf_evsel *evsel,int cpu,int thread,perf_evsel__read_cb_t cb); +int perf_evsel__read (struct perf_evsel *evsel,int cpu,int thread, +struct perf_counts_values *count); +int __perf_evsel__read_on_cpu (struct perf_evsel *evsel,int cpu,int thread,bool scale);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 15/24 perf stat: Introduce read_counters function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Moving read counters logic into single read_counters function, which will be called for both interval and overall processing legs.
The reason is to split reading and processing (following patches) counters code, so we could read counters from other sources (like perf.data) and process them in the same way as 'perf stat' command does.
--- tools/perf/builtin-stat.c | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-)
tools/perf/builtin-stat.c +22 -25
@@ -323,27 +323,35 @@ static int read_counter(struct perf_evsel *counter)return 0 ; } -static void print_interval (void ) +static void read_counters (bool close) { -static int num_print_interval;struct perf_evsel *counter;struct perf_stat *ps; -struct timespec ts, rs; -char prefix[64 ]; -if (aggr_mode ==AGGR_GLOBAL ) { -evlist__for_each (evsel_list, counter) { - ps = counter->priv; -memset (ps->res_stats,0 ,sizeof (ps->res_stats)); +evlist__for_each (evsel_list, counter) { + ps = counter->priv; +memset (ps->res_stats,0 ,sizeof (ps->res_stats)); + +if (aggr_mode ==AGGR_GLOBAL )read_counter_aggr (counter); - } - }else { -evlist__for_each (evsel_list, counter) { - ps = counter->priv; -memset (ps->res_stats,0 ,sizeof (ps->res_stats)); +else read_counter (counter); + +if (close) { +perf_evsel__close_fd (counter,perf_evsel__nr_cpus (counter), +thread_map__nr (evsel_list->threads)); } } +} + +static void print_interval (void ) +{ +static int num_print_interval; +struct perf_evsel *counter; +struct timespec ts, rs; +char prefix[64 ]; + +read_counters (false);clock_gettime (CLOCK_MONOTONIC , &ts);diff_timespec (&rs, &ts, &ref_time);
@@ -525,18 +533,7 @@ static int __run_perf_stat(int argc, const char **argv)update_stats (&walltime_nsecs_stats, t1 - t0); -if (aggr_mode ==AGGR_GLOBAL ) { -evlist__for_each (evsel_list, counter) { -read_counter_aggr (counter); -perf_evsel__close_fd (counter,perf_evsel__nr_cpus (counter), -thread_map__nr (evsel_list->threads)); - } - }else { -evlist__for_each (evsel_list, counter) { -read_counter (counter); -perf_evsel__close_fd (counter,perf_evsel__nr_cpus (counter),1 ); - } - } +read_counters (true);return WEXITSTATUS (status); }
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 16/24 perf stat: Separate counters reading and processing
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Separating counters reading and processing so we could use the processing part in following patches.
Using simple reading via perf_evsel__read function to read counters now, because part of the processing was in the read_cb callback.
--- tools/perf/builtin-stat.c | 56 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 17 deletions(-)
tools/perf/builtin-stat.c +39 -17
@@ -217,8 +217,9 @@ static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)return 0 ; } -static int read_cb (struct perf_evsel *evsel,int cpu,int thread, -struct perf_counts_values *count) +static int +process_counter_values (struct perf_evsel *evsel,int cpu,int thread, +struct perf_counts_values *count) {struct perf_counts_values *aggr = &evsel->counts->aggr;static struct perf_counts_values zero;
@@ -239,7 +240,6 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread,if (!evsel->snapshot)perf_evsel__compute_deltas (evsel, cpu, thread, count);perf_counts_values__scale (count, scale,NULL ); - *perf_counts (evsel->counts, cpu, thread) = *count;if (aggr_mode ==AGGR_NONE )perf_stat__update_shadow_stats (evsel, count->values, cpu);break ;
@@ -256,23 +256,41 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread,return 0 ; } -static int read_counter (struct perf_evsel *counter); +static int process_counter_maps (struct perf_evsel *counter) +{ +int nthreads =thread_map__nr (counter->threads); +int ncpus =perf_evsel__nr_cpus (counter); +int cpu, thread; -/* -* Read out the results of a single counter: -* aggregate counts across CPUs in system-wide mode -*/ -static int read_counter_aggr (struct perf_evsel *counter) +if (counter->system_wide) + nthreads =1 ; + +for (thread =0 ; thread < nthreads; thread++) { +for (cpu =0 ; cpu < ncpus; cpu++) { +if (process_counter_values (counter, cpu, thread, +perf_counts (counter->counts, cpu, thread))) +return -1 ; + } + } + +return 0 ; +} + +static int process_counter (struct perf_evsel *counter) {struct perf_counts_values *aggr = &counter->counts->aggr;struct perf_stat *ps = counter->priv;u64 *count = counter->counts->aggr.values; -int i; +int i, ret; aggr->val = aggr->ena = aggr->run =0 ; -if (read_counter (counter)) -return -1 ; + ret =process_counter_maps (counter); +if (ret) +return ret; + +if (aggr_mode !=AGGR_GLOBAL ) +return 0 ;if (!counter->snapshot)perf_evsel__compute_deltas (counter,-1 ,-1 , aggr);
@@ -315,7 +333,10 @@ static int read_counter(struct perf_evsel *counter)for (thread =0 ; thread < nthreads; thread++) {for (cpu =0 ; cpu < ncpus; cpu++) { -if (perf_evsel__read_cb (counter, cpu, thread, read_cb)) +struct perf_counts_values *count; + + count =perf_counts (counter->counts, cpu, thread); +if (perf_evsel__read (counter, cpu, thread, count))return -1 ; } }
@@ -332,10 +353,11 @@ static void read_counters(bool close) ps = counter->priv;memset (ps->res_stats,0 ,sizeof (ps->res_stats)); -if (aggr_mode ==AGGR_GLOBAL ) -read_counter_aggr (counter); -else -read_counter (counter); +if (read_counter (counter)) +pr_warning ("failed to read counter %s\n" , counter->name); + +if (process_counter (counter)) +pr_warning ("failed to process counter %s\n" , counter->name);if (close) { perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 17/24 perf stat: Move zero_per_pkg into counter process code
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Moving zero_per_pkg into counter process code, to make the reading path free of processing logic.
--- tools/perf/builtin-stat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +3 -3
@@ -285,6 +285,9 @@ static int process_counter(struct perf_evsel *counter) aggr->val = aggr->ena = aggr->run =0 ; +if (counter->per_pkg) +zero_per_pkg (counter); + ret =process_counter_maps (counter);if (ret)return ret;
@@ -328,9 +331,6 @@ static int read_counter(struct perf_evsel *counter)if (counter->system_wide) nthreads =1 ; -if (counter->per_pkg) -zero_per_pkg (counter); -for (thread =0 ; thread < nthreads; thread++) {for (cpu =0 ; cpu < ncpus; cpu++) {struct perf_counts_values *count;
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 18/24 perf stat: Move perf_stat initialization counter process code
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Moving perf_stat initialization counter process code, to make the reading path free of processing logic.
--- tools/perf/builtin-stat.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
tools/perf/builtin-stat.c +1 -4
@@ -284,6 +284,7 @@ static int process_counter(struct perf_evsel *counter)int i, ret; aggr->val = aggr->ena = aggr->run =0 ; +memset (ps->res_stats,0 ,sizeof (ps->res_stats));if (counter->per_pkg)zero_per_pkg (counter);
@@ -347,12 +348,8 @@ static int read_counter(struct perf_evsel *counter)static void read_counters (bool close) {struct perf_evsel *counter; -struct perf_stat *ps;evlist__for_each (evsel_list, counter) { - ps = counter->priv; -memset (ps->res_stats,0 ,sizeof (ps->res_stats)); -if (read_counter (counter))pr_warning ("failed to read counter %s\n" , counter->name);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 19/24 perf stat: Remove perf_evsel__read_cb function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
It's no longer used, the stat command uses perf_evsel__read now.
--- tools/perf/util/evsel.c | 16 ---------------- tools/perf/util/evsel.h | 7 ------- 2 files changed, 23 deletions(-)
tools/perf/util/evsel.c +0 -16
@@ -939,22 +939,6 @@ void perf_counts_values__scale(struct perf_counts_values *count, *pscaled = scaled; } -int perf_evsel__read_cb (struct perf_evsel *evsel,int cpu,int thread, -perf_evsel__read_cb_t cb) -{ -struct perf_counts_values count; - -memset (&count,0 ,sizeof (count)); - -if (FD (evsel, cpu, thread) <0 ) -return -EINVAL ; - -if (readn (FD (evsel, cpu, thread), &count,sizeof (count)) <0 ) -return -errno; - -return cb (evsel, cpu, thread, &count); -} -int perf_evsel__read (struct perf_evsel *evsel,int cpu,int thread,struct perf_counts_values *count) {
tools/perf/util/evsel.h +0 -7
@@ -229,13 +229,6 @@ static inline bool perf_evsel__match2(struct perf_evsel *e1, (a)->attr.type == (b)->attr.type && \ (a)->attr.config == (b)->attr.config) -typedef int (perf_evsel__read_cb_t )(struct perf_evsel *evsel, -int cpu,int thread, -struct perf_counts_values *count); - -int perf_evsel__read_cb (struct perf_evsel *evsel,int cpu,int thread, -perf_evsel__read_cb_t cb); -int perf_evsel__read (struct perf_evsel *evsel,int cpu,int thread,struct perf_counts_values *count);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 20/24 perf stat: Rename print_interval to process_interval
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
It suits better, because the function also reads counter's data.
Also the 'print_interval' name will be used in following generalization of counters display.
--- tools/perf/builtin-stat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +3 -3
@@ -363,7 +363,7 @@ static void read_counters(bool close) } } -static void print_interval (void ) +static void process_interval (void ) {static int num_print_interval;struct perf_evsel *counter;
@@ -526,7 +526,7 @@ static int __run_perf_stat(int argc, const char **argv)if (interval) {while (!waitpid (child_pid, &status,WNOHANG )) {nanosleep (&ts,NULL ); -print_interval (); +process_interval (); } }wait (&status);
@@ -544,7 +544,7 @@ static int __run_perf_stat(int argc, const char **argv)while (!done) {nanosleep (&ts,NULL );if (interval) -print_interval (); +process_interval (); } }
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 21/24 perf stat: Using init_stats instead of memset
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
The init_stats function is meant to init 'struct stats'.
--- tools/perf/builtin-stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-stat.c +1 -1
@@ -284,7 +284,7 @@ static int process_counter(struct perf_evsel *counter)int i, ret; aggr->val = aggr->ena = aggr->run =0 ; -memset (ps->res_stats,0 ,sizeof (ps->res_stats)); +init_stats (ps->res_stats);if (counter->per_pkg)zero_per_pkg (counter);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 22/24 perf stat: Introduce print_counters function
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Centralize counters print code into single print_counters function.
--- tools/perf/builtin-stat.c | 127 +++++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 63 deletions(-)
tools/perf/builtin-stat.c +64 -63
@@ -67,10 +67,7 @@#define CNTR_NOT_SUPPORTED "<not supported>"#define CNTR_NOT_COUNTED "<not counted>" -static void print_stat (int argc,const char **argv); -static void print_counter_aggr (struct perf_evsel *counter,char *prefix); -static void print_counter (struct perf_evsel *counter,char *prefix); -static void print_aggr (char *prefix); +static void print_counters (struct timespec *ts,int argc,const char **argv);/* Default events used for perf stat -T */ static const char *transaction_attrs = {
@@ -365,53 +362,14 @@ static void read_counters(bool close)static void process_interval (void ) { -static int num_print_interval; -struct perf_evsel *counter;struct timespec ts, rs; -char prefix[64 ];read_counters (false);clock_gettime (CLOCK_MONOTONIC , &ts);diff_timespec (&rs, &ts, &ref_time); -sprintf (prefix,"%6lu.%09lu%s" , rs.tv_sec, rs.tv_nsec, csv_sep); - -if (num_print_interval ==0 && !csv_output) { -switch (aggr_mode) { -case AGGR_SOCKET : -fprintf (output,"# time socket cpus counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_CORE : -fprintf (output,"# time core cpus counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_NONE : -fprintf (output,"# time CPU counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_GLOBAL : -default : -fprintf (output,"# time counts %*s events\n" , unit_width,"unit" ); - } - } - -if (++num_print_interval ==25 ) - num_print_interval =0 ; -switch (aggr_mode) { -case AGGR_CORE : -case AGGR_SOCKET : -print_aggr (prefix); -break ; -case AGGR_NONE : -evlist__for_each (evsel_list, counter) -print_counter (counter, prefix); -break ; -case AGGR_GLOBAL : -default : -evlist__for_each (evsel_list, counter) -print_counter_aggr (counter, prefix); - } - -fflush (output); +print_counters (&rs,0 ,NULL ); }static void handle_initial_delay (void )
@@ -901,9 +859,35 @@ static void print_counter(struct perf_evsel *counter, char *prefix) } } -static void print_stat (int argc,const char **argv) +static void print_interval (char *prefix,struct timespec *ts) +{ +static int num_print_interval; + +sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, csv_sep); + +if (num_print_interval ==0 && !csv_output) { +switch (aggr_mode) { +case AGGR_SOCKET : +fprintf (output,"# time socket cpus counts %*s events\n" , unit_width,"unit" ); +break ; +case AGGR_CORE : +fprintf (output,"# time core cpus counts %*s events\n" , unit_width,"unit" ); +break ; +case AGGR_NONE : +fprintf (output,"# time CPU counts %*s events\n" , unit_width,"unit" ); +break ; +case AGGR_GLOBAL : +default : +fprintf (output,"# time counts %*s events\n" , unit_width,"unit" ); + } + } + +if (++num_print_interval ==25 ) + num_print_interval =0 ; +} + +static void print_header (int argc,const char **argv) { -struct perf_evsel *counter;int i;fflush (stdout);
@@ -929,36 +913,53 @@ static void print_stat(int argc, const char **argv)fprintf (output," (%d runs)" , run_count);fprintf (output,":\n\n" ); } +} + +static void print_footer (void ) +{ +if (!null_run) +fprintf (output,"\n" ); +fprintf (output," %17.9f seconds time elapsed" , +avg_stats (&walltime_nsecs_stats)/1e9 ); +if (run_count >1 ) { +fprintf (output," " ); +print_noise_pct (stddev_stats (&walltime_nsecs_stats), +avg_stats (&walltime_nsecs_stats)); + } +fprintf (output,"\n\n" ); +} + +static void print_counters (struct timespec *ts,int argc,const char **argv) +{ +struct perf_evsel *counter; +char buf[64 ], *prefix =NULL ; + +if (interval) +print_interval (prefix = buf, ts); +else +print_header (argc, argv);switch (aggr_mode) {case AGGR_CORE :case AGGR_SOCKET : -print_aggr (NULL ); +print_aggr (prefix);break ;case AGGR_GLOBAL :evlist__for_each (evsel_list, counter) -print_counter_aggr (counter,NULL ); +print_counter_aggr (counter, prefix);break ;case AGGR_NONE :evlist__for_each (evsel_list, counter) -print_counter (counter,NULL ); +print_counter (counter, prefix);break ;default :break ; } -if (!csv_output) { -if (!null_run) -fprintf (output,"\n" ); -fprintf (output," %17.9f seconds time elapsed" , -avg_stats (&walltime_nsecs_stats)/1e9 ); -if (run_count >1 ) { -fprintf (output," " ); -print_noise_pct (stddev_stats (&walltime_nsecs_stats), -avg_stats (&walltime_nsecs_stats)); - } -fprintf (output,"\n\n" ); - } +if (!interval && !csv_output) +print_footer (); + +fflush (output); }static volatile int signr =-1 ;
@@ -1407,13 +1408,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) status =run_perf_stat (argc, argv);if (forever && status !=-1 ) { -print_stat (argc, argv); +print_counters (NULL , argc, argv);perf_stat__reset_stats (); } }if (!forever && status !=-1 && !interval) -print_stat (argc, argv); +print_counters (NULL , argc, argv);perf_evlist__free_stats (evsel_list); out:
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 23/24 perf stat: Introduce --per-thread option
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Currently all the -p option PID arguments tasks values get aggregated and printed as single values.
Adding --per-tasks option to print values per task.
$ perf stat -e cycles,instructions --per-thread -p 30190,30242 ^C Performance counter stats for process id '30190,30242':
cat-30190 0 cycles
yes-30242 3,842,525,421 cycles
cat-30190 0 instructions
yes-30242 10,370,817,010 instructions1.143155657 seconds time elapsed
Also works under interval mode:
$ perf stat -e cycles,instructions --per-thread -p 30190,30242 -I 1000
# time comm-pid counts unit events
1.000073435 cat-30190 89,058 cycles
1.000073435 yes-30242 3,360,786,902 cycles (100.00%)
1.000073435 cat-30190 14,066 instructions
1.000073435 yes-30242 9,069,937,462 instructions
2.000204830 cat-30190 0 cycles
2.000204830 yes-30242 3,351,667,626 cycles
2.000204830 cat-30190 0 instructions
2.000204830 yes-30242 9,045,796,885 instructions
^C 2.771286639 cat-30190 0 cycles
2.771286639 yes-30242 2,593,884,166 cycles
2.771286639 cat-30190 0 instructions
2.771286639 yes-30242 7,001,171,191 instructionsIt works only with -t and -p options, otherwise following error is printed:
$ perf stat -e cycles --per-thread -I 1000 ls
The --per-thread option is only available when monitoring via -p -t options.
-p, --pid <pid> stat events on existing process id
-t, --tid <tid> stat events on existing thread id--- tools/perf/Documentation/perf-stat.txt | 4 ++ tools/perf/builtin-stat.c | 76 +++++++++++++++++++++++++++++++++- tools/perf/util/stat.h | 1 + 3 files changed, 79 insertions(+), 2 deletions(-)
tools/perf/Documentation/perf-stat.txt +4 -0
@@ -144,6 +144,10 @@ is a useful mode to detect imbalance between physical cores. To enable this mod use --per-core in addition to -a. (system-wide). The output includes the core number and the number of online logical processors on that physical processor. +--per-thread:: +Aggregate counts per monitored threads, when monitoring threads (-t option) +or processes (-p option). + -D msecs:: --delay msecs:: After starting the program, wait msecs before measuring. This is useful to
tools/perf/builtin-stat.c +74 -2
130 lines not on this page · raw message
tools/perf/util/stat.h +1 -0
@@ -30,6 +30,7 @@ enum aggr_mode {AGGR_GLOBAL ,AGGR_SOCKET ,AGGR_CORE , + AGGR_THREAD, }; struct perf_counts_values {
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 24/24 perf symbols: Check access permission when reading symbol files
In reply to Arnaldo Carvalho de MeloFrom: Li Zhang <[email protected]>
There 2 problems when reading symbols files:
* It doesn't report any errors even if when users specify symbol files which don't exist with --kallsyms or --vmlinux. The result just shows the address without symbols, which is not what is expected. So it's better to report errors and exit the program.
* When using command perf report --kallsyms=/proc/kallsyms with a non-root user, symbols are resolved. Then select one symbol and annotate it, it reports the error as the following:
Can't annotate __clear_user: No vmlinux file with build id xxx was found.
The problem is caused by reading /proc/kcore without access permission. /proc/kcore requires CAP_SYS_RAWIO capability to access, so it needs to change access permission to allow a specific user to read /proc/kcore or use root to execute the perf command.
This patch is to report errors when symbol files specified by users don't exist. And check access permission of /proc/kcore when reading it.
--- tools/perf/builtin-report.c | 11 +++++++++++ tools/perf/util/symbol.c | 5 ++++- 2 files changed, 15 insertions(+), 1 deletion(-)
tools/perf/builtin-report.c +11 -0
@@ -742,6 +742,17 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) argc =parse_options (argc, argv, options, report_usage,0 ); +if (symbol_conf.vmlinux_name && +access (symbol_conf.vmlinux_name,R_OK )) { +pr_err ("Invalid file: %s\n" , symbol_conf.vmlinux_name); +return -EINVAL ; + } +if (symbol_conf.kallsyms_name && +access (symbol_conf.kallsyms_name,R_OK )) { +pr_err ("Invalid file: %s\n" , symbol_conf.kallsyms_name); +return -EINVAL ; + } +if (report.use_stdio) use_browser =0 ;else if (report.use_tui)
tools/perf/util/symbol.c +4 -1
@@ -1132,8 +1132,11 @@ static int dso__load_kcore(struct dso *dso, struct map *map,INIT_LIST_HEAD (&md.maps); fd =open (kcore_filename,O_RDONLY ); -if (fd <0 ) +if (fd <0 ) { +pr_err ("%s requires CAP_SYS_RAWIO capability to access.\n" , + kcore_filename);return -EINVAL ; + }/* Read new maps into temporary lists */ err = file__read_maps(fd, md.type == MAP__FUNCTION, kcore_mapfn, &md,
Signature · 1 line
2.1.0
Quoted 81 lines · Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <[email protected]>
Hi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit
6eedf416429a32e0216f61b8b690d25577b2b91e:Merge tag 'perf-core-for-mingo' of
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linuxinto perf/urgent (2015-06-26 10:38:11 +0200)are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-core-for-mingofor you to fetch changes up to
36c8bb56a9f718a9a5f35d1834ca9dcec95deb4a:perf symbols: Check access permission when reading symbol files (2015-06-26 12:11:53 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:User visible:
- Validate syscall list passed via -e argument to 'perf trace' (Arnaldo Carvalho de Melo)
- Introduce 'perf stat --per-thread' (Jiri Olsa)
- Check access permission for --kallsyms and --vmlinux (Li Zhang)
Infrastructure:
- Move stuff out of 'perf stat' and into the lib for further use (Jiri Olsa)
Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
Arnaldo Carvalho de Melo (1):
perf trace: Validate syscall list passed via -e argumentJiri Olsa (22):
perfthread_map: Introducethread_map__resetfunction
perfthrad_map: Add comm string into array
perf tests: Addthread_mapobject tests
perf stat: Introduceperf_countsfunction
perf stat: Use xyarray for cpu evsel counts
perf stat: Make stats work over the thread dimension
perf stat: Rename structperf_counts::cpumember to values perf stat: Introduceperf_evlist__reset_stats
perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into stat object perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into stat object perf stat: Move perf_evlist__(alloc|free|reset)_stats into stat object perf stat: Introduceperf_evsel__alloc_statsfunction
perf stat: Introduceperf_evsel__readfunction
perf stat: Introduceread_countersfunction
perf stat: Separate counters reading and processing
perf stat: Movezero_per_pkginto counter process code
perf stat: Moveperf_statinitialization counter process code perf stat: Removeperf_evsel__read_cbfunction
perf stat: Renameprint_intervaltoprocess_interval
perf stat: Usinginit_statsinstead of memset
perf stat: Introduceprint_countersfunction
perf stat: Introduce --per-thread optionLi Zhang (1):
perf symbols: Check access permission when reading symbol filestools/perf/Documentation/perf-stat.txt | 4 + tools/perf/builtin-report.c | 11 + tools/perf/builtin-stat.c | 402 +++++++++++++++-------------- tools/perf/builtin-trace.c | 32 +++ tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/openat-syscall-all-cpus.c | 6 +- tools/perf/tests/openat-syscall.c | 4 +- tools/perf/tests/tests.h | 1 + tools/perf/tests/thread-map.c | 38 +++ tools/perf/util/evlist.h | 1 - tools/perf/util/evsel.c | 24 +- tools/perf/util/evsel.h | 28 +-
Quoted 8 lines
tools/perf/util/python-ext-sources | 1 + tools/perf/util/stat.c | 132 +++++++++- tools/perf/util/stat.h | 47 +++- tools/perf/util/symbol.c | 5 +- tools/perf/util/thread_map.c | 76 +++++- tools/perf/util/thread_map.h | 8 + 19 files changed, 570 insertions(+), 255 deletions(-) create mode 100644 tools/perf/tests/thread-map.c
Pulled, thanks a lot Arnaldo!
Ingo