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 | }; |
