1 #include <linux/hw_breakpoint.h> 2 #include "util.h" 3 #include "../perf.h" 4 #include "evlist.h" 5 #include "evsel.h" 6 #include "parse-options.h" 7 #include "parse-events.h" 8 #include "exec_cmd.h" 9 #include "linux/string.h" 10 #include "symbol.h" 11 #include "cache.h" 12 #include "header.h" 13 #include <lk/debugfs.h> 14 #include "parse-events-bison.h" 15 #define YY_EXTRA_TYPE int 16 #include "parse-events-flex.h" 17 #include "pmu.h" 18 #include "thread_map.h" 19 20 #define MAX_NAME_LEN 100 21 22 struct event_symbol { 23 const char *symbol; 24 const char *alias; 25 }; 26 27 #ifdef PARSER_DEBUG 28 extern int parse_events_debug; 29 #endif 30 int parse_events_parse(void *data, void *scanner); 31 32 static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = { 33 [PERF_COUNT_HW_CPU_CYCLES] = { 34 .symbol = "cpu-cycles", 35 .alias = "cycles", 36 }, 37 [PERF_COUNT_HW_INSTRUCTIONS] = { 38 .symbol = "instructions", 39 .alias = "", 40 }, 41 [PERF_COUNT_HW_CACHE_REFERENCES] = { 42 .symbol = "cache-references", 43 .alias = "", 44 }, 45 [PERF_COUNT_HW_CACHE_MISSES] = { 46 .symbol = "cache-misses", 47 .alias = "", 48 }, 49 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 50 .symbol = "branch-instructions", 51 .alias = "branches", 52 }, 53 [PERF_COUNT_HW_BRANCH_MISSES] = { 54 .symbol = "branch-misses", 55 .alias = "", 56 }, 57 [PERF_COUNT_HW_BUS_CYCLES] = { 58 .symbol = "bus-cycles", 59 .alias = "", 60 }, 61 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = { 62 .symbol = "stalled-cycles-frontend", 63 .alias = "idle-cycles-frontend", 64 }, 65 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = { 66 .symbol = "stalled-cycles-backend", 67 .alias = "idle-cycles-backend", 68 }, 69 [PERF_COUNT_HW_REF_CPU_CYCLES] = { 70 .symbol = "ref-cycles", 71 .alias = "", 72 }, 73 }; 74 75 static struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { 76 [PERF_COUNT_SW_CPU_CLOCK] = { 77 .symbol = "cpu-clock", 78 .alias = "", 79 }, 80 [PERF_COUNT_SW_TASK_CLOCK] = { 81 .symbol = "task-clock", 82 .alias = "", 83 }, 84 [PERF_COUNT_SW_PAGE_FAULTS] = { 85 .symbol = "page-faults", 86 .alias = "faults", 87 }, 88 [PERF_COUNT_SW_CONTEXT_SWITCHES] = { 89 .symbol = "context-switches", 90 .alias = "cs", 91 }, 92 [PERF_COUNT_SW_CPU_MIGRATIONS] = { 93 .symbol = "cpu-migrations", 94 .alias = "migrations", 95 }, 96 [PERF_COUNT_SW_PAGE_FAULTS_MIN] = { 97 .symbol = "minor-faults", 98 .alias = "", 99 }, 100 [PERF_COUNT_SW_PAGE_FAULTS_MAJ] = { 101 .symbol = "major-faults", 102 .alias = "", 103 }, 104 [PERF_COUNT_SW_ALIGNMENT_FAULTS] = { 105 .symbol = "alignment-faults", 106 .alias = "", 107 }, 108 [PERF_COUNT_SW_EMULATION_FAULTS] = { 109 .symbol = "emulation-faults", 110 .alias = "", 111 }, 112 [PERF_COUNT_SW_DUMMY] = { 113 .symbol = "dummy", 114 .alias = "", 115 }, 116 }; 117 118 #define __PERF_EVENT_FIELD(config, name) \ 119 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 120 121 #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 122 #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 123 #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 124 #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 125 126 #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 127 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 128 if (sys_dirent.d_type == DT_DIR && \ 129 (strcmp(sys_dirent.d_name, ".")) && \ 130 (strcmp(sys_dirent.d_name, ".."))) 131 132 static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 133 { 134 char evt_path[MAXPATHLEN]; 135 int fd; 136 137 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path, 138 sys_dir->d_name, evt_dir->d_name); 139 fd = open(evt_path, O_RDONLY); 140 if (fd < 0) 141 return -EINVAL; 142 close(fd); 143 144 return 0; 145 } 146 147 #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ 148 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 149 if (evt_dirent.d_type == DT_DIR && \ 150 (strcmp(evt_dirent.d_name, ".")) && \ 151 (strcmp(evt_dirent.d_name, "..")) && \ 152 (!tp_event_has_id(&sys_dirent, &evt_dirent))) 153 154 #define MAX_EVENT_LENGTH 512 155 156 157 struct tracepoint_path *tracepoint_id_to_path(u64 config) 158 { 159 struct tracepoint_path *path = NULL; 160 DIR *sys_dir, *evt_dir; 161 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 162 char id_buf[24]; 163 int fd; 164 u64 id; 165 char evt_path[MAXPATHLEN]; 166 char dir_path[MAXPATHLEN]; 167 168 if (debugfs_valid_mountpoint(tracing_events_path)) 169 return NULL; 170 171 sys_dir = opendir(tracing_events_path); 172 if (!sys_dir) 173 return NULL; 174 175 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 176 177 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 178 sys_dirent.d_name); 179 evt_dir = opendir(dir_path); 180 if (!evt_dir) 181 continue; 182 183 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 184 185 snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 186 evt_dirent.d_name); 187 fd = open(evt_path, O_RDONLY); 188 if (fd < 0) 189 continue; 190 if (read(fd, id_buf, sizeof(id_buf)) < 0) { 191 close(fd); 192 continue; 193 } 194 close(fd); 195 id = atoll(id_buf); 196 if (id == config) { 197 closedir(evt_dir); 198 closedir(sys_dir); 199 path = zalloc(sizeof(*path)); 200 path->system = malloc(MAX_EVENT_LENGTH); 201 if (!path->system) { 202 free(path); 203 return NULL; 204 } 205 path->name = malloc(MAX_EVENT_LENGTH); 206 if (!path->name) { 207 free(path->system); 208 free(path); 209 return NULL; 210 } 211 strncpy(path->system, sys_dirent.d_name, 212 MAX_EVENT_LENGTH); 213 strncpy(path->name, evt_dirent.d_name, 214 MAX_EVENT_LENGTH); 215 return path; 216 } 217 } 218 closedir(evt_dir); 219 } 220 221 closedir(sys_dir); 222 return NULL; 223 } 224 225 struct tracepoint_path *tracepoint_name_to_path(const char *name) 226 { 227 struct tracepoint_path *path = zalloc(sizeof(*path)); 228 char *str = strchr(name, ':'); 229 230 if (path == NULL || str == NULL) { 231 free(path); 232 return NULL; 233 } 234 235 path->system = strndup(name, str - name); 236 path->name = strdup(str+1); 237 238 if (path->system == NULL || path->name == NULL) { 239 free(path->system); 240 free(path->name); 241 free(path); 242 path = NULL; 243 } 244 245 return path; 246 } 247 248 const char *event_type(int type) 249 { 250 switch (type) { 251 case PERF_TYPE_HARDWARE: 252 return "hardware"; 253 254 case PERF_TYPE_SOFTWARE: 255 return "software"; 256 257 case PERF_TYPE_TRACEPOINT: 258 return "tracepoint"; 259 260 case PERF_TYPE_HW_CACHE: 261 return "hardware-cache"; 262 263 default: 264 break; 265 } 266 267 return "unknown"; 268 } 269 270 271 272 static int __add_event(struct list_head *list, int *idx, 273 struct perf_event_attr *attr, 274 char *name, struct cpu_map *cpus) 275 { 276 struct perf_evsel *evsel; 277 278 event_attr_init(attr); 279 280 evsel = perf_evsel__new_idx(attr, (*idx)++); 281 if (!evsel) 282 return -ENOMEM; 283 284 evsel->cpus = cpus; 285 if (name) 286 evsel->name = strdup(name); 287 list_add_tail(&evsel->node, list); 288 return 0; 289 } 290 291 static int add_event(struct list_head *list, int *idx, 292 struct perf_event_attr *attr, char *name) 293 { 294 return __add_event(list, idx, attr, name, NULL); 295 } 296 297 static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) 298 { 299 int i, j; 300 int n, longest = -1; 301 302 for (i = 0; i < size; i++) { 303 for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) { 304 n = strlen(names[i][j]); 305 if (n > longest && !strncasecmp(str, names[i][j], n)) 306 longest = n; 307 } 308 if (longest > 0) 309 return i; 310 } 311 312 return -1; 313 } 314 315 int parse_events_add_cache(struct list_head *list, int *idx, 316 char *type, char *op_result1, char *op_result2) 317 { 318 struct perf_event_attr attr; 319 char name[MAX_NAME_LEN]; 320 int cache_type = -1, cache_op = -1, cache_result = -1; 321 char *op_result[2] = { op_result1, op_result2 }; 322 int i, n; 323 324 /* 325 * No fallback - if we cannot get a clear cache type 326 * then bail out: 327 */ 328 cache_type = parse_aliases(type, perf_evsel__hw_cache, 329 PERF_COUNT_HW_CACHE_MAX); 330 if (cache_type == -1) 331 return -EINVAL; 332 333 n = snprintf(name, MAX_NAME_LEN, "%s", type); 334 335 for (i = 0; (i < 2) && (op_result[i]); i++) { 336 char *str = op_result[i]; 337 338 n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str); 339 340 if (cache_op == -1) { 341 cache_op = parse_aliases(str, perf_evsel__hw_cache_op, 342 PERF_COUNT_HW_CACHE_OP_MAX); 343 if (cache_op >= 0) { 344 if (!perf_evsel__is_cache_op_valid(cache_type, cache_op)) 345 return -EINVAL; 346 continue; 347 } 348 } 349 350 if (cache_result == -1) { 351 cache_result = parse_aliases(str, perf_evsel__hw_cache_result, 352 PERF_COUNT_HW_CACHE_RESULT_MAX); 353 if (cache_result >= 0) 354 continue; 355 } 356 } 357 358 /* 359 * Fall back to reads: 360 */ 361 if (cache_op == -1) 362 cache_op = PERF_COUNT_HW_CACHE_OP_READ; 363 364 /* 365 * Fall back to accesses: 366 */ 367 if (cache_result == -1) 368 cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 369 370 memset(&attr, 0, sizeof(attr)); 371 attr.config = cache_type | (cache_op << 8) | (cache_result << 16); 372 attr.type = PERF_TYPE_HW_CACHE; 373 return add_event(list, idx, &attr, name); 374 } 375 376 static int add_tracepoint(struct list_head *list, int *idx, 377 char *sys_name, char *evt_name) 378 { 379 struct perf_evsel *evsel; 380 381 evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++); 382 if (!evsel) 383 return -ENOMEM; 384 385 list_add_tail(&evsel->node, list); 386 387 return 0; 388 } 389 390 static int add_tracepoint_multi_event(struct list_head *list, int *idx, 391 char *sys_name, char *evt_name) 392 { 393 char evt_path[MAXPATHLEN]; 394 struct dirent *evt_ent; 395 DIR *evt_dir; 396 int ret = 0; 397 398 snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); 399 evt_dir = opendir(evt_path); 400 if (!evt_dir) { 401 perror("Can't open event dir"); 402 return -1; 403 } 404 405 while (!ret && (evt_ent = readdir(evt_dir))) { 406 if (!strcmp(evt_ent->d_name, ".") 407 || !strcmp(evt_ent->d_name, "..") 408 || !strcmp(evt_ent->d_name, "enable") 409 || !strcmp(evt_ent->d_name, "filter")) 410 continue; 411 412 if (!strglobmatch(evt_ent->d_name, evt_name)) 413 continue; 414 415 ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name); 416 } 417 418 closedir(evt_dir); 419 return ret; 420 } 421 422 static int add_tracepoint_event(struct list_head *list, int *idx, 423 char *sys_name, char *evt_name) 424 { 425 return strpbrk(evt_name, "*?") ? 426 add_tracepoint_multi_event(list, idx, sys_name, evt_name) : 427 add_tracepoint(list, idx, sys_name, evt_name); 428 } 429 430 static int add_tracepoint_multi_sys(struct list_head *list, int *idx, 431 char *sys_name, char *evt_name) 432 { 433 struct dirent *events_ent; 434 DIR *events_dir; 435 int ret = 0; 436 437 events_dir = opendir(tracing_events_path); 438 if (!events_dir) { 439 perror("Can't open event dir"); 440 return -1; 441 } 442 443 while (!ret && (events_ent = readdir(events_dir))) { 444 if (!strcmp(events_ent->d_name, ".") 445 || !strcmp(events_ent->d_name, "..") 446 || !strcmp(events_ent->d_name, "enable") 447 || !strcmp(events_ent->d_name, "header_event") 448 || !strcmp(events_ent->d_name, "header_page")) 449 continue; 450 451 if (!strglobmatch(events_ent->d_name, sys_name)) 452 continue; 453 454 ret = add_tracepoint_event(list, idx, events_ent->d_name, 455 evt_name); 456 } 457 458 closedir(events_dir); 459 return ret; 460 } 461 462 int parse_events_add_tracepoint(struct list_head *list, int *idx, 463 char *sys, char *event) 464 { 465 int ret; 466 467 ret = debugfs_valid_mountpoint(tracing_events_path); 468 if (ret) 469 return ret; 470 471 if (strpbrk(sys, "*?")) 472 return add_tracepoint_multi_sys(list, idx, sys, event); 473 else 474 return add_tracepoint_event(list, idx, sys, event); 475 } 476 477 static int 478 parse_breakpoint_type(const char *type, struct perf_event_attr *attr) 479 { 480 int i; 481 482 for (i = 0; i < 3; i++) { 483 if (!type || !type[i]) 484 break; 485 486 #define CHECK_SET_TYPE(bit) \ 487 do { \ 488 if (attr->bp_type & bit) \ 489 return -EINVAL; \ 490 else \ 491 attr->bp_type |= bit; \ 492 } while (0) 493 494 switch (type[i]) { 495 case 'r': 496 CHECK_SET_TYPE(HW_BREAKPOINT_R); 497 break; 498 case 'w': 499 CHECK_SET_TYPE(HW_BREAKPOINT_W); 500 break; 501 case 'x': 502 CHECK_SET_TYPE(HW_BREAKPOINT_X); 503 break; 504 default: 505 return -EINVAL; 506 } 507 } 508 509 #undef CHECK_SET_TYPE 510 511 if (!attr->bp_type) /* Default */ 512 attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 513 514 return 0; 515 } 516 517 int parse_events_add_breakpoint(struct list_head *list, int *idx, 518 void *ptr, char *type) 519 { 520 struct perf_event_attr attr; 521 522 memset(&attr, 0, sizeof(attr)); 523 attr.bp_addr = (unsigned long) ptr; 524 525 if (parse_breakpoint_type(type, &attr)) 526 return -EINVAL; 527 528 /* 529 * We should find a nice way to override the access length 530 * Provide some defaults for now 531 */ 532 if (attr.bp_type == HW_BREAKPOINT_X) 533 attr.bp_len = sizeof(long); 534 else 535 attr.bp_len = HW_BREAKPOINT_LEN_4; 536 537 attr.type = PERF_TYPE_BREAKPOINT; 538 attr.sample_period = 1; 539 540 return add_event(list, idx, &attr, NULL); 541 } 542 543 static int config_term(struct perf_event_attr *attr, 544 struct parse_events_term *term) 545 { 546 #define CHECK_TYPE_VAL(type) \ 547 do { \ 548 if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val) \ 549 return -EINVAL; \ 550 } while (0) 551 552 switch (term->type_term) { 553 case PARSE_EVENTS__TERM_TYPE_CONFIG: 554 CHECK_TYPE_VAL(NUM); 555 attr->config = term->val.num; 556 break; 557 case PARSE_EVENTS__TERM_TYPE_CONFIG1: 558 CHECK_TYPE_VAL(NUM); 559 attr->config1 = term->val.num; 560 break; 561 case PARSE_EVENTS__TERM_TYPE_CONFIG2: 562 CHECK_TYPE_VAL(NUM); 563 attr->config2 = term->val.num; 564 break; 565 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 566 CHECK_TYPE_VAL(NUM); 567 attr->sample_period = term->val.num; 568 break; 569 case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: 570 /* 571 * TODO uncomment when the field is available 572 * attr->branch_sample_type = term->val.num; 573 */ 574 break; 575 case PARSE_EVENTS__TERM_TYPE_NAME: 576 CHECK_TYPE_VAL(STR); 577 break; 578 default: 579 return -EINVAL; 580 } 581 582 return 0; 583 #undef CHECK_TYPE_VAL 584 } 585 586 static int config_attr(struct perf_event_attr *attr, 587 struct list_head *head, int fail) 588 { 589 struct parse_events_term *term; 590 591 list_for_each_entry(term, head, list) 592 if (config_term(attr, term) && fail) 593 return -EINVAL; 594 595 return 0; 596 } 597 598 int parse_events_add_numeric(struct list_head *list, int *idx, 599 u32 type, u64 config, 600 struct list_head *head_config) 601 { 602 struct perf_event_attr attr; 603 604 memset(&attr, 0, sizeof(attr)); 605 attr.type = type; 606 attr.config = config; 607 608 if (head_config && 609 config_attr(&attr, head_config, 1)) 610 return -EINVAL; 611 612 return add_event(list, idx, &attr, NULL); 613 } 614 615 static int parse_events__is_name_term(struct parse_events_term *term) 616 { 617 return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; 618 } 619 620 static char *pmu_event_name(struct list_head *head_terms) 621 { 622 struct parse_events_term *term; 623 624 list_for_each_entry(term, head_terms, list) 625 if (parse_events__is_name_term(term)) 626 return term->val.str; 627 628 return NULL; 629 } 630 631 int parse_events_add_pmu(struct list_head *list, int *idx, 632 char *name, struct list_head *head_config) 633 { 634 struct perf_event_attr attr; 635 struct perf_pmu *pmu; 636 637 pmu = perf_pmu__find(name); 638 if (!pmu) 639 return -EINVAL; 640 641 memset(&attr, 0, sizeof(attr)); 642 643 if (perf_pmu__check_alias(pmu, head_config)) 644 return -EINVAL; 645 646 /* 647 * Configure hardcoded terms first, no need to check 648 * return value when called with fail == 0 ;) 649 */ 650 config_attr(&attr, head_config, 0); 651 652 if (perf_pmu__config(pmu, &attr, head_config)) 653 return -EINVAL; 654 655 return __add_event(list, idx, &attr, pmu_event_name(head_config), 656 pmu->cpus); 657 } 658 659 int parse_events__modifier_group(struct list_head *list, 660 char *event_mod) 661 { 662 return parse_events__modifier_event(list, event_mod, true); 663 } 664 665 void parse_events__set_leader(char *name, struct list_head *list) 666 { 667 struct perf_evsel *leader; 668 669 __perf_evlist__set_leader(list); 670 leader = list_entry(list->next, struct perf_evsel, node); 671 leader->group_name = name ? strdup(name) : NULL; 672 } 673 674 /* list_event is assumed to point to malloc'ed memory */ 675 void parse_events_update_lists(struct list_head *list_event, 676 struct list_head *list_all) 677 { 678 /* 679 * Called for single event definition. Update the 680 * 'all event' list, and reinit the 'single event' 681 * list, for next event definition. 682 */ 683 list_splice_tail(list_event, list_all); 684 free(list_event); 685 } 686 687 struct event_modifier { 688 int eu; 689 int ek; 690 int eh; 691 int eH; 692 int eG; 693 int precise; 694 int exclude_GH; 695 int sample_read; 696 int pinned; 697 }; 698 699 static int get_event_modifier(struct event_modifier *mod, char *str, 700 struct perf_evsel *evsel) 701 { 702 int eu = evsel ? evsel->attr.exclude_user : 0; 703 int ek = evsel ? evsel->attr.exclude_kernel : 0; 704 int eh = evsel ? evsel->attr.exclude_hv : 0; 705 int eH = evsel ? evsel->attr.exclude_host : 0; 706 int eG = evsel ? evsel->attr.exclude_guest : 0; 707 int precise = evsel ? evsel->attr.precise_ip : 0; 708 int sample_read = 0; 709 int pinned = evsel ? evsel->attr.pinned : 0; 710 711 int exclude = eu | ek | eh; 712 int exclude_GH = evsel ? evsel->exclude_GH : 0; 713 714 memset(mod, 0, sizeof(*mod)); 715 716 while (*str) { 717 if (*str == 'u') { 718 if (!exclude) 719 exclude = eu = ek = eh = 1; 720 eu = 0; 721 } else if (*str == 'k') { 722 if (!exclude) 723 exclude = eu = ek = eh = 1; 724 ek = 0; 725 } else if (*str == 'h') { 726 if (!exclude) 727 exclude = eu = ek = eh = 1; 728 eh = 0; 729 } else if (*str == 'G') { 730 if (!exclude_GH) 731 exclude_GH = eG = eH = 1; 732 eG = 0; 733 } else if (*str == 'H') { 734 if (!exclude_GH) 735 exclude_GH = eG = eH = 1; 736 eH = 0; 737 } else if (*str == 'p') { 738 precise++; 739 /* use of precise requires exclude_guest */ 740 if (!exclude_GH) 741 eG = 1; 742 } else if (*str == 'S') { 743 sample_read = 1; 744 } else if (*str == 'D') { 745 pinned = 1; 746 } else 747 break; 748 749 ++str; 750 } 751 752 /* 753 * precise ip: 754 * 755 * 0 - SAMPLE_IP can have arbitrary skid 756 * 1 - SAMPLE_IP must have constant skid 757 * 2 - SAMPLE_IP requested to have 0 skid 758 * 3 - SAMPLE_IP must have 0 skid 759 * 760 * See also PERF_RECORD_MISC_EXACT_IP 761 */ 762 if (precise > 3) 763 return -EINVAL; 764 765 mod->eu = eu; 766 mod->ek = ek; 767 mod->eh = eh; 768 mod->eH = eH; 769 mod->eG = eG; 770 mod->precise = precise; 771 mod->exclude_GH = exclude_GH; 772 mod->sample_read = sample_read; 773 mod->pinned = pinned; 774 775 return 0; 776 } 777 778 /* 779 * Basic modifier sanity check to validate it contains only one 780 * instance of any modifier (apart from 'p') present. 781 */ 782 static int check_modifier(char *str) 783 { 784 char *p = str; 785 786 /* The sizeof includes 0 byte as well. */ 787 if (strlen(str) > (sizeof("ukhGHpppSD") - 1)) 788 return -1; 789 790 while (*p) { 791 if (*p != 'p' && strchr(p + 1, *p)) 792 return -1; 793 p++; 794 } 795 796 return 0; 797 } 798 799 int parse_events__modifier_event(struct list_head *list, char *str, bool add) 800 { 801 struct perf_evsel *evsel; 802 struct event_modifier mod; 803 804 if (str == NULL) 805 return 0; 806 807 if (check_modifier(str)) 808 return -EINVAL; 809 810 if (!add && get_event_modifier(&mod, str, NULL)) 811 return -EINVAL; 812 813 list_for_each_entry(evsel, list, node) { 814 815 if (add && get_event_modifier(&mod, str, evsel)) 816 return -EINVAL; 817 818 evsel->attr.exclude_user = mod.eu; 819 evsel->attr.exclude_kernel = mod.ek; 820 evsel->attr.exclude_hv = mod.eh; 821 evsel->attr.precise_ip = mod.precise; 822 evsel->attr.exclude_host = mod.eH; 823 evsel->attr.exclude_guest = mod.eG; 824 evsel->exclude_GH = mod.exclude_GH; 825 evsel->sample_read = mod.sample_read; 826 827 if (perf_evsel__is_group_leader(evsel)) 828 evsel->attr.pinned = mod.pinned; 829 } 830 831 return 0; 832 } 833 834 int parse_events_name(struct list_head *list, char *name) 835 { 836 struct perf_evsel *evsel; 837 838 list_for_each_entry(evsel, list, node) { 839 if (!evsel->name) 840 evsel->name = strdup(name); 841 } 842 843 return 0; 844 } 845 846 static int parse_events__scanner(const char *str, void *data, int start_token); 847 848 static int parse_events_fixup(int ret, const char *str, void *data, 849 int start_token) 850 { 851 char *o = strdup(str); 852 char *s = NULL; 853 char *t = o; 854 char *p; 855 int len = 0; 856 857 if (!o) 858 return ret; 859 while ((p = strsep(&t, ",")) != NULL) { 860 if (s) 861 str_append(&s, &len, ","); 862 str_append(&s, &len, "cpu/"); 863 str_append(&s, &len, p); 864 str_append(&s, &len, "/"); 865 } 866 free(o); 867 if (!s) 868 return -ENOMEM; 869 return parse_events__scanner(s, data, start_token); 870 } 871 872 static int parse_events__scanner(const char *str, void *data, int start_token) 873 { 874 YY_BUFFER_STATE buffer; 875 void *scanner; 876 int ret; 877 878 ret = parse_events_lex_init_extra(start_token, &scanner); 879 if (ret) 880 return ret; 881 882 buffer = parse_events__scan_string(str, scanner); 883 884 #ifdef PARSER_DEBUG 885 parse_events_debug = 1; 886 #endif 887 ret = parse_events_parse(data, scanner); 888 889 parse_events__flush_buffer(buffer, scanner); 890 parse_events__delete_buffer(buffer, scanner); 891 parse_events_lex_destroy(scanner); 892 if (ret && !strchr(str, '/')) 893 ret = parse_events_fixup(ret, str, data, start_token); 894 return ret; 895 } 896 897 /* 898 * parse event config string, return a list of event terms. 899 */ 900 int parse_events_terms(struct list_head *terms, const char *str) 901 { 902 struct parse_events_terms data = { 903 .terms = NULL, 904 }; 905 int ret; 906 907 ret = parse_events__scanner(str, &data, PE_START_TERMS); 908 if (!ret) { 909 list_splice(data.terms, terms); 910 free(data.terms); 911 return 0; 912 } 913 914 if (data.terms) 915 parse_events__free_terms(data.terms); 916 return ret; 917 } 918 919 int parse_events(struct perf_evlist *evlist, const char *str) 920 { 921 struct parse_events_evlist data = { 922 .list = LIST_HEAD_INIT(data.list), 923 .idx = evlist->nr_entries, 924 }; 925 int ret; 926 927 ret = parse_events__scanner(str, &data, PE_START_EVENTS); 928 if (!ret) { 929 int entries = data.idx - evlist->nr_entries; 930 perf_evlist__splice_list_tail(evlist, &data.list, entries); 931 evlist->nr_groups += data.nr_groups; 932 return 0; 933 } 934 935 /* 936 * There are 2 users - builtin-record and builtin-test objects. 937 * Both call perf_evlist__delete in case of error, so we dont 938 * need to bother. 939 */ 940 return ret; 941 } 942 943 int parse_events_option(const struct option *opt, const char *str, 944 int unset __maybe_unused) 945 { 946 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 947 int ret = parse_events(evlist, str); 948 949 if (ret) { 950 fprintf(stderr, "invalid or unsupported event: '%s'\n", str); 951 fprintf(stderr, "Run 'perf list' for a list of valid events\n"); 952 } 953 return ret; 954 } 955 956 int parse_filter(const struct option *opt, const char *str, 957 int unset __maybe_unused) 958 { 959 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 960 struct perf_evsel *last = NULL; 961 962 if (evlist->nr_entries > 0) 963 last = perf_evlist__last(evlist); 964 965 if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { 966 fprintf(stderr, 967 "-F option should follow a -e tracepoint option\n"); 968 return -1; 969 } 970 971 last->filter = strdup(str); 972 if (last->filter == NULL) { 973 fprintf(stderr, "not enough memory to hold filter string\n"); 974 return -1; 975 } 976 977 return 0; 978 } 979 980 static const char * const event_type_descriptors[] = { 981 "Hardware event", 982 "Software event", 983 "Tracepoint event", 984 "Hardware cache event", 985 "Raw hardware event descriptor", 986 "Hardware breakpoint", 987 }; 988 989 /* 990 * Print the events from <debugfs_mount_point>/tracing/events 991 */ 992 993 void print_tracepoint_events(const char *subsys_glob, const char *event_glob, 994 bool name_only) 995 { 996 DIR *sys_dir, *evt_dir; 997 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 998 char evt_path[MAXPATHLEN]; 999 char dir_path[MAXPATHLEN]; 1000 1001 if (debugfs_valid_mountpoint(tracing_events_path)) { 1002 printf(" [ Tracepoints not available: %s ]\n", strerror(errno)); 1003 return; 1004 } 1005 1006 sys_dir = opendir(tracing_events_path); 1007 if (!sys_dir) 1008 return; 1009 1010 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 1011 if (subsys_glob != NULL && 1012 !strglobmatch(sys_dirent.d_name, subsys_glob)) 1013 continue; 1014 1015 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 1016 sys_dirent.d_name); 1017 evt_dir = opendir(dir_path); 1018 if (!evt_dir) 1019 continue; 1020 1021 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 1022 if (event_glob != NULL && 1023 !strglobmatch(evt_dirent.d_name, event_glob)) 1024 continue; 1025 1026 if (name_only) { 1027 printf("%s:%s ", sys_dirent.d_name, evt_dirent.d_name); 1028 continue; 1029 } 1030 1031 snprintf(evt_path, MAXPATHLEN, "%s:%s", 1032 sys_dirent.d_name, evt_dirent.d_name); 1033 printf(" %-50s [%s]\n", evt_path, 1034 event_type_descriptors[PERF_TYPE_TRACEPOINT]); 1035 } 1036 closedir(evt_dir); 1037 } 1038 closedir(sys_dir); 1039 } 1040 1041 /* 1042 * Check whether event is in <debugfs_mount_point>/tracing/events 1043 */ 1044 1045 int is_valid_tracepoint(const char *event_string) 1046 { 1047 DIR *sys_dir, *evt_dir; 1048 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1049 char evt_path[MAXPATHLEN]; 1050 char dir_path[MAXPATHLEN]; 1051 1052 if (debugfs_valid_mountpoint(tracing_events_path)) 1053 return 0; 1054 1055 sys_dir = opendir(tracing_events_path); 1056 if (!sys_dir) 1057 return 0; 1058 1059 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 1060 1061 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 1062 sys_dirent.d_name); 1063 evt_dir = opendir(dir_path); 1064 if (!evt_dir) 1065 continue; 1066 1067 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 1068 snprintf(evt_path, MAXPATHLEN, "%s:%s", 1069 sys_dirent.d_name, evt_dirent.d_name); 1070 if (!strcmp(evt_path, event_string)) { 1071 closedir(evt_dir); 1072 closedir(sys_dir); 1073 return 1; 1074 } 1075 } 1076 closedir(evt_dir); 1077 } 1078 closedir(sys_dir); 1079 return 0; 1080 } 1081 1082 static bool is_event_supported(u8 type, unsigned config) 1083 { 1084 bool ret = true; 1085 struct perf_evsel *evsel; 1086 struct perf_event_attr attr = { 1087 .type = type, 1088 .config = config, 1089 .disabled = 1, 1090 .exclude_kernel = 1, 1091 }; 1092 struct { 1093 struct thread_map map; 1094 int threads[1]; 1095 } tmap = { 1096 .map.nr = 1, 1097 .threads = { 0 }, 1098 }; 1099 1100 evsel = perf_evsel__new(&attr); 1101 if (evsel) { 1102 ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; 1103 perf_evsel__delete(evsel); 1104 } 1105 1106 return ret; 1107 } 1108 1109 static void __print_events_type(u8 type, struct event_symbol *syms, 1110 unsigned max) 1111 { 1112 char name[64]; 1113 unsigned i; 1114 1115 for (i = 0; i < max ; i++, syms++) { 1116 if (!is_event_supported(type, i)) 1117 continue; 1118 1119 if (strlen(syms->alias)) 1120 snprintf(name, sizeof(name), "%s OR %s", 1121 syms->symbol, syms->alias); 1122 else 1123 snprintf(name, sizeof(name), "%s", syms->symbol); 1124 1125 printf(" %-50s [%s]\n", name, event_type_descriptors[type]); 1126 } 1127 } 1128 1129 void print_events_type(u8 type) 1130 { 1131 if (type == PERF_TYPE_SOFTWARE) 1132 __print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX); 1133 else 1134 __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX); 1135 } 1136 1137 int print_hwcache_events(const char *event_glob, bool name_only) 1138 { 1139 unsigned int type, op, i, printed = 0; 1140 char name[64]; 1141 1142 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 1143 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 1144 /* skip invalid cache type */ 1145 if (!perf_evsel__is_cache_op_valid(type, op)) 1146 continue; 1147 1148 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 1149 __perf_evsel__hw_cache_type_op_res_name(type, op, i, 1150 name, sizeof(name)); 1151 if (event_glob != NULL && !strglobmatch(name, event_glob)) 1152 continue; 1153 1154 if (!is_event_supported(PERF_TYPE_HW_CACHE, 1155 type | (op << 8) | (i << 16))) 1156 continue; 1157 1158 if (name_only) 1159 printf("%s ", name); 1160 else 1161 printf(" %-50s [%s]\n", name, 1162 event_type_descriptors[PERF_TYPE_HW_CACHE]); 1163 ++printed; 1164 } 1165 } 1166 } 1167 1168 if (printed) 1169 printf("\n"); 1170 return printed; 1171 } 1172 1173 static void print_symbol_events(const char *event_glob, unsigned type, 1174 struct event_symbol *syms, unsigned max, 1175 bool name_only) 1176 { 1177 unsigned i, printed = 0; 1178 char name[MAX_NAME_LEN]; 1179 1180 for (i = 0; i < max; i++, syms++) { 1181 1182 if (event_glob != NULL && 1183 !(strglobmatch(syms->symbol, event_glob) || 1184 (syms->alias && strglobmatch(syms->alias, event_glob)))) 1185 continue; 1186 1187 if (!is_event_supported(type, i)) 1188 continue; 1189 1190 if (name_only) { 1191 printf("%s ", syms->symbol); 1192 continue; 1193 } 1194 1195 if (strlen(syms->alias)) 1196 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 1197 else 1198 strncpy(name, syms->symbol, MAX_NAME_LEN); 1199 1200 printf(" %-50s [%s]\n", name, event_type_descriptors[type]); 1201 1202 printed++; 1203 } 1204 1205 if (printed) 1206 printf("\n"); 1207 } 1208 1209 /* 1210 * Print the help text for the event symbols: 1211 */ 1212 void print_events(const char *event_glob, bool name_only) 1213 { 1214 if (!name_only) { 1215 printf("\n"); 1216 printf("List of pre-defined events (to be used in -e):\n"); 1217 } 1218 1219 print_symbol_events(event_glob, PERF_TYPE_HARDWARE, 1220 event_symbols_hw, PERF_COUNT_HW_MAX, name_only); 1221 1222 print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, 1223 event_symbols_sw, PERF_COUNT_SW_MAX, name_only); 1224 1225 print_hwcache_events(event_glob, name_only); 1226 1227 print_pmu_events(event_glob, name_only); 1228 1229 if (event_glob != NULL) 1230 return; 1231 1232 if (!name_only) { 1233 printf(" %-50s [%s]\n", 1234 "rNNN", 1235 event_type_descriptors[PERF_TYPE_RAW]); 1236 printf(" %-50s [%s]\n", 1237 "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 1238 event_type_descriptors[PERF_TYPE_RAW]); 1239 printf(" (see 'man perf-list' on how to encode it)\n"); 1240 printf("\n"); 1241 1242 printf(" %-50s [%s]\n", 1243 "mem:<addr>[:access]", 1244 event_type_descriptors[PERF_TYPE_BREAKPOINT]); 1245 printf("\n"); 1246 } 1247 1248 print_tracepoint_events(NULL, NULL, name_only); 1249 } 1250 1251 int parse_events__is_hardcoded_term(struct parse_events_term *term) 1252 { 1253 return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; 1254 } 1255 1256 static int new_term(struct parse_events_term **_term, int type_val, 1257 int type_term, char *config, 1258 char *str, u64 num) 1259 { 1260 struct parse_events_term *term; 1261 1262 term = zalloc(sizeof(*term)); 1263 if (!term) 1264 return -ENOMEM; 1265 1266 INIT_LIST_HEAD(&term->list); 1267 term->type_val = type_val; 1268 term->type_term = type_term; 1269 term->config = config; 1270 1271 switch (type_val) { 1272 case PARSE_EVENTS__TERM_TYPE_NUM: 1273 term->val.num = num; 1274 break; 1275 case PARSE_EVENTS__TERM_TYPE_STR: 1276 term->val.str = str; 1277 break; 1278 default: 1279 free(term); 1280 return -EINVAL; 1281 } 1282 1283 *_term = term; 1284 return 0; 1285 } 1286 1287 int parse_events_term__num(struct parse_events_term **term, 1288 int type_term, char *config, u64 num) 1289 { 1290 return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, 1291 config, NULL, num); 1292 } 1293 1294 int parse_events_term__str(struct parse_events_term **term, 1295 int type_term, char *config, char *str) 1296 { 1297 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, 1298 config, str, 0); 1299 } 1300 1301 int parse_events_term__sym_hw(struct parse_events_term **term, 1302 char *config, unsigned idx) 1303 { 1304 struct event_symbol *sym; 1305 1306 BUG_ON(idx >= PERF_COUNT_HW_MAX); 1307 sym = &event_symbols_hw[idx]; 1308 1309 if (config) 1310 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 1311 PARSE_EVENTS__TERM_TYPE_USER, config, 1312 (char *) sym->symbol, 0); 1313 else 1314 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 1315 PARSE_EVENTS__TERM_TYPE_USER, 1316 (char *) "event", (char *) sym->symbol, 0); 1317 } 1318 1319 int parse_events_term__clone(struct parse_events_term **new, 1320 struct parse_events_term *term) 1321 { 1322 return new_term(new, term->type_val, term->type_term, term->config, 1323 term->val.str, term->val.num); 1324 } 1325 1326 void parse_events__free_terms(struct list_head *terms) 1327 { 1328 struct parse_events_term *term, *h; 1329 1330 list_for_each_entry_safe(term, h, terms, list) 1331 free(term); 1332 } 1333