perf evsel: Support perf_evsel__open(cpus > 1 && threads > 1)
Commit-ID: 0252208eb52f6fe8731a47804eddc7ba93f60a87 Gitweb: http://git.kernel.org/tip/0252208eb52f6fe8731a47804eddc7ba93f60a87 Author: Arnaldo Carvalho de Melo <[email protected]> AuthorDate: Tue, 4 Jan 2011 11:55:27 -0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 10 Jan 2011 22:03:26 -0200
perf evsel: Support perf_evsel__open(cpus > 1 && threads > 1)
And a test for it:
[acme@felicio linux]$ perf test
1: vmlinux symtab matches kallsyms: Ok
2: detect open syscall event: Ok
3: detect open syscall event on all cpus: Ok
[acme@felicio linux]$
Translating C the test does:
1. generates different number of open syscalls on each CPU by using sched_setaffinity
2. Verifies that the expected number of events is generated on each CPU
It works as expected.
LKML-Reference: <new-submission>
Cc Frederic Weisbecker <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Tom Zanussi <[email protected]>
Signed-off-by Arnaldo Carvalho de Melo <[email protected]>
--- tools/perf/builtin-test.c | 110 +++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/evsel.c | 82 ++++++++++++++++++++------------- 2 files changed, 159 insertions(+), 33 deletions(-)
tools/perf/builtin-test.c +110 -0
@@ -234,6 +234,7 @@ out:return err; } +#include "util/cpumap.h" #include "util/evsel.h" #include <sys/types.h>
@@ -321,6 +322,111 @@ out_thread_map_delete:return err; } +#include <sched.h> + +static int test__open_syscall_event_on_all_cpus (void ) +{ +int err =-1 , fd, cpu; +struct thread_map *threads; +struct cpu_map *cpus; +struct perf_evsel *evsel; +struct perf_event_attr attr; +unsigned int nr_open_calls =111 , i; +cpu_set_t *cpu_set; +size_t cpu_set_size; +int id =trace_event__id ("sys_enter_open" ); + +if (id <0 ) { +pr_debug ("is debugfs mounted on /sys/kernel/debug?\n" ); +return -1 ; + } + + threads =thread_map__new (-1 ,getpid ()); +if (threads ==NULL ) { +pr_debug ("thread_map__new\n" ); +return -1 ; + } + + cpus =cpu_map__new (NULL ); +if (threads ==NULL ) { +pr_debug ("thread_map__new\n" ); +return -1 ; + } + + cpu_set =CPU_ALLOC (cpus->nr); + +if (cpu_set ==NULL ) + goto out_thread_map_delete; + + cpu_set_size =CPU_ALLOC_SIZE (cpus->nr); +CPU_ZERO_S (cpu_set_size, cpu_set); + +memset (&attr,0 ,sizeof (attr)); + attr.type =PERF_TYPE_TRACEPOINT ; + attr.config = id; + evsel =perf_evsel__new (&attr,0 ); +if (evsel ==NULL ) { +pr_debug ("perf_evsel__new\n" ); + goto out_cpu_free; + } + +if (perf_evsel__open (evsel, cpus, threads) <0 ) { +pr_debug ("failed to open counter: %s, " +"tweak /proc/sys/kernel/perf_event_paranoid?\n" , +strerror (errno)); + goto out_evsel_delete; + } + +for (cpu =0 ; cpu < cpus->nr; ++cpu) { +unsigned int ncalls = nr_open_calls + cpu; + +CPU_SET (cpu, cpu_set); +sched_setaffinity (0 , cpu_set_size, cpu_set); +for (i =0 ; i < ncalls; ++i) { + fd =open ("/etc/passwd" ,O_RDONLY ); +close (fd); + } +CPU_CLR (cpu, cpu_set); + } + +/* +* Here we need to explicitely preallocate the counts, as if +* 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 ) { +pr_debug ("perf_evsel__alloc_counts(ncpus=%d)\n" , cpus->nr); + goto out_close_fd; + } + +for (cpu =0 ; cpu < cpus->nr; ++cpu) { +unsigned int expected; + +if (perf_evsel__read_on_cpu (evsel, cpu,0 ) <0 ) { +pr_debug ("perf_evsel__open_read_on_cpu\n" ); + goto out_close_fd; + } + + expected = nr_open_calls + cpu; +if (evsel->counts->cpu[cpu].val != expected) { +pr_debug ("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %Ld\n" , + expected, cpu, evsel->counts->cpu[cpu].val); + goto out_close_fd; + } + } + + err =0 ; +out_close_fd: +perf_evsel__close_fd (evsel,1 , threads->nr); +out_evsel_delete: +perf_evsel__delete (evsel); +out_cpu_free: +CPU_FREE (cpu_set); +out_thread_map_delete: +thread_map__delete (threads); +return err; +} + static struct test { const char *desc; int (*func)(void);
@@ -334,6 +440,10 @@ static struct test { .func = test__open_syscall_event, }, { + .desc = "detect open syscall event on all cpus", + .func = test__open_syscall_event_on_all_cpus, + }, + { .func = NULL, }, };
tools/perf/util/evsel.c +49 -33
108 lines not on this page · raw message