aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/Makefile1
-rw-r--r--tools/perf/tests/builtin-test.c157
-rw-r--r--tools/perf/tests/mmap-basic.c162
-rw-r--r--tools/perf/tests/tests.h1
4 files changed, 164 insertions, 157 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index d413e89c38e1..337489e827ca 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -434,6 +434,7 @@ LIB_OBJS += $(OUTPUT)tests/attr.o
434LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o 434LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o
435LIB_OBJS += $(OUTPUT)tests/open-syscall.o 435LIB_OBJS += $(OUTPUT)tests/open-syscall.o
436LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o 436LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o
437LIB_OBJS += $(OUTPUT)tests/mmap-basic.o
437LIB_OBJS += $(OUTPUT)tests/util.o 438LIB_OBJS += $(OUTPUT)tests/util.o
438 439
439BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o 440BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 98e883bc330b..609f59295326 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -30,163 +30,6 @@
30#include <sched.h> 30#include <sched.h>
31 31
32 32
33/*
34 * This test will generate random numbers of calls to some getpid syscalls,
35 * then establish an mmap for a group of events that are created to monitor
36 * the syscalls.
37 *
38 * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated
39 * sample.id field to map back to its respective perf_evsel instance.
40 *
41 * Then it checks if the number of syscalls reported as perf events by
42 * the kernel corresponds to the number of syscalls made.
43 */
44static int test__basic_mmap(void)
45{
46 int err = -1;
47 union perf_event *event;
48 struct thread_map *threads;
49 struct cpu_map *cpus;
50 struct perf_evlist *evlist;
51 struct perf_event_attr attr = {
52 .type = PERF_TYPE_TRACEPOINT,
53 .read_format = PERF_FORMAT_ID,
54 .sample_type = PERF_SAMPLE_ID,
55 .watermark = 0,
56 };
57 cpu_set_t cpu_set;
58 const char *syscall_names[] = { "getsid", "getppid", "getpgrp",
59 "getpgid", };
60 pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp,
61 (void*)getpgid };
62#define nsyscalls ARRAY_SIZE(syscall_names)
63 int ids[nsyscalls];
64 unsigned int nr_events[nsyscalls],
65 expected_nr_events[nsyscalls], i, j;
66 struct perf_evsel *evsels[nsyscalls], *evsel;
67
68 for (i = 0; i < nsyscalls; ++i) {
69 char name[64];
70
71 snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]);
72 ids[i] = trace_event__id(name);
73 if (ids[i] < 0) {
74 pr_debug("Is debugfs mounted on /sys/kernel/debug?\n");
75 return -1;
76 }
77 nr_events[i] = 0;
78 expected_nr_events[i] = random() % 257;
79 }
80
81 threads = thread_map__new(-1, getpid(), UINT_MAX);
82 if (threads == NULL) {
83 pr_debug("thread_map__new\n");
84 return -1;
85 }
86
87 cpus = cpu_map__new(NULL);
88 if (cpus == NULL) {
89 pr_debug("cpu_map__new\n");
90 goto out_free_threads;
91 }
92
93 CPU_ZERO(&cpu_set);
94 CPU_SET(cpus->map[0], &cpu_set);
95 sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
96 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
97 pr_debug("sched_setaffinity() failed on CPU %d: %s ",
98 cpus->map[0], strerror(errno));
99 goto out_free_cpus;
100 }
101
102 evlist = perf_evlist__new(cpus, threads);
103 if (evlist == NULL) {
104 pr_debug("perf_evlist__new\n");
105 goto out_free_cpus;
106 }
107
108 /* anonymous union fields, can't be initialized above */
109 attr.wakeup_events = 1;
110 attr.sample_period = 1;
111
112 for (i = 0; i < nsyscalls; ++i) {
113 attr.config = ids[i];
114 evsels[i] = perf_evsel__new(&attr, i);
115 if (evsels[i] == NULL) {
116 pr_debug("perf_evsel__new\n");
117 goto out_free_evlist;
118 }
119
120 perf_evlist__add(evlist, evsels[i]);
121
122 if (perf_evsel__open(evsels[i], cpus, threads) < 0) {
123 pr_debug("failed to open counter: %s, "
124 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
125 strerror(errno));
126 goto out_close_fd;
127 }
128 }
129
130 if (perf_evlist__mmap(evlist, 128, true) < 0) {
131 pr_debug("failed to mmap events: %d (%s)\n", errno,
132 strerror(errno));
133 goto out_close_fd;
134 }
135
136 for (i = 0; i < nsyscalls; ++i)
137 for (j = 0; j < expected_nr_events[i]; ++j) {
138 int foo = syscalls[i]();
139 ++foo;
140 }
141
142 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
143 struct perf_sample sample;
144
145 if (event->header.type != PERF_RECORD_SAMPLE) {
146 pr_debug("unexpected %s event\n",
147 perf_event__name(event->header.type));
148 goto out_munmap;
149 }
150
151 err = perf_evlist__parse_sample(evlist, event, &sample);
152 if (err) {
153 pr_err("Can't parse sample, err = %d\n", err);
154 goto out_munmap;
155 }
156
157 evsel = perf_evlist__id2evsel(evlist, sample.id);
158 if (evsel == NULL) {
159 pr_debug("event with id %" PRIu64
160 " doesn't map to an evsel\n", sample.id);
161 goto out_munmap;
162 }
163 nr_events[evsel->idx]++;
164 }
165
166 list_for_each_entry(evsel, &evlist->entries, node) {
167 if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
168 pr_debug("expected %d %s events, got %d\n",
169 expected_nr_events[evsel->idx],
170 perf_evsel__name(evsel), nr_events[evsel->idx]);
171 goto out_munmap;
172 }
173 }
174
175 err = 0;
176out_munmap:
177 perf_evlist__munmap(evlist);
178out_close_fd:
179 for (i = 0; i < nsyscalls; ++i)
180 perf_evsel__close_fd(evsels[i], 1, threads->nr);
181out_free_evlist:
182 perf_evlist__delete(evlist);
183out_free_cpus:
184 cpu_map__delete(cpus);
185out_free_threads:
186 thread_map__delete(threads);
187 return err;
188#undef nsyscalls
189}
190 33
191static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp) 34static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp)
192{ 35{
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
new file mode 100644
index 000000000000..e1746811e14b
--- /dev/null
+++ b/tools/perf/tests/mmap-basic.c
@@ -0,0 +1,162 @@
1#include "evlist.h"
2#include "evsel.h"
3#include "thread_map.h"
4#include "cpumap.h"
5#include "tests.h"
6
7/*
8 * This test will generate random numbers of calls to some getpid syscalls,
9 * then establish an mmap for a group of events that are created to monitor
10 * the syscalls.
11 *
12 * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated
13 * sample.id field to map back to its respective perf_evsel instance.
14 *
15 * Then it checks if the number of syscalls reported as perf events by
16 * the kernel corresponds to the number of syscalls made.
17 */
18int test__basic_mmap(void)
19{
20 int err = -1;
21 union perf_event *event;
22 struct thread_map *threads;
23 struct cpu_map *cpus;
24 struct perf_evlist *evlist;
25 struct perf_event_attr attr = {
26 .type = PERF_TYPE_TRACEPOINT,
27 .read_format = PERF_FORMAT_ID,
28 .sample_type = PERF_SAMPLE_ID,
29 .watermark = 0,
30 };
31 cpu_set_t cpu_set;
32 const char *syscall_names[] = { "getsid", "getppid", "getpgrp",
33 "getpgid", };
34 pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp,
35 (void*)getpgid };
36#define nsyscalls ARRAY_SIZE(syscall_names)
37 int ids[nsyscalls];
38 unsigned int nr_events[nsyscalls],
39 expected_nr_events[nsyscalls], i, j;
40 struct perf_evsel *evsels[nsyscalls], *evsel;
41
42 for (i = 0; i < nsyscalls; ++i) {
43 char name[64];
44
45 snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]);
46 ids[i] = trace_event__id(name);
47 if (ids[i] < 0) {
48 pr_debug("Is debugfs mounted on /sys/kernel/debug?\n");
49 return -1;
50 }
51 nr_events[i] = 0;
52 expected_nr_events[i] = random() % 257;
53 }
54
55 threads = thread_map__new(-1, getpid(), UINT_MAX);
56 if (threads == NULL) {
57 pr_debug("thread_map__new\n");
58 return -1;
59 }
60
61 cpus = cpu_map__new(NULL);
62 if (cpus == NULL) {
63 pr_debug("cpu_map__new\n");
64 goto out_free_threads;
65 }
66
67 CPU_ZERO(&cpu_set);
68 CPU_SET(cpus->map[0], &cpu_set);
69 sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
70 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
71 pr_debug("sched_setaffinity() failed on CPU %d: %s ",
72 cpus->map[0], strerror(errno));
73 goto out_free_cpus;
74 }
75
76 evlist = perf_evlist__new(cpus, threads);
77 if (evlist == NULL) {
78 pr_debug("perf_evlist__new\n");
79 goto out_free_cpus;
80 }
81
82 /* anonymous union fields, can't be initialized above */
83 attr.wakeup_events = 1;
84 attr.sample_period = 1;
85
86 for (i = 0; i < nsyscalls; ++i) {
87 attr.config = ids[i];
88 evsels[i] = perf_evsel__new(&attr, i);
89 if (evsels[i] == NULL) {
90 pr_debug("perf_evsel__new\n");
91 goto out_free_evlist;
92 }
93
94 perf_evlist__add(evlist, evsels[i]);
95
96 if (perf_evsel__open(evsels[i], cpus, threads) < 0) {
97 pr_debug("failed to open counter: %s, "
98 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
99 strerror(errno));
100 goto out_close_fd;
101 }
102 }
103
104 if (perf_evlist__mmap(evlist, 128, true) < 0) {
105 pr_debug("failed to mmap events: %d (%s)\n", errno,
106 strerror(errno));
107 goto out_close_fd;
108 }
109
110 for (i = 0; i < nsyscalls; ++i)
111 for (j = 0; j < expected_nr_events[i]; ++j) {
112 int foo = syscalls[i]();
113 ++foo;
114 }
115
116 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
117 struct perf_sample sample;
118
119 if (event->header.type != PERF_RECORD_SAMPLE) {
120 pr_debug("unexpected %s event\n",
121 perf_event__name(event->header.type));
122 goto out_munmap;
123 }
124
125 err = perf_evlist__parse_sample(evlist, event, &sample);
126 if (err) {
127 pr_err("Can't parse sample, err = %d\n", err);
128 goto out_munmap;
129 }
130
131 evsel = perf_evlist__id2evsel(evlist, sample.id);
132 if (evsel == NULL) {
133 pr_debug("event with id %" PRIu64
134 " doesn't map to an evsel\n", sample.id);
135 goto out_munmap;
136 }
137 nr_events[evsel->idx]++;
138 }
139
140 list_for_each_entry(evsel, &evlist->entries, node) {
141 if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
142 pr_debug("expected %d %s events, got %d\n",
143 expected_nr_events[evsel->idx],
144 perf_evsel__name(evsel), nr_events[evsel->idx]);
145 goto out_munmap;
146 }
147 }
148
149 err = 0;
150out_munmap:
151 perf_evlist__munmap(evlist);
152out_close_fd:
153 for (i = 0; i < nsyscalls; ++i)
154 perf_evsel__close_fd(evsels[i], 1, threads->nr);
155out_free_evlist:
156 perf_evlist__delete(evlist);
157out_free_cpus:
158 cpu_map__delete(cpus);
159out_free_threads:
160 thread_map__delete(threads);
161 return err;
162}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index c2887f226db3..1a925ddeae7a 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -5,6 +5,7 @@
5int test__vmlinux_matches_kallsyms(void); 5int test__vmlinux_matches_kallsyms(void);
6int test__open_syscall_event(void); 6int test__open_syscall_event(void);
7int test__open_syscall_event_on_all_cpus(void); 7int test__open_syscall_event_on_all_cpus(void);
8int test__basic_mmap(void);
8 9
9/* Util */ 10/* Util */
10int trace_event__id(const char *evname); 11int trace_event__id(const char *evname);