aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-record.txt3
-rw-r--r--tools/perf/Makefile2
-rw-r--r--tools/perf/arch/s390/Makefile4
-rw-r--r--tools/perf/arch/s390/util/dwarf-regs.c22
-rw-r--r--tools/perf/builtin-record.c9
-rw-r--r--tools/perf/builtin-sched.c23
-rw-r--r--tools/perf/builtin-stat.c6
-rw-r--r--tools/perf/builtin-test.c116
-rw-r--r--tools/perf/builtin-top.c3
-rw-r--r--tools/perf/perf.c2
-rw-r--r--tools/perf/util/evsel.c87
-rw-r--r--tools/perf/util/evsel.h2
-rw-r--r--tools/perf/util/parse-events.c74
-rw-r--r--tools/perf/util/session.c2
14 files changed, 266 insertions, 89 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 52462ae26455..e032716c839b 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -61,6 +61,9 @@ OPTIONS
61-r:: 61-r::
62--realtime=:: 62--realtime=::
63 Collect data with this RT SCHED_FIFO priority. 63 Collect data with this RT SCHED_FIFO priority.
64-D::
65--no-delay::
66 Collect data without buffering.
64-A:: 67-A::
65--append:: 68--append::
66 Append to the output file to do incremental profiling. 69 Append to the output file to do incremental profiling.
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
228endif 228endif
229 229
230CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) 230CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
231EXTLIBS = -lpthread -lrt -lelf -lm 231EXTLIBS = -lpthread -lrt -lelf -lm
232ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 232ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
233ALL_LDFLAGS = $(LDFLAGS) 233ALL_LDFLAGS = $(LDFLAGS)
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
new file mode 100644
index 000000000000..15130b50dfe3
--- /dev/null
+++ b/tools/perf/arch/s390/Makefile
@@ -0,0 +1,4 @@
1ifndef NO_DWARF
2PERF_HAVE_DWARF_REGS := 1
3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
4endif
diff --git a/tools/perf/arch/s390/util/dwarf-regs.c b/tools/perf/arch/s390/util/dwarf-regs.c
new file mode 100644
index 000000000000..e19653e025fa
--- /dev/null
+++ b/tools/perf/arch/s390/util/dwarf-regs.c
@@ -0,0 +1,22 @@
1/*
2 * Mapping of DWARF debug register numbers into register names.
3 *
4 * Copyright IBM Corp. 2010
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
6 *
7 */
8
9#include <libio.h>
10#include <dwarf-regs.h>
11
12#define NUM_GPRS 16
13
14static const char *gpr_names[NUM_GPRS] = {
15 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
16 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
17};
18
19const char *get_arch_regstr(unsigned int n)
20{
21 return (n >= NUM_GPRS) ? NULL : gpr_names[n];
22}
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 7bc049035484..df6064ad9bf2 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -49,6 +49,7 @@ static int pipe_output = 0;
49static const char *output_name = "perf.data"; 49static const char *output_name = "perf.data";
50static int group = 0; 50static int group = 0;
51static int realtime_prio = 0; 51static int realtime_prio = 0;
52static bool nodelay = false;
52static bool raw_samples = false; 53static bool raw_samples = false;
53static bool sample_id_all_avail = true; 54static bool sample_id_all_avail = true;
54static bool system_wide = false; 55static bool system_wide = false;
@@ -307,6 +308,11 @@ static void create_counter(struct perf_evsel *evsel, int cpu)
307 attr->sample_type |= PERF_SAMPLE_CPU; 308 attr->sample_type |= PERF_SAMPLE_CPU;
308 } 309 }
309 310
311 if (nodelay) {
312 attr->watermark = 0;
313 attr->wakeup_events = 1;
314 }
315
310 attr->mmap = track; 316 attr->mmap = track;
311 attr->comm = track; 317 attr->comm = track;
312 attr->inherit = !no_inherit; 318 attr->inherit = !no_inherit;
@@ -477,6 +483,7 @@ static void atexit_header(void)
477 process_buildids(); 483 process_buildids();
478 perf_header__write(&session->header, output, true); 484 perf_header__write(&session->header, output, true);
479 perf_session__delete(session); 485 perf_session__delete(session);
486 perf_evsel_list__delete();
480 symbol__exit(); 487 symbol__exit();
481 } 488 }
482} 489}
@@ -842,6 +849,8 @@ const struct option record_options[] = {
842 "record events on existing thread id"), 849 "record events on existing thread id"),
843 OPT_INTEGER('r', "realtime", &realtime_prio, 850 OPT_INTEGER('r', "realtime", &realtime_prio,
844 "collect data with this RT SCHED_FIFO priority"), 851 "collect data with this RT SCHED_FIFO priority"),
852 OPT_BOOLEAN('D', "no-delay", &nodelay,
853 "collect data without buffering"),
845 OPT_BOOLEAN('R', "raw-samples", &raw_samples, 854 OPT_BOOLEAN('R', "raw-samples", &raw_samples,
846 "collect raw sample records from all opened counters"), 855 "collect raw sample records from all opened counters"),
847 OPT_BOOLEAN('a', "all-cpus", &system_wide, 856 OPT_BOOLEAN('a', "all-cpus", &system_wide,
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 7a4ebeb8b016..29e7ffd85690 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);
@@ -1842,15 +1843,15 @@ static const char *record_args[] = {
1842 "-f", 1843 "-f",
1843 "-m", "1024", 1844 "-m", "1024",
1844 "-c", "1", 1845 "-c", "1",
1845 "-e", "sched:sched_switch:r", 1846 "-e", "sched:sched_switch",
1846 "-e", "sched:sched_stat_wait:r", 1847 "-e", "sched:sched_stat_wait",
1847 "-e", "sched:sched_stat_sleep:r", 1848 "-e", "sched:sched_stat_sleep",
1848 "-e", "sched:sched_stat_iowait:r", 1849 "-e", "sched:sched_stat_iowait",
1849 "-e", "sched:sched_stat_runtime:r", 1850 "-e", "sched:sched_stat_runtime",
1850 "-e", "sched:sched_process_exit:r", 1851 "-e", "sched:sched_process_exit",
1851 "-e", "sched:sched_process_fork:r", 1852 "-e", "sched:sched_process_fork",
1852 "-e", "sched:sched_wakeup:r", 1853 "-e", "sched:sched_wakeup",
1853 "-e", "sched:sched_migrate_task:r", 1854 "-e", "sched:sched_migrate_task",
1854}; 1855};
1855 1856
1856static int __cmd_record(int argc, const char **argv) 1857static int __cmd_record(int argc, const char **argv)
@@ -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..0ff11d9b13be 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;
@@ -742,6 +743,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
742out_free_fd: 743out_free_fd:
743 list_for_each_entry(pos, &evsel_list, node) 744 list_for_each_entry(pos, &evsel_list, node)
744 perf_evsel__free_stat_priv(pos); 745 perf_evsel__free_stat_priv(pos);
746 perf_evsel_list__delete();
745out: 747out:
746 thread_map__delete(threads); 748 thread_map__delete(threads);
747 threads = NULL; 749 threads = NULL;
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
327static 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;
419out_close_fd:
420 perf_evsel__close_fd(evsel, 1, threads->nr);
421out_evsel_delete:
422 perf_evsel__delete(evsel);
423out_cpu_free:
424 CPU_FREE(cpu_set);
425out_thread_map_delete:
426 thread_map__delete(threads);
427 return err;
428}
429
320static struct test { 430static 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..05344c6210ac 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1471,6 +1471,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1471 pos->attr.sample_period = default_interval; 1471 pos->attr.sample_period = default_interval;
1472 } 1472 }
1473 1473
1474 sym_evsel = list_entry(evsel_list.next, struct perf_evsel, node);
1475
1474 symbol_conf.priv_size = (sizeof(struct sym_entry) + 1476 symbol_conf.priv_size = (sizeof(struct sym_entry) +
1475 (nr_counters + 1) * sizeof(unsigned long)); 1477 (nr_counters + 1) * sizeof(unsigned long));
1476 1478
@@ -1488,6 +1490,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1488out_free_fd: 1490out_free_fd:
1489 list_for_each_entry(pos, &evsel_list, node) 1491 list_for_each_entry(pos, &evsel_list, node)
1490 perf_evsel__free_mmap(pos); 1492 perf_evsel__free_mmap(pos);
1493 perf_evsel_list__delete();
1491 1494
1492 return status; 1495 return status;
1493} 1496}
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 5b1ecd66bb36..595d0f4a7103 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -286,8 +286,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
286 status = p->fn(argc, argv, prefix); 286 status = p->fn(argc, argv, prefix);
287 exit_browser(status); 287 exit_browser(status);
288 288
289 perf_evsel_list__delete();
290
291 if (status) 289 if (status)
292 return status & 0xff; 290 return status & 0xff;
293 291
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
9struct perf_evsel *perf_evsel__new(u32 type, u64 config, int idx) 9struct 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
131int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus) 130static 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
147out_close: 151out_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
155int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *threads) 162static struct {
163 struct cpu_map map;
164 int cpus[1];
165} empty_cpu_map = {
166 .map.nr = 1,
167 .cpus = { -1, },
168};
169
170static struct {
171 struct thread_map map;
172 int threads[1];
173} empty_thread_map = {
174 .map.nr = 1,
175 .threads = { -1, },
176};
177
178int 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
171out_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
179int perf_evsel__open(struct perf_evsel *evsel, 193int 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); 198int 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 {
37struct cpu_map; 37struct cpu_map;
38struct thread_map; 38struct thread_map;
39 39
40struct perf_evsel *perf_evsel__new(u32 type, u64 config, int idx); 40struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx);
41void perf_evsel__delete(struct perf_evsel *evsel); 41void perf_evsel__delete(struct perf_evsel *evsel);
42 42
43int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); 43int 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
493static 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
494static enum event_result parse_tracepoint_event(const char **strp, 519static 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
541static enum event_result 570static enum event_result
@@ -778,41 +807,11 @@ modifier:
778 return ret; 807 return ret;
779} 808}
780 809
781static 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
807int parse_events(const struct option *opt __used, const char *str, int unset __used) 810int 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
1015int perf_evsel_list__create_default(void) 1014int 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;