diff options
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; |
