diff options
author | Ingo Molnar <mingo@elte.hu> | 2011-01-07 08:14:15 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-01-07 08:14:15 -0500 |
commit | 1c2a48cf65580a276552151eb8f78d78c55b828e (patch) | |
tree | 68ed0628a276b33cb5aa0ad4899c1afe0a33a69d /tools/perf/builtin-test.c | |
parent | 0aa002fe602939370e9476e5ec32b562000a0425 (diff) | |
parent | cb600d2f83c854ec3d6660063e4466431999489b (diff) |
Merge branch 'linus' into x86/apic-cleanups
Conflicts:
arch/x86/include/asm/io_apic.h
Merge reason: Resolve the conflict, update to a more recent -rc base
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-test.c')
-rw-r--r-- | tools/perf/builtin-test.c | 110 |
1 files changed, 106 insertions, 4 deletions
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 035b9fa063a9..1c984342a579 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -119,10 +119,16 @@ static int test__vmlinux_matches_kallsyms(void) | |||
119 | * end addresses too. | 119 | * end addresses too. |
120 | */ | 120 | */ |
121 | for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) { | 121 | for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) { |
122 | struct symbol *pair; | 122 | struct symbol *pair, *first_pair; |
123 | bool backwards = true; | ||
123 | 124 | ||
124 | sym = rb_entry(nd, struct symbol, rb_node); | 125 | sym = rb_entry(nd, struct symbol, rb_node); |
125 | pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL); | 126 | |
127 | if (sym->start == sym->end) | ||
128 | continue; | ||
129 | |||
130 | first_pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL); | ||
131 | pair = first_pair; | ||
126 | 132 | ||
127 | if (pair && pair->start == sym->start) { | 133 | if (pair && pair->start == sym->start) { |
128 | next_pair: | 134 | next_pair: |
@@ -143,8 +149,10 @@ next_pair: | |||
143 | pr_debug("%#Lx: diff end addr for %s v: %#Lx k: %#Lx\n", | 149 | pr_debug("%#Lx: diff end addr for %s v: %#Lx k: %#Lx\n", |
144 | sym->start, sym->name, sym->end, pair->end); | 150 | sym->start, sym->name, sym->end, pair->end); |
145 | } else { | 151 | } else { |
146 | struct rb_node *nnd = rb_prev(&pair->rb_node); | 152 | struct rb_node *nnd; |
147 | 153 | detour: | |
154 | nnd = backwards ? rb_prev(&pair->rb_node) : | ||
155 | rb_next(&pair->rb_node); | ||
148 | if (nnd) { | 156 | if (nnd) { |
149 | struct symbol *next = rb_entry(nnd, struct symbol, rb_node); | 157 | struct symbol *next = rb_entry(nnd, struct symbol, rb_node); |
150 | 158 | ||
@@ -153,6 +161,13 @@ next_pair: | |||
153 | goto next_pair; | 161 | goto next_pair; |
154 | } | 162 | } |
155 | } | 163 | } |
164 | |||
165 | if (backwards) { | ||
166 | backwards = false; | ||
167 | pair = first_pair; | ||
168 | goto detour; | ||
169 | } | ||
170 | |||
156 | pr_debug("%#Lx: diff name v: %s k: %s\n", | 171 | pr_debug("%#Lx: diff name v: %s k: %s\n", |
157 | sym->start, sym->name, pair->name); | 172 | sym->start, sym->name, pair->name); |
158 | } | 173 | } |
@@ -219,6 +234,89 @@ out: | |||
219 | return err; | 234 | return err; |
220 | } | 235 | } |
221 | 236 | ||
237 | #include "util/evsel.h" | ||
238 | #include <sys/types.h> | ||
239 | |||
240 | static int trace_event__id(const char *event_name) | ||
241 | { | ||
242 | char *filename; | ||
243 | int err = -1, fd; | ||
244 | |||
245 | if (asprintf(&filename, | ||
246 | "/sys/kernel/debug/tracing/events/syscalls/%s/id", | ||
247 | event_name) < 0) | ||
248 | return -1; | ||
249 | |||
250 | fd = open(filename, O_RDONLY); | ||
251 | if (fd >= 0) { | ||
252 | char id[16]; | ||
253 | if (read(fd, id, sizeof(id)) > 0) | ||
254 | err = atoi(id); | ||
255 | close(fd); | ||
256 | } | ||
257 | |||
258 | free(filename); | ||
259 | return err; | ||
260 | } | ||
261 | |||
262 | static int test__open_syscall_event(void) | ||
263 | { | ||
264 | int err = -1, fd; | ||
265 | struct thread_map *threads; | ||
266 | struct perf_evsel *evsel; | ||
267 | unsigned int nr_open_calls = 111, i; | ||
268 | int id = trace_event__id("sys_enter_open"); | ||
269 | |||
270 | if (id < 0) { | ||
271 | pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); | ||
272 | return -1; | ||
273 | } | ||
274 | |||
275 | threads = thread_map__new(-1, getpid()); | ||
276 | if (threads == NULL) { | ||
277 | pr_debug("thread_map__new\n"); | ||
278 | return -1; | ||
279 | } | ||
280 | |||
281 | evsel = perf_evsel__new(PERF_TYPE_TRACEPOINT, id, 0); | ||
282 | if (evsel == NULL) { | ||
283 | pr_debug("perf_evsel__new\n"); | ||
284 | goto out_thread_map_delete; | ||
285 | } | ||
286 | |||
287 | if (perf_evsel__open_per_thread(evsel, threads) < 0) { | ||
288 | pr_debug("failed to open counter: %s, " | ||
289 | "tweak /proc/sys/kernel/perf_event_paranoid?\n", | ||
290 | strerror(errno)); | ||
291 | goto out_evsel_delete; | ||
292 | } | ||
293 | |||
294 | for (i = 0; i < nr_open_calls; ++i) { | ||
295 | fd = open("/etc/passwd", O_RDONLY); | ||
296 | close(fd); | ||
297 | } | ||
298 | |||
299 | if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) { | ||
300 | pr_debug("perf_evsel__open_read_on_cpu\n"); | ||
301 | goto out_close_fd; | ||
302 | } | ||
303 | |||
304 | if (evsel->counts->cpu[0].val != nr_open_calls) { | ||
305 | pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %Ld\n", | ||
306 | nr_open_calls, evsel->counts->cpu[0].val); | ||
307 | goto out_close_fd; | ||
308 | } | ||
309 | |||
310 | err = 0; | ||
311 | out_close_fd: | ||
312 | perf_evsel__close_fd(evsel, 1, threads->nr); | ||
313 | out_evsel_delete: | ||
314 | perf_evsel__delete(evsel); | ||
315 | out_thread_map_delete: | ||
316 | thread_map__delete(threads); | ||
317 | return err; | ||
318 | } | ||
319 | |||
222 | static struct test { | 320 | static struct test { |
223 | const char *desc; | 321 | const char *desc; |
224 | int (*func)(void); | 322 | int (*func)(void); |
@@ -228,6 +326,10 @@ static struct test { | |||
228 | .func = test__vmlinux_matches_kallsyms, | 326 | .func = test__vmlinux_matches_kallsyms, |
229 | }, | 327 | }, |
230 | { | 328 | { |
329 | .desc = "detect open syscall event", | ||
330 | .func = test__open_syscall_event, | ||
331 | }, | ||
332 | { | ||
231 | .func = NULL, | 333 | .func = NULL, |
232 | }, | 334 | }, |
233 | }; | 335 | }; |