diff options
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r-- | tools/perf/util/evsel.c | 370 |
1 files changed, 348 insertions, 22 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 1b16dd1edc8e..9c82f98f26de 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -22,6 +22,11 @@ | |||
22 | #include <linux/perf_event.h> | 22 | #include <linux/perf_event.h> |
23 | #include "perf_regs.h" | 23 | #include "perf_regs.h" |
24 | 24 | ||
25 | static struct { | ||
26 | bool sample_id_all; | ||
27 | bool exclude_guest; | ||
28 | } perf_missing_features; | ||
29 | |||
25 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 30 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
26 | 31 | ||
27 | static int __perf_evsel__sample_size(u64 sample_type) | 32 | static int __perf_evsel__sample_size(u64 sample_type) |
@@ -50,11 +55,36 @@ void hists__init(struct hists *hists) | |||
50 | pthread_mutex_init(&hists->lock, NULL); | 55 | pthread_mutex_init(&hists->lock, NULL); |
51 | } | 56 | } |
52 | 57 | ||
58 | void __perf_evsel__set_sample_bit(struct perf_evsel *evsel, | ||
59 | enum perf_event_sample_format bit) | ||
60 | { | ||
61 | if (!(evsel->attr.sample_type & bit)) { | ||
62 | evsel->attr.sample_type |= bit; | ||
63 | evsel->sample_size += sizeof(u64); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | void __perf_evsel__reset_sample_bit(struct perf_evsel *evsel, | ||
68 | enum perf_event_sample_format bit) | ||
69 | { | ||
70 | if (evsel->attr.sample_type & bit) { | ||
71 | evsel->attr.sample_type &= ~bit; | ||
72 | evsel->sample_size -= sizeof(u64); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | void perf_evsel__set_sample_id(struct perf_evsel *evsel) | ||
77 | { | ||
78 | perf_evsel__set_sample_bit(evsel, ID); | ||
79 | evsel->attr.read_format |= PERF_FORMAT_ID; | ||
80 | } | ||
81 | |||
53 | void perf_evsel__init(struct perf_evsel *evsel, | 82 | void perf_evsel__init(struct perf_evsel *evsel, |
54 | struct perf_event_attr *attr, int idx) | 83 | struct perf_event_attr *attr, int idx) |
55 | { | 84 | { |
56 | evsel->idx = idx; | 85 | evsel->idx = idx; |
57 | evsel->attr = *attr; | 86 | evsel->attr = *attr; |
87 | evsel->leader = evsel; | ||
58 | INIT_LIST_HEAD(&evsel->node); | 88 | INIT_LIST_HEAD(&evsel->node); |
59 | hists__init(&evsel->hists); | 89 | hists__init(&evsel->hists); |
60 | evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); | 90 | evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); |
@@ -404,6 +434,31 @@ const char *perf_evsel__name(struct perf_evsel *evsel) | |||
404 | return evsel->name ?: "unknown"; | 434 | return evsel->name ?: "unknown"; |
405 | } | 435 | } |
406 | 436 | ||
437 | const char *perf_evsel__group_name(struct perf_evsel *evsel) | ||
438 | { | ||
439 | return evsel->group_name ?: "anon group"; | ||
440 | } | ||
441 | |||
442 | int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size) | ||
443 | { | ||
444 | int ret; | ||
445 | struct perf_evsel *pos; | ||
446 | const char *group_name = perf_evsel__group_name(evsel); | ||
447 | |||
448 | ret = scnprintf(buf, size, "%s", group_name); | ||
449 | |||
450 | ret += scnprintf(buf + ret, size - ret, " { %s", | ||
451 | perf_evsel__name(evsel)); | ||
452 | |||
453 | for_each_group_member(pos, evsel) | ||
454 | ret += scnprintf(buf + ret, size - ret, ", %s", | ||
455 | perf_evsel__name(pos)); | ||
456 | |||
457 | ret += scnprintf(buf + ret, size - ret, " }"); | ||
458 | |||
459 | return ret; | ||
460 | } | ||
461 | |||
407 | /* | 462 | /* |
408 | * The enable_on_exec/disabled value strategy: | 463 | * The enable_on_exec/disabled value strategy: |
409 | * | 464 | * |
@@ -438,13 +493,11 @@ void perf_evsel__config(struct perf_evsel *evsel, | |||
438 | struct perf_event_attr *attr = &evsel->attr; | 493 | struct perf_event_attr *attr = &evsel->attr; |
439 | int track = !evsel->idx; /* only the first counter needs these */ | 494 | int track = !evsel->idx; /* only the first counter needs these */ |
440 | 495 | ||
441 | attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1; | 496 | attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1; |
442 | attr->inherit = !opts->no_inherit; | 497 | attr->inherit = !opts->no_inherit; |
443 | attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | | ||
444 | PERF_FORMAT_TOTAL_TIME_RUNNING | | ||
445 | PERF_FORMAT_ID; | ||
446 | 498 | ||
447 | attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID; | 499 | perf_evsel__set_sample_bit(evsel, IP); |
500 | perf_evsel__set_sample_bit(evsel, TID); | ||
448 | 501 | ||
449 | /* | 502 | /* |
450 | * We default some events to a 1 default interval. But keep | 503 | * We default some events to a 1 default interval. But keep |
@@ -453,7 +506,7 @@ void perf_evsel__config(struct perf_evsel *evsel, | |||
453 | if (!attr->sample_period || (opts->user_freq != UINT_MAX && | 506 | if (!attr->sample_period || (opts->user_freq != UINT_MAX && |
454 | opts->user_interval != ULLONG_MAX)) { | 507 | opts->user_interval != ULLONG_MAX)) { |
455 | if (opts->freq) { | 508 | if (opts->freq) { |
456 | attr->sample_type |= PERF_SAMPLE_PERIOD; | 509 | perf_evsel__set_sample_bit(evsel, PERIOD); |
457 | attr->freq = 1; | 510 | attr->freq = 1; |
458 | attr->sample_freq = opts->freq; | 511 | attr->sample_freq = opts->freq; |
459 | } else { | 512 | } else { |
@@ -468,16 +521,16 @@ void perf_evsel__config(struct perf_evsel *evsel, | |||
468 | attr->inherit_stat = 1; | 521 | attr->inherit_stat = 1; |
469 | 522 | ||
470 | if (opts->sample_address) { | 523 | if (opts->sample_address) { |
471 | attr->sample_type |= PERF_SAMPLE_ADDR; | 524 | perf_evsel__set_sample_bit(evsel, ADDR); |
472 | attr->mmap_data = track; | 525 | attr->mmap_data = track; |
473 | } | 526 | } |
474 | 527 | ||
475 | if (opts->call_graph) { | 528 | if (opts->call_graph) { |
476 | attr->sample_type |= PERF_SAMPLE_CALLCHAIN; | 529 | perf_evsel__set_sample_bit(evsel, CALLCHAIN); |
477 | 530 | ||
478 | if (opts->call_graph == CALLCHAIN_DWARF) { | 531 | if (opts->call_graph == CALLCHAIN_DWARF) { |
479 | attr->sample_type |= PERF_SAMPLE_REGS_USER | | 532 | perf_evsel__set_sample_bit(evsel, REGS_USER); |
480 | PERF_SAMPLE_STACK_USER; | 533 | perf_evsel__set_sample_bit(evsel, STACK_USER); |
481 | attr->sample_regs_user = PERF_REGS_MASK; | 534 | attr->sample_regs_user = PERF_REGS_MASK; |
482 | attr->sample_stack_user = opts->stack_dump_size; | 535 | attr->sample_stack_user = opts->stack_dump_size; |
483 | attr->exclude_callchain_user = 1; | 536 | attr->exclude_callchain_user = 1; |
@@ -485,20 +538,20 @@ void perf_evsel__config(struct perf_evsel *evsel, | |||
485 | } | 538 | } |
486 | 539 | ||
487 | if (perf_target__has_cpu(&opts->target)) | 540 | if (perf_target__has_cpu(&opts->target)) |
488 | attr->sample_type |= PERF_SAMPLE_CPU; | 541 | perf_evsel__set_sample_bit(evsel, CPU); |
489 | 542 | ||
490 | if (opts->period) | 543 | if (opts->period) |
491 | attr->sample_type |= PERF_SAMPLE_PERIOD; | 544 | perf_evsel__set_sample_bit(evsel, PERIOD); |
492 | 545 | ||
493 | if (!opts->sample_id_all_missing && | 546 | if (!perf_missing_features.sample_id_all && |
494 | (opts->sample_time || !opts->no_inherit || | 547 | (opts->sample_time || !opts->no_inherit || |
495 | perf_target__has_cpu(&opts->target))) | 548 | perf_target__has_cpu(&opts->target))) |
496 | attr->sample_type |= PERF_SAMPLE_TIME; | 549 | perf_evsel__set_sample_bit(evsel, TIME); |
497 | 550 | ||
498 | if (opts->raw_samples) { | 551 | if (opts->raw_samples) { |
499 | attr->sample_type |= PERF_SAMPLE_TIME; | 552 | perf_evsel__set_sample_bit(evsel, TIME); |
500 | attr->sample_type |= PERF_SAMPLE_RAW; | 553 | perf_evsel__set_sample_bit(evsel, RAW); |
501 | attr->sample_type |= PERF_SAMPLE_CPU; | 554 | perf_evsel__set_sample_bit(evsel, CPU); |
502 | } | 555 | } |
503 | 556 | ||
504 | if (opts->no_delay) { | 557 | if (opts->no_delay) { |
@@ -506,7 +559,7 @@ void perf_evsel__config(struct perf_evsel *evsel, | |||
506 | attr->wakeup_events = 1; | 559 | attr->wakeup_events = 1; |
507 | } | 560 | } |
508 | if (opts->branch_stack) { | 561 | if (opts->branch_stack) { |
509 | attr->sample_type |= PERF_SAMPLE_BRANCH_STACK; | 562 | perf_evsel__set_sample_bit(evsel, BRANCH_STACK); |
510 | attr->branch_sample_type = opts->branch_stack; | 563 | attr->branch_sample_type = opts->branch_stack; |
511 | } | 564 | } |
512 | 565 | ||
@@ -519,14 +572,14 @@ void perf_evsel__config(struct perf_evsel *evsel, | |||
519 | * Disabling only independent events or group leaders, | 572 | * Disabling only independent events or group leaders, |
520 | * keeping group members enabled. | 573 | * keeping group members enabled. |
521 | */ | 574 | */ |
522 | if (!perf_evsel__is_group_member(evsel)) | 575 | if (perf_evsel__is_group_leader(evsel)) |
523 | attr->disabled = 1; | 576 | attr->disabled = 1; |
524 | 577 | ||
525 | /* | 578 | /* |
526 | * Setting enable_on_exec for independent events and | 579 | * Setting enable_on_exec for independent events and |
527 | * group leaders for traced executed by perf. | 580 | * group leaders for traced executed by perf. |
528 | */ | 581 | */ |
529 | if (perf_target__none(&opts->target) && !perf_evsel__is_group_member(evsel)) | 582 | if (perf_target__none(&opts->target) && perf_evsel__is_group_leader(evsel)) |
530 | attr->enable_on_exec = 1; | 583 | attr->enable_on_exec = 1; |
531 | } | 584 | } |
532 | 585 | ||
@@ -612,6 +665,11 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | |||
612 | } | 665 | } |
613 | } | 666 | } |
614 | 667 | ||
668 | void perf_evsel__free_counts(struct perf_evsel *evsel) | ||
669 | { | ||
670 | free(evsel->counts); | ||
671 | } | ||
672 | |||
615 | void perf_evsel__exit(struct perf_evsel *evsel) | 673 | void perf_evsel__exit(struct perf_evsel *evsel) |
616 | { | 674 | { |
617 | assert(list_empty(&evsel->node)); | 675 | assert(list_empty(&evsel->node)); |
@@ -631,6 +689,28 @@ void perf_evsel__delete(struct perf_evsel *evsel) | |||
631 | free(evsel); | 689 | free(evsel); |
632 | } | 690 | } |
633 | 691 | ||
692 | static inline void compute_deltas(struct perf_evsel *evsel, | ||
693 | int cpu, | ||
694 | struct perf_counts_values *count) | ||
695 | { | ||
696 | struct perf_counts_values tmp; | ||
697 | |||
698 | if (!evsel->prev_raw_counts) | ||
699 | return; | ||
700 | |||
701 | if (cpu == -1) { | ||
702 | tmp = evsel->prev_raw_counts->aggr; | ||
703 | evsel->prev_raw_counts->aggr = *count; | ||
704 | } else { | ||
705 | tmp = evsel->prev_raw_counts->cpu[cpu]; | ||
706 | evsel->prev_raw_counts->cpu[cpu] = *count; | ||
707 | } | ||
708 | |||
709 | count->val = count->val - tmp.val; | ||
710 | count->ena = count->ena - tmp.ena; | ||
711 | count->run = count->run - tmp.run; | ||
712 | } | ||
713 | |||
634 | int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, | 714 | int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, |
635 | int cpu, int thread, bool scale) | 715 | int cpu, int thread, bool scale) |
636 | { | 716 | { |
@@ -646,6 +726,8 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, | |||
646 | if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) < 0) | 726 | if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) < 0) |
647 | return -errno; | 727 | return -errno; |
648 | 728 | ||
729 | compute_deltas(evsel, cpu, &count); | ||
730 | |||
649 | if (scale) { | 731 | if (scale) { |
650 | if (count.run == 0) | 732 | if (count.run == 0) |
651 | count.val = 0; | 733 | count.val = 0; |
@@ -684,6 +766,8 @@ int __perf_evsel__read(struct perf_evsel *evsel, | |||
684 | } | 766 | } |
685 | } | 767 | } |
686 | 768 | ||
769 | compute_deltas(evsel, -1, aggr); | ||
770 | |||
687 | evsel->counts->scaled = 0; | 771 | evsel->counts->scaled = 0; |
688 | if (scale) { | 772 | if (scale) { |
689 | if (aggr->run == 0) { | 773 | if (aggr->run == 0) { |
@@ -707,7 +791,7 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread) | |||
707 | struct perf_evsel *leader = evsel->leader; | 791 | struct perf_evsel *leader = evsel->leader; |
708 | int fd; | 792 | int fd; |
709 | 793 | ||
710 | if (!perf_evsel__is_group_member(evsel)) | 794 | if (perf_evsel__is_group_leader(evsel)) |
711 | return -1; | 795 | return -1; |
712 | 796 | ||
713 | /* | 797 | /* |
@@ -738,6 +822,13 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | |||
738 | pid = evsel->cgrp->fd; | 822 | pid = evsel->cgrp->fd; |
739 | } | 823 | } |
740 | 824 | ||
825 | fallback_missing_features: | ||
826 | if (perf_missing_features.exclude_guest) | ||
827 | evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; | ||
828 | retry_sample_id: | ||
829 | if (perf_missing_features.sample_id_all) | ||
830 | evsel->attr.sample_id_all = 0; | ||
831 | |||
741 | for (cpu = 0; cpu < cpus->nr; cpu++) { | 832 | for (cpu = 0; cpu < cpus->nr; cpu++) { |
742 | 833 | ||
743 | for (thread = 0; thread < threads->nr; thread++) { | 834 | for (thread = 0; thread < threads->nr; thread++) { |
@@ -754,13 +845,26 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | |||
754 | group_fd, flags); | 845 | group_fd, flags); |
755 | if (FD(evsel, cpu, thread) < 0) { | 846 | if (FD(evsel, cpu, thread) < 0) { |
756 | err = -errno; | 847 | err = -errno; |
757 | goto out_close; | 848 | goto try_fallback; |
758 | } | 849 | } |
759 | } | 850 | } |
760 | } | 851 | } |
761 | 852 | ||
762 | return 0; | 853 | return 0; |
763 | 854 | ||
855 | try_fallback: | ||
856 | if (err != -EINVAL || cpu > 0 || thread > 0) | ||
857 | goto out_close; | ||
858 | |||
859 | if (!perf_missing_features.exclude_guest && | ||
860 | (evsel->attr.exclude_guest || evsel->attr.exclude_host)) { | ||
861 | perf_missing_features.exclude_guest = true; | ||
862 | goto fallback_missing_features; | ||
863 | } else if (!perf_missing_features.sample_id_all) { | ||
864 | perf_missing_features.sample_id_all = true; | ||
865 | goto retry_sample_id; | ||
866 | } | ||
867 | |||
764 | out_close: | 868 | out_close: |
765 | do { | 869 | do { |
766 | while (--thread >= 0) { | 870 | while (--thread >= 0) { |
@@ -1205,3 +1309,225 @@ u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, | |||
1205 | 1309 | ||
1206 | return 0; | 1310 | return 0; |
1207 | } | 1311 | } |
1312 | |||
1313 | static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...) | ||
1314 | { | ||
1315 | va_list args; | ||
1316 | int ret = 0; | ||
1317 | |||
1318 | if (!*first) { | ||
1319 | ret += fprintf(fp, ","); | ||
1320 | } else { | ||
1321 | ret += fprintf(fp, ":"); | ||
1322 | *first = false; | ||
1323 | } | ||
1324 | |||
1325 | va_start(args, fmt); | ||
1326 | ret += vfprintf(fp, fmt, args); | ||
1327 | va_end(args); | ||
1328 | return ret; | ||
1329 | } | ||
1330 | |||
1331 | static int __if_fprintf(FILE *fp, bool *first, const char *field, u64 value) | ||
1332 | { | ||
1333 | if (value == 0) | ||
1334 | return 0; | ||
1335 | |||
1336 | return comma_fprintf(fp, first, " %s: %" PRIu64, field, value); | ||
1337 | } | ||
1338 | |||
1339 | #define if_print(field) printed += __if_fprintf(fp, &first, #field, evsel->attr.field) | ||
1340 | |||
1341 | struct bit_names { | ||
1342 | int bit; | ||
1343 | const char *name; | ||
1344 | }; | ||
1345 | |||
1346 | static int bits__fprintf(FILE *fp, const char *field, u64 value, | ||
1347 | struct bit_names *bits, bool *first) | ||
1348 | { | ||
1349 | int i = 0, printed = comma_fprintf(fp, first, " %s: ", field); | ||
1350 | bool first_bit = true; | ||
1351 | |||
1352 | do { | ||
1353 | if (value & bits[i].bit) { | ||
1354 | printed += fprintf(fp, "%s%s", first_bit ? "" : "|", bits[i].name); | ||
1355 | first_bit = false; | ||
1356 | } | ||
1357 | } while (bits[++i].name != NULL); | ||
1358 | |||
1359 | return printed; | ||
1360 | } | ||
1361 | |||
1362 | static int sample_type__fprintf(FILE *fp, bool *first, u64 value) | ||
1363 | { | ||
1364 | #define bit_name(n) { PERF_SAMPLE_##n, #n } | ||
1365 | struct bit_names bits[] = { | ||
1366 | bit_name(IP), bit_name(TID), bit_name(TIME), bit_name(ADDR), | ||
1367 | bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU), | ||
1368 | bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), | ||
1369 | bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), | ||
1370 | { .name = NULL, } | ||
1371 | }; | ||
1372 | #undef bit_name | ||
1373 | return bits__fprintf(fp, "sample_type", value, bits, first); | ||
1374 | } | ||
1375 | |||
1376 | static int read_format__fprintf(FILE *fp, bool *first, u64 value) | ||
1377 | { | ||
1378 | #define bit_name(n) { PERF_FORMAT_##n, #n } | ||
1379 | struct bit_names bits[] = { | ||
1380 | bit_name(TOTAL_TIME_ENABLED), bit_name(TOTAL_TIME_RUNNING), | ||
1381 | bit_name(ID), bit_name(GROUP), | ||
1382 | { .name = NULL, } | ||
1383 | }; | ||
1384 | #undef bit_name | ||
1385 | return bits__fprintf(fp, "read_format", value, bits, first); | ||
1386 | } | ||
1387 | |||
1388 | int perf_evsel__fprintf(struct perf_evsel *evsel, | ||
1389 | struct perf_attr_details *details, FILE *fp) | ||
1390 | { | ||
1391 | bool first = true; | ||
1392 | int printed = 0; | ||
1393 | |||
1394 | if (details->event_group) { | ||
1395 | struct perf_evsel *pos; | ||
1396 | |||
1397 | if (!perf_evsel__is_group_leader(evsel)) | ||
1398 | return 0; | ||
1399 | |||
1400 | if (evsel->nr_members > 1) | ||
1401 | printed += fprintf(fp, "%s{", evsel->group_name ?: ""); | ||
1402 | |||
1403 | printed += fprintf(fp, "%s", perf_evsel__name(evsel)); | ||
1404 | for_each_group_member(pos, evsel) | ||
1405 | printed += fprintf(fp, ",%s", perf_evsel__name(pos)); | ||
1406 | |||
1407 | if (evsel->nr_members > 1) | ||
1408 | printed += fprintf(fp, "}"); | ||
1409 | goto out; | ||
1410 | } | ||
1411 | |||
1412 | printed += fprintf(fp, "%s", perf_evsel__name(evsel)); | ||
1413 | |||
1414 | if (details->verbose || details->freq) { | ||
1415 | printed += comma_fprintf(fp, &first, " sample_freq=%" PRIu64, | ||
1416 | (u64)evsel->attr.sample_freq); | ||
1417 | } | ||
1418 | |||
1419 | if (details->verbose) { | ||
1420 | if_print(type); | ||
1421 | if_print(config); | ||
1422 | if_print(config1); | ||
1423 | if_print(config2); | ||
1424 | if_print(size); | ||
1425 | printed += sample_type__fprintf(fp, &first, evsel->attr.sample_type); | ||
1426 | if (evsel->attr.read_format) | ||
1427 | printed += read_format__fprintf(fp, &first, evsel->attr.read_format); | ||
1428 | if_print(disabled); | ||
1429 | if_print(inherit); | ||
1430 | if_print(pinned); | ||
1431 | if_print(exclusive); | ||
1432 | if_print(exclude_user); | ||
1433 | if_print(exclude_kernel); | ||
1434 | if_print(exclude_hv); | ||
1435 | if_print(exclude_idle); | ||
1436 | if_print(mmap); | ||
1437 | if_print(comm); | ||
1438 | if_print(freq); | ||
1439 | if_print(inherit_stat); | ||
1440 | if_print(enable_on_exec); | ||
1441 | if_print(task); | ||
1442 | if_print(watermark); | ||
1443 | if_print(precise_ip); | ||
1444 | if_print(mmap_data); | ||
1445 | if_print(sample_id_all); | ||
1446 | if_print(exclude_host); | ||
1447 | if_print(exclude_guest); | ||
1448 | if_print(__reserved_1); | ||
1449 | if_print(wakeup_events); | ||
1450 | if_print(bp_type); | ||
1451 | if_print(branch_sample_type); | ||
1452 | } | ||
1453 | out: | ||
1454 | fputc('\n', fp); | ||
1455 | return ++printed; | ||
1456 | } | ||
1457 | |||
1458 | bool perf_evsel__fallback(struct perf_evsel *evsel, int err, | ||
1459 | char *msg, size_t msgsize) | ||
1460 | { | ||
1461 | if ((err == ENOENT || err == ENXIO) && | ||
1462 | evsel->attr.type == PERF_TYPE_HARDWARE && | ||
1463 | evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES) { | ||
1464 | /* | ||
1465 | * If it's cycles then fall back to hrtimer based | ||
1466 | * cpu-clock-tick sw counter, which is always available even if | ||
1467 | * no PMU support. | ||
1468 | * | ||
1469 | * PPC returns ENXIO until 2.6.37 (behavior changed with commit | ||
1470 | * b0a873e). | ||
1471 | */ | ||
1472 | scnprintf(msg, msgsize, "%s", | ||
1473 | "The cycles event is not supported, trying to fall back to cpu-clock-ticks"); | ||
1474 | |||
1475 | evsel->attr.type = PERF_TYPE_SOFTWARE; | ||
1476 | evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK; | ||
1477 | |||
1478 | free(evsel->name); | ||
1479 | evsel->name = NULL; | ||
1480 | return true; | ||
1481 | } | ||
1482 | |||
1483 | return false; | ||
1484 | } | ||
1485 | |||
1486 | int perf_evsel__open_strerror(struct perf_evsel *evsel, | ||
1487 | struct perf_target *target, | ||
1488 | int err, char *msg, size_t size) | ||
1489 | { | ||
1490 | switch (err) { | ||
1491 | case EPERM: | ||
1492 | case EACCES: | ||
1493 | return scnprintf(msg, size, "%s", | ||
1494 | "You may not have permission to collect %sstats.\n" | ||
1495 | "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" | ||
1496 | " -1 - Not paranoid at all\n" | ||
1497 | " 0 - Disallow raw tracepoint access for unpriv\n" | ||
1498 | " 1 - Disallow cpu events for unpriv\n" | ||
1499 | " 2 - Disallow kernel profiling for unpriv", | ||
1500 | target->system_wide ? "system-wide " : ""); | ||
1501 | case ENOENT: | ||
1502 | return scnprintf(msg, size, "The %s event is not supported.", | ||
1503 | perf_evsel__name(evsel)); | ||
1504 | case EMFILE: | ||
1505 | return scnprintf(msg, size, "%s", | ||
1506 | "Too many events are opened.\n" | ||
1507 | "Try again after reducing the number of events."); | ||
1508 | case ENODEV: | ||
1509 | if (target->cpu_list) | ||
1510 | return scnprintf(msg, size, "%s", | ||
1511 | "No such device - did you specify an out-of-range profile CPU?\n"); | ||
1512 | break; | ||
1513 | case EOPNOTSUPP: | ||
1514 | if (evsel->attr.precise_ip) | ||
1515 | return scnprintf(msg, size, "%s", | ||
1516 | "\'precise\' request may not be supported. Try removing 'p' modifier."); | ||
1517 | #if defined(__i386__) || defined(__x86_64__) | ||
1518 | if (evsel->attr.type == PERF_TYPE_HARDWARE) | ||
1519 | return scnprintf(msg, size, "%s", | ||
1520 | "No hardware sampling interrupt available.\n" | ||
1521 | "No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it."); | ||
1522 | #endif | ||
1523 | break; | ||
1524 | default: | ||
1525 | break; | ||
1526 | } | ||
1527 | |||
1528 | return scnprintf(msg, size, | ||
1529 | "The sys_perf_event_open() syscall returned with %d (%s) for event (%s). \n" | ||
1530 | "/bin/dmesg may provide additional information.\n" | ||
1531 | "No CONFIG_PERF_EVENTS=y kernel support configured?\n", | ||
1532 | err, strerror(err), perf_evsel__name(evsel)); | ||
1533 | } | ||