diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 14:02:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 14:02:13 -0500 |
commit | 42776163e13a56ea3096edff7a5df95408e80eb4 (patch) | |
tree | 92f17bb5dadc7261b2d9238244cd8d4cb6c1bfd7 /tools | |
parent | edb2877f4a62647e36e20839a786f94d688a06ed (diff) | |
parent | 3d03e2ea74103a50c23d6ab1906cf73399c0dafb (diff) |
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (28 commits)
perf session: Fix infinite loop in __perf_session__process_events
perf evsel: Support perf_evsel__open(cpus > 1 && threads > 1)
perf sched: Use PTHREAD_STACK_MIN to avoid pthread_attr_setstacksize() fail
perf tools: Emit clearer message for sys_perf_event_open ENOENT return
perf stat: better error message for unsupported events
perf sched: Fix allocation result check
perf, x86: P4 PMU - Fix unflagged overflows handling
dynamic debug: Fix build issue with older gcc
tracing: Fix TRACE_EVENT power tracepoint creation
tracing: Fix preempt count leak
tracepoint: Add __rcu annotation
tracing: remove duplicate null-pointer check in skb tracepoint
tracing/trivial: Add missing comma in TRACE_EVENT comment
tracing: Include module.h in define_trace.h
x86: Save rbp in pt_regs on irq entry
x86, dumpstack: Fix unused variable warning
x86, NMI: Clean-up default_do_nmi()
x86, NMI: Allow NMI reason io port (0x61) to be processed on any CPU
x86, NMI: Remove DIE_NMI_IPI
x86, NMI: Add priorities to handlers
...
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Makefile | 2 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 3 | ||||
-rw-r--r-- | tools/perf/builtin-sched.c | 5 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 5 | ||||
-rw-r--r-- | tools/perf/builtin-test.c | 116 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 2 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 87 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 2 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 74 | ||||
-rw-r--r-- | tools/perf/util/session.c | 2 |
10 files changed, 220 insertions, 78 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 1b9b13ee2a72..2b5387d53ba5 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -227,7 +227,7 @@ ifndef PERF_DEBUG | |||
227 | CFLAGS_OPTIMIZE = -O6 | 227 | CFLAGS_OPTIMIZE = -O6 |
228 | endif | 228 | endif |
229 | 229 | ||
230 | CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) | 230 | CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) |
231 | EXTLIBS = -lpthread -lrt -lelf -lm | 231 | EXTLIBS = -lpthread -lrt -lelf -lm |
232 | ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 | 232 | ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 |
233 | ALL_LDFLAGS = $(LDFLAGS) | 233 | ALL_LDFLAGS = $(LDFLAGS) |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 7bc049035484..7069bd3e90b3 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -331,6 +331,9 @@ try_again: | |||
331 | else if (err == ENODEV && cpu_list) { | 331 | else if (err == ENODEV && cpu_list) { |
332 | die("No such device - did you specify" | 332 | die("No such device - did you specify" |
333 | " an out-of-range profile CPU?\n"); | 333 | " an out-of-range profile CPU?\n"); |
334 | } else if (err == ENOENT) { | ||
335 | die("%s event is not supported. ", | ||
336 | event_name(evsel)); | ||
334 | } else if (err == EINVAL && sample_id_all_avail) { | 337 | } else if (err == EINVAL && sample_id_all_avail) { |
335 | /* | 338 | /* |
336 | * Old kernel, no attr->sample_id_type_all field | 339 | * Old kernel, no attr->sample_id_type_all field |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 7a4ebeb8b016..abd4b8497bc4 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -489,7 +489,8 @@ static void create_tasks(void) | |||
489 | 489 | ||
490 | err = pthread_attr_init(&attr); | 490 | err = pthread_attr_init(&attr); |
491 | BUG_ON(err); | 491 | BUG_ON(err); |
492 | err = pthread_attr_setstacksize(&attr, (size_t)(16*1024)); | 492 | err = pthread_attr_setstacksize(&attr, |
493 | (size_t) max(16 * 1024, PTHREAD_STACK_MIN)); | ||
493 | BUG_ON(err); | 494 | BUG_ON(err); |
494 | err = pthread_mutex_lock(&start_work_mutex); | 495 | err = pthread_mutex_lock(&start_work_mutex); |
495 | BUG_ON(err); | 496 | BUG_ON(err); |
@@ -1861,7 +1862,7 @@ static int __cmd_record(int argc, const char **argv) | |||
1861 | rec_argc = ARRAY_SIZE(record_args) + argc - 1; | 1862 | rec_argc = ARRAY_SIZE(record_args) + argc - 1; |
1862 | rec_argv = calloc(rec_argc + 1, sizeof(char *)); | 1863 | rec_argv = calloc(rec_argc + 1, sizeof(char *)); |
1863 | 1864 | ||
1864 | if (rec_argv) | 1865 | if (rec_argv == NULL) |
1865 | return -ENOMEM; | 1866 | return -ENOMEM; |
1866 | 1867 | ||
1867 | for (i = 0; i < ARRAY_SIZE(record_args); i++) | 1868 | for (i = 0; i < ARRAY_SIZE(record_args); i++) |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 02b2d8013a61..c385a63ebfd1 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -316,6 +316,8 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
316 | "\t Consider tweaking" | 316 | "\t Consider tweaking" |
317 | " /proc/sys/kernel/perf_event_paranoid or running as root.", | 317 | " /proc/sys/kernel/perf_event_paranoid or running as root.", |
318 | system_wide ? "system-wide " : ""); | 318 | system_wide ? "system-wide " : ""); |
319 | } else if (errno == ENOENT) { | ||
320 | error("%s event is not supported. ", event_name(counter)); | ||
319 | } else { | 321 | } else { |
320 | error("open_counter returned with %d (%s). " | 322 | error("open_counter returned with %d (%s). " |
321 | "/bin/dmesg may provide additional information.\n", | 323 | "/bin/dmesg may provide additional information.\n", |
@@ -683,8 +685,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
683 | nr_counters = ARRAY_SIZE(default_attrs); | 685 | nr_counters = ARRAY_SIZE(default_attrs); |
684 | 686 | ||
685 | for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) { | 687 | for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) { |
686 | pos = perf_evsel__new(default_attrs[c].type, | 688 | pos = perf_evsel__new(&default_attrs[c], |
687 | default_attrs[c].config, | ||
688 | nr_counters); | 689 | nr_counters); |
689 | if (pos == NULL) | 690 | if (pos == NULL) |
690 | goto out; | 691 | goto out; |
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 1c984342a579..ed5696198d3d 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -234,6 +234,7 @@ out: | |||
234 | return err; | 234 | return err; |
235 | } | 235 | } |
236 | 236 | ||
237 | #include "util/cpumap.h" | ||
237 | #include "util/evsel.h" | 238 | #include "util/evsel.h" |
238 | #include <sys/types.h> | 239 | #include <sys/types.h> |
239 | 240 | ||
@@ -264,6 +265,7 @@ static int test__open_syscall_event(void) | |||
264 | int err = -1, fd; | 265 | int err = -1, fd; |
265 | struct thread_map *threads; | 266 | struct thread_map *threads; |
266 | struct perf_evsel *evsel; | 267 | struct perf_evsel *evsel; |
268 | struct perf_event_attr attr; | ||
267 | unsigned int nr_open_calls = 111, i; | 269 | unsigned int nr_open_calls = 111, i; |
268 | int id = trace_event__id("sys_enter_open"); | 270 | int id = trace_event__id("sys_enter_open"); |
269 | 271 | ||
@@ -278,7 +280,10 @@ static int test__open_syscall_event(void) | |||
278 | return -1; | 280 | return -1; |
279 | } | 281 | } |
280 | 282 | ||
281 | evsel = perf_evsel__new(PERF_TYPE_TRACEPOINT, id, 0); | 283 | memset(&attr, 0, sizeof(attr)); |
284 | attr.type = PERF_TYPE_TRACEPOINT; | ||
285 | attr.config = id; | ||
286 | evsel = perf_evsel__new(&attr, 0); | ||
282 | if (evsel == NULL) { | 287 | if (evsel == NULL) { |
283 | pr_debug("perf_evsel__new\n"); | 288 | pr_debug("perf_evsel__new\n"); |
284 | goto out_thread_map_delete; | 289 | goto out_thread_map_delete; |
@@ -317,6 +322,111 @@ out_thread_map_delete: | |||
317 | return err; | 322 | return err; |
318 | } | 323 | } |
319 | 324 | ||
325 | #include <sched.h> | ||
326 | |||
327 | static int test__open_syscall_event_on_all_cpus(void) | ||
328 | { | ||
329 | int err = -1, fd, cpu; | ||
330 | struct thread_map *threads; | ||
331 | struct cpu_map *cpus; | ||
332 | struct perf_evsel *evsel; | ||
333 | struct perf_event_attr attr; | ||
334 | unsigned int nr_open_calls = 111, i; | ||
335 | cpu_set_t *cpu_set; | ||
336 | size_t cpu_set_size; | ||
337 | int id = trace_event__id("sys_enter_open"); | ||
338 | |||
339 | if (id < 0) { | ||
340 | pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); | ||
341 | return -1; | ||
342 | } | ||
343 | |||
344 | threads = thread_map__new(-1, getpid()); | ||
345 | if (threads == NULL) { | ||
346 | pr_debug("thread_map__new\n"); | ||
347 | return -1; | ||
348 | } | ||
349 | |||
350 | cpus = cpu_map__new(NULL); | ||
351 | if (threads == NULL) { | ||
352 | pr_debug("thread_map__new\n"); | ||
353 | return -1; | ||
354 | } | ||
355 | |||
356 | cpu_set = CPU_ALLOC(cpus->nr); | ||
357 | |||
358 | if (cpu_set == NULL) | ||
359 | goto out_thread_map_delete; | ||
360 | |||
361 | cpu_set_size = CPU_ALLOC_SIZE(cpus->nr); | ||
362 | CPU_ZERO_S(cpu_set_size, cpu_set); | ||
363 | |||
364 | memset(&attr, 0, sizeof(attr)); | ||
365 | attr.type = PERF_TYPE_TRACEPOINT; | ||
366 | attr.config = id; | ||
367 | evsel = perf_evsel__new(&attr, 0); | ||
368 | if (evsel == NULL) { | ||
369 | pr_debug("perf_evsel__new\n"); | ||
370 | goto out_cpu_free; | ||
371 | } | ||
372 | |||
373 | if (perf_evsel__open(evsel, cpus, threads) < 0) { | ||
374 | pr_debug("failed to open counter: %s, " | ||
375 | "tweak /proc/sys/kernel/perf_event_paranoid?\n", | ||
376 | strerror(errno)); | ||
377 | goto out_evsel_delete; | ||
378 | } | ||
379 | |||
380 | for (cpu = 0; cpu < cpus->nr; ++cpu) { | ||
381 | unsigned int ncalls = nr_open_calls + cpu; | ||
382 | |||
383 | CPU_SET(cpu, cpu_set); | ||
384 | sched_setaffinity(0, cpu_set_size, cpu_set); | ||
385 | for (i = 0; i < ncalls; ++i) { | ||
386 | fd = open("/etc/passwd", O_RDONLY); | ||
387 | close(fd); | ||
388 | } | ||
389 | CPU_CLR(cpu, cpu_set); | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | * Here we need to explicitely preallocate the counts, as if | ||
394 | * we use the auto allocation it will allocate just for 1 cpu, | ||
395 | * as we start by cpu 0. | ||
396 | */ | ||
397 | if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) { | ||
398 | pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr); | ||
399 | goto out_close_fd; | ||
400 | } | ||
401 | |||
402 | for (cpu = 0; cpu < cpus->nr; ++cpu) { | ||
403 | unsigned int expected; | ||
404 | |||
405 | if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) { | ||
406 | pr_debug("perf_evsel__open_read_on_cpu\n"); | ||
407 | goto out_close_fd; | ||
408 | } | ||
409 | |||
410 | expected = nr_open_calls + cpu; | ||
411 | if (evsel->counts->cpu[cpu].val != expected) { | ||
412 | pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %Ld\n", | ||
413 | expected, cpu, evsel->counts->cpu[cpu].val); | ||
414 | goto out_close_fd; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | err = 0; | ||
419 | out_close_fd: | ||
420 | perf_evsel__close_fd(evsel, 1, threads->nr); | ||
421 | out_evsel_delete: | ||
422 | perf_evsel__delete(evsel); | ||
423 | out_cpu_free: | ||
424 | CPU_FREE(cpu_set); | ||
425 | out_thread_map_delete: | ||
426 | thread_map__delete(threads); | ||
427 | return err; | ||
428 | } | ||
429 | |||
320 | static struct test { | 430 | static struct test { |
321 | const char *desc; | 431 | const char *desc; |
322 | int (*func)(void); | 432 | int (*func)(void); |
@@ -330,6 +440,10 @@ static struct test { | |||
330 | .func = test__open_syscall_event, | 440 | .func = test__open_syscall_event, |
331 | }, | 441 | }, |
332 | { | 442 | { |
443 | .desc = "detect open syscall event on all cpus", | ||
444 | .func = test__open_syscall_event_on_all_cpus, | ||
445 | }, | ||
446 | { | ||
333 | .func = NULL, | 447 | .func = NULL, |
334 | }, | 448 | }, |
335 | }; | 449 | }; |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1e67ab9c7ebc..6ce4042421bd 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -1247,6 +1247,8 @@ try_again: | |||
1247 | die("Permission error - are you root?\n" | 1247 | die("Permission error - are you root?\n" |
1248 | "\t Consider tweaking" | 1248 | "\t Consider tweaking" |
1249 | " /proc/sys/kernel/perf_event_paranoid.\n"); | 1249 | " /proc/sys/kernel/perf_event_paranoid.\n"); |
1250 | if (err == ENOENT) | ||
1251 | die("%s event is not supported. ", event_name(evsel)); | ||
1250 | /* | 1252 | /* |
1251 | * If it's cycles then fall back to hrtimer | 1253 | * If it's cycles then fall back to hrtimer |
1252 | * based cpu-clock-tick sw counter, which | 1254 | * based cpu-clock-tick sw counter, which |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index c95267e63c5b..f5cfed60af98 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -6,14 +6,13 @@ | |||
6 | 6 | ||
7 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 7 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
8 | 8 | ||
9 | struct perf_evsel *perf_evsel__new(u32 type, u64 config, int idx) | 9 | struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) |
10 | { | 10 | { |
11 | struct perf_evsel *evsel = zalloc(sizeof(*evsel)); | 11 | struct perf_evsel *evsel = zalloc(sizeof(*evsel)); |
12 | 12 | ||
13 | if (evsel != NULL) { | 13 | if (evsel != NULL) { |
14 | evsel->idx = idx; | 14 | evsel->idx = idx; |
15 | evsel->attr.type = type; | 15 | evsel->attr = *attr; |
16 | evsel->attr.config = config; | ||
17 | INIT_LIST_HEAD(&evsel->node); | 16 | INIT_LIST_HEAD(&evsel->node); |
18 | } | 17 | } |
19 | 18 | ||
@@ -128,59 +127,75 @@ int __perf_evsel__read(struct perf_evsel *evsel, | |||
128 | return 0; | 127 | return 0; |
129 | } | 128 | } |
130 | 129 | ||
131 | int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus) | 130 | static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, |
131 | struct thread_map *threads) | ||
132 | { | 132 | { |
133 | int cpu; | 133 | int cpu, thread; |
134 | 134 | ||
135 | if (evsel->fd == NULL && perf_evsel__alloc_fd(evsel, cpus->nr, 1) < 0) | 135 | if (evsel->fd == NULL && |
136 | perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0) | ||
136 | return -1; | 137 | return -1; |
137 | 138 | ||
138 | for (cpu = 0; cpu < cpus->nr; cpu++) { | 139 | for (cpu = 0; cpu < cpus->nr; cpu++) { |
139 | FD(evsel, cpu, 0) = sys_perf_event_open(&evsel->attr, -1, | 140 | for (thread = 0; thread < threads->nr; thread++) { |
140 | cpus->map[cpu], -1, 0); | 141 | FD(evsel, cpu, thread) = sys_perf_event_open(&evsel->attr, |
141 | if (FD(evsel, cpu, 0) < 0) | 142 | threads->map[thread], |
142 | goto out_close; | 143 | cpus->map[cpu], -1, 0); |
144 | if (FD(evsel, cpu, thread) < 0) | ||
145 | goto out_close; | ||
146 | } | ||
143 | } | 147 | } |
144 | 148 | ||
145 | return 0; | 149 | return 0; |
146 | 150 | ||
147 | out_close: | 151 | out_close: |
148 | while (--cpu >= 0) { | 152 | do { |
149 | close(FD(evsel, cpu, 0)); | 153 | while (--thread >= 0) { |
150 | FD(evsel, cpu, 0) = -1; | 154 | close(FD(evsel, cpu, thread)); |
151 | } | 155 | FD(evsel, cpu, thread) = -1; |
156 | } | ||
157 | thread = threads->nr; | ||
158 | } while (--cpu >= 0); | ||
152 | return -1; | 159 | return -1; |
153 | } | 160 | } |
154 | 161 | ||
155 | int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *threads) | 162 | static struct { |
163 | struct cpu_map map; | ||
164 | int cpus[1]; | ||
165 | } empty_cpu_map = { | ||
166 | .map.nr = 1, | ||
167 | .cpus = { -1, }, | ||
168 | }; | ||
169 | |||
170 | static struct { | ||
171 | struct thread_map map; | ||
172 | int threads[1]; | ||
173 | } empty_thread_map = { | ||
174 | .map.nr = 1, | ||
175 | .threads = { -1, }, | ||
176 | }; | ||
177 | |||
178 | int perf_evsel__open(struct perf_evsel *evsel, | ||
179 | struct cpu_map *cpus, struct thread_map *threads) | ||
156 | { | 180 | { |
157 | int thread; | ||
158 | |||
159 | if (evsel->fd == NULL && perf_evsel__alloc_fd(evsel, 1, threads->nr)) | ||
160 | return -1; | ||
161 | 181 | ||
162 | for (thread = 0; thread < threads->nr; thread++) { | 182 | if (cpus == NULL) { |
163 | FD(evsel, 0, thread) = sys_perf_event_open(&evsel->attr, | 183 | /* Work around old compiler warnings about strict aliasing */ |
164 | threads->map[thread], -1, -1, 0); | 184 | cpus = &empty_cpu_map.map; |
165 | if (FD(evsel, 0, thread) < 0) | ||
166 | goto out_close; | ||
167 | } | 185 | } |
168 | 186 | ||
169 | return 0; | 187 | if (threads == NULL) |
188 | threads = &empty_thread_map.map; | ||
170 | 189 | ||
171 | out_close: | 190 | return __perf_evsel__open(evsel, cpus, threads); |
172 | while (--thread >= 0) { | ||
173 | close(FD(evsel, 0, thread)); | ||
174 | FD(evsel, 0, thread) = -1; | ||
175 | } | ||
176 | return -1; | ||
177 | } | 191 | } |
178 | 192 | ||
179 | int perf_evsel__open(struct perf_evsel *evsel, | 193 | int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus) |
180 | struct cpu_map *cpus, struct thread_map *threads) | ||
181 | { | 194 | { |
182 | if (threads == NULL) | 195 | return __perf_evsel__open(evsel, cpus, &empty_thread_map.map); |
183 | return perf_evsel__open_per_cpu(evsel, cpus); | 196 | } |
184 | 197 | ||
185 | return perf_evsel__open_per_thread(evsel, threads); | 198 | int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *threads) |
199 | { | ||
200 | return __perf_evsel__open(evsel, &empty_cpu_map.map, threads); | ||
186 | } | 201 | } |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a0ccd69c3fc2..b2d755fe88a5 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -37,7 +37,7 @@ struct perf_evsel { | |||
37 | struct cpu_map; | 37 | struct cpu_map; |
38 | struct thread_map; | 38 | struct thread_map; |
39 | 39 | ||
40 | struct perf_evsel *perf_evsel__new(u32 type, u64 config, int idx); | 40 | struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx); |
41 | void perf_evsel__delete(struct perf_evsel *evsel); | 41 | void perf_evsel__delete(struct perf_evsel *evsel); |
42 | 42 | ||
43 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); | 43 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 649083f27e08..5cb6f4bde905 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -490,6 +490,31 @@ parse_multiple_tracepoint_event(char *sys_name, const char *evt_exp, | |||
490 | return EVT_HANDLED_ALL; | 490 | return EVT_HANDLED_ALL; |
491 | } | 491 | } |
492 | 492 | ||
493 | static int store_event_type(const char *orgname) | ||
494 | { | ||
495 | char filename[PATH_MAX], *c; | ||
496 | FILE *file; | ||
497 | int id, n; | ||
498 | |||
499 | sprintf(filename, "%s/", debugfs_path); | ||
500 | strncat(filename, orgname, strlen(orgname)); | ||
501 | strcat(filename, "/id"); | ||
502 | |||
503 | c = strchr(filename, ':'); | ||
504 | if (c) | ||
505 | *c = '/'; | ||
506 | |||
507 | file = fopen(filename, "r"); | ||
508 | if (!file) | ||
509 | return 0; | ||
510 | n = fscanf(file, "%i", &id); | ||
511 | fclose(file); | ||
512 | if (n < 1) { | ||
513 | pr_err("cannot store event ID\n"); | ||
514 | return -EINVAL; | ||
515 | } | ||
516 | return perf_header__push_event(id, orgname); | ||
517 | } | ||
493 | 518 | ||
494 | static enum event_result parse_tracepoint_event(const char **strp, | 519 | static enum event_result parse_tracepoint_event(const char **strp, |
495 | struct perf_event_attr *attr) | 520 | struct perf_event_attr *attr) |
@@ -533,9 +558,13 @@ static enum event_result parse_tracepoint_event(const char **strp, | |||
533 | *strp += strlen(sys_name) + evt_length; | 558 | *strp += strlen(sys_name) + evt_length; |
534 | return parse_multiple_tracepoint_event(sys_name, evt_name, | 559 | return parse_multiple_tracepoint_event(sys_name, evt_name, |
535 | flags); | 560 | flags); |
536 | } else | 561 | } else { |
562 | if (store_event_type(evt_name) < 0) | ||
563 | return EVT_FAILED; | ||
564 | |||
537 | return parse_single_tracepoint_event(sys_name, evt_name, | 565 | return parse_single_tracepoint_event(sys_name, evt_name, |
538 | evt_length, attr, strp); | 566 | evt_length, attr, strp); |
567 | } | ||
539 | } | 568 | } |
540 | 569 | ||
541 | static enum event_result | 570 | static enum event_result |
@@ -778,41 +807,11 @@ modifier: | |||
778 | return ret; | 807 | return ret; |
779 | } | 808 | } |
780 | 809 | ||
781 | static int store_event_type(const char *orgname) | ||
782 | { | ||
783 | char filename[PATH_MAX], *c; | ||
784 | FILE *file; | ||
785 | int id, n; | ||
786 | |||
787 | sprintf(filename, "%s/", debugfs_path); | ||
788 | strncat(filename, orgname, strlen(orgname)); | ||
789 | strcat(filename, "/id"); | ||
790 | |||
791 | c = strchr(filename, ':'); | ||
792 | if (c) | ||
793 | *c = '/'; | ||
794 | |||
795 | file = fopen(filename, "r"); | ||
796 | if (!file) | ||
797 | return 0; | ||
798 | n = fscanf(file, "%i", &id); | ||
799 | fclose(file); | ||
800 | if (n < 1) { | ||
801 | pr_err("cannot store event ID\n"); | ||
802 | return -EINVAL; | ||
803 | } | ||
804 | return perf_header__push_event(id, orgname); | ||
805 | } | ||
806 | |||
807 | int parse_events(const struct option *opt __used, const char *str, int unset __used) | 810 | int parse_events(const struct option *opt __used, const char *str, int unset __used) |
808 | { | 811 | { |
809 | struct perf_event_attr attr; | 812 | struct perf_event_attr attr; |
810 | enum event_result ret; | 813 | enum event_result ret; |
811 | 814 | ||
812 | if (strchr(str, ':')) | ||
813 | if (store_event_type(str) < 0) | ||
814 | return -1; | ||
815 | |||
816 | for (;;) { | 815 | for (;;) { |
817 | memset(&attr, 0, sizeof(attr)); | 816 | memset(&attr, 0, sizeof(attr)); |
818 | ret = parse_event_symbols(&str, &attr); | 817 | ret = parse_event_symbols(&str, &attr); |
@@ -824,7 +823,7 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u | |||
824 | 823 | ||
825 | if (ret != EVT_HANDLED_ALL) { | 824 | if (ret != EVT_HANDLED_ALL) { |
826 | struct perf_evsel *evsel; | 825 | struct perf_evsel *evsel; |
827 | evsel = perf_evsel__new(attr.type, attr.config, | 826 | evsel = perf_evsel__new(&attr, |
828 | nr_counters); | 827 | nr_counters); |
829 | if (evsel == NULL) | 828 | if (evsel == NULL) |
830 | return -1; | 829 | return -1; |
@@ -1014,8 +1013,15 @@ void print_events(void) | |||
1014 | 1013 | ||
1015 | int perf_evsel_list__create_default(void) | 1014 | int perf_evsel_list__create_default(void) |
1016 | { | 1015 | { |
1017 | struct perf_evsel *evsel = perf_evsel__new(PERF_TYPE_HARDWARE, | 1016 | struct perf_evsel *evsel; |
1018 | PERF_COUNT_HW_CPU_CYCLES, 0); | 1017 | struct perf_event_attr attr; |
1018 | |||
1019 | memset(&attr, 0, sizeof(attr)); | ||
1020 | attr.type = PERF_TYPE_HARDWARE; | ||
1021 | attr.config = PERF_COUNT_HW_CPU_CYCLES; | ||
1022 | |||
1023 | evsel = perf_evsel__new(&attr, 0); | ||
1024 | |||
1019 | if (evsel == NULL) | 1025 | if (evsel == NULL) |
1020 | return -ENOMEM; | 1026 | return -ENOMEM; |
1021 | 1027 | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 6fb4694d05fa..313dac2d94ce 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -1007,7 +1007,7 @@ more: | |||
1007 | if (size == 0) | 1007 | if (size == 0) |
1008 | size = 8; | 1008 | size = 8; |
1009 | 1009 | ||
1010 | if (head + event->header.size >= mmap_size) { | 1010 | if (head + event->header.size > mmap_size) { |
1011 | if (mmaps[map_idx]) { | 1011 | if (mmaps[map_idx]) { |
1012 | munmap(mmaps[map_idx], mmap_size); | 1012 | munmap(mmaps[map_idx], mmap_size); |
1013 | mmaps[map_idx] = NULL; | 1013 | mmaps[map_idx] = NULL; |