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(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(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 return; 1003 1004 sys_dir = opendir(tracing_events_path); 1005 if (!sys_dir) 1006 return; 1007 1008 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 1009 if (subsys_glob != NULL && 1010 !strglobmatch(sys_dirent.d_name, subsys_glob)) 1011 continue; 1012 1013 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 1014 sys_dirent.d_name); 1015 evt_dir = opendir(dir_path); 1016 if (!evt_dir) 1017 continue; 1018 1019 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 1020 if (event_glob != NULL && 1021 !strglobmatch(evt_dirent.d_name, event_glob)) 1022 continue; 1023 1024 if (name_only) { 1025 printf("%s:%s ", sys_dirent.d_name, evt_dirent.d_name); 1026 continue; 1027 } 1028 1029 snprintf(evt_path, MAXPATHLEN, "%s:%s", 1030 sys_dirent.d_name, evt_dirent.d_name); 1031 printf(" %-50s [%s]\n", evt_path, 1032 event_type_descriptors[PERF_TYPE_TRACEPOINT]); 1033 } 1034 closedir(evt_dir); 1035 } 1036 closedir(sys_dir); 1037 } 1038 1039 /* 1040 * Check whether event is in <debugfs_mount_point>/tracing/events 1041 */ 1042 1043 int is_valid_tracepoint(const char *event_string) 1044 { 1045 DIR *sys_dir, *evt_dir; 1046 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1047 char evt_path[MAXPATHLEN]; 1048 char dir_path[MAXPATHLEN]; 1049 1050 if (debugfs_valid_mountpoint(tracing_events_path)) 1051 return 0; 1052 1053 sys_dir = opendir(tracing_events_path); 1054 if (!sys_dir) 1055 return 0; 1056 1057 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 1058 1059 snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 1060 sys_dirent.d_name); 1061 evt_dir = opendir(dir_path); 1062 if (!evt_dir) 1063 continue; 1064 1065 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 1066 snprintf(evt_path, MAXPATHLEN, "%s:%s", 1067 sys_dirent.d_name, evt_dirent.d_name); 1068 if (!strcmp(evt_path, event_string)) { 1069 closedir(evt_dir); 1070 closedir(sys_dir); 1071 return 1; 1072 } 1073 } 1074 closedir(evt_dir); 1075 } 1076 closedir(sys_dir); 1077 return 0; 1078 } 1079 1080 static bool is_event_supported(u8 type, unsigned config) 1081 { 1082 bool ret = true; 1083 struct perf_evsel *evsel; 1084 struct perf_event_attr attr = { 1085 .type = type, 1086 .config = config, 1087 .disabled = 1, 1088 .exclude_kernel = 1, 1089 }; 1090 struct { 1091 struct thread_map map; 1092 int threads[1]; 1093 } tmap = { 1094 .map.nr = 1, 1095 .threads = { 0 }, 1096 }; 1097 1098 evsel = perf_evsel__new(&attr, 0); 1099 if (evsel) { 1100 ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; 1101 perf_evsel__delete(evsel); 1102 } 1103 1104 return ret; 1105 } 1106 1107 static void __print_events_type(u8 type, struct event_symbol *syms, 1108 unsigned max) 1109 { 1110 char name[64]; 1111 unsigned i; 1112 1113 for (i = 0; i < max ; i++, syms++) { 1114 if (!is_event_supported(type, i)) 1115 continue; 1116 1117 if (strlen(syms->alias)) 1118 snprintf(name, sizeof(name), "%s OR %s", 1119 syms->symbol, syms->alias); 1120 else 1121 snprintf(name, sizeof(name), "%s", syms->symbol); 1122 1123 printf(" %-50s [%s]\n", name, event_type_descriptors[type]); 1124 } 1125 } 1126 1127 void print_events_type(u8 type) 1128 { 1129 if (type == PERF_TYPE_SOFTWARE) 1130 __print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX); 1131 else 1132 __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX); 1133 } 1134 1135 int print_hwcache_events(const char *event_glob, bool name_only) 1136 { 1137 unsigned int type, op, i, printed = 0; 1138 char name[64]; 1139 1140 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 1141 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 1142 /* skip invalid cache type */ 1143 if (!perf_evsel__is_cache_op_valid(type, op)) 1144 continue; 1145 1146 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 1147 __perf_evsel__hw_cache_type_op_res_name(type, op, i, 1148 name, sizeof(name)); 1149 if (event_glob != NULL && !strglobmatch(name, event_glob)) 1150 continue; 1151 1152 if (!is_event_supported(PERF_TYPE_HW_CACHE, 1153 type | (op << 8) | (i << 16))) 1154 continue; 1155 1156 if (name_only) 1157 printf("%s ", name); 1158 else 1159 printf(" %-50s [%s]\n", name, 1160 event_type_descriptors[PERF_TYPE_HW_CACHE]); 1161 ++printed; 1162 } 1163 } 1164 } 1165 1166 if (printed) 1167 printf("\n"); 1168 return printed; 1169 } 1170 1171 static void print_symbol_events(const char *event_glob, unsigned type, 1172 struct event_symbol *syms, unsigned max, 1173 bool name_only) 1174 { 1175 unsigned i, printed = 0; 1176 char name[MAX_NAME_LEN]; 1177 1178 for (i = 0; i < max; i++, syms++) { 1179 1180 if (event_glob != NULL && 1181 !(strglobmatch(syms->symbol, event_glob) || 1182 (syms->alias && strglobmatch(syms->alias, event_glob)))) 1183 continue; 1184 1185 if (!is_event_supported(type, i)) 1186 continue; 1187 1188 if (name_only) { 1189 printf("%s ", syms->symbol); 1190 continue; 1191 } 1192 1193 if (strlen(syms->alias)) 1194 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 1195 else 1196 strncpy(name, syms->symbol, MAX_NAME_LEN); 1197 1198 printf(" %-50s [%s]\n", name, event_type_descriptors[type]); 1199 1200 printed++; 1201 } 1202 1203 if (printed) 1204 printf("\n"); 1205 } 1206 1207 /* 1208 * Print the help text for the event symbols: 1209 */ 1210 void print_events(const char *event_glob, bool name_only) 1211 { 1212 if (!name_only) { 1213 printf("\n"); 1214 printf("List of pre-defined events (to be used in -e):\n"); 1215 } 1216 1217 print_symbol_events(event_glob, PERF_TYPE_HARDWARE, 1218 event_symbols_hw, PERF_COUNT_HW_MAX, name_only); 1219 1220 print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, 1221 event_symbols_sw, PERF_COUNT_SW_MAX, name_only); 1222 1223 print_hwcache_events(event_glob, name_only); 1224 1225 print_pmu_events(event_glob, name_only); 1226 1227 if (event_glob != NULL) 1228 return; 1229 1230 if (!name_only) { 1231 printf(" %-50s [%s]\n", 1232 "rNNN", 1233 event_type_descriptors[PERF_TYPE_RAW]); 1234 printf(" %-50s [%s]\n", 1235 "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 1236 event_type_descriptors[PERF_TYPE_RAW]); 1237 printf(" (see 'man perf-list' on how to encode it)\n"); 1238 printf("\n"); 1239 1240 printf(" %-50s [%s]\n", 1241 "mem:<addr>[:access]", 1242 event_type_descriptors[PERF_TYPE_BREAKPOINT]); 1243 printf("\n"); 1244 } 1245 1246 print_tracepoint_events(NULL, NULL, name_only); 1247 } 1248 1249 int parse_events__is_hardcoded_term(struct parse_events_term *term) 1250 { 1251 return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; 1252 } 1253 1254 static int new_term(struct parse_events_term **_term, int type_val, 1255 int type_term, char *config, 1256 char *str, u64 num) 1257 { 1258 struct parse_events_term *term; 1259 1260 term = zalloc(sizeof(*term)); 1261 if (!term) 1262 return -ENOMEM; 1263 1264 INIT_LIST_HEAD(&term->list); 1265 term->type_val = type_val; 1266 term->type_term = type_term; 1267 term->config = config; 1268 1269 switch (type_val) { 1270 case PARSE_EVENTS__TERM_TYPE_NUM: 1271 term->val.num = num; 1272 break; 1273 case PARSE_EVENTS__TERM_TYPE_STR: 1274 term->val.str = str; 1275 break; 1276 default: 1277 free(term); 1278 return -EINVAL; 1279 } 1280 1281 *_term = term; 1282 return 0; 1283 } 1284 1285 int parse_events_term__num(struct parse_events_term **term, 1286 int type_term, char *config, u64 num) 1287 { 1288 return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, 1289 config, NULL, num); 1290 } 1291 1292 int parse_events_term__str(struct parse_events_term **term, 1293 int type_term, char *config, char *str) 1294 { 1295 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, 1296 config, str, 0); 1297 } 1298 1299 int parse_events_term__sym_hw(struct parse_events_term **term, 1300 char *config, unsigned idx) 1301 { 1302 struct event_symbol *sym; 1303 1304 BUG_ON(idx >= PERF_COUNT_HW_MAX); 1305 sym = &event_symbols_hw[idx]; 1306 1307 if (config) 1308 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 1309 PARSE_EVENTS__TERM_TYPE_USER, config, 1310 (char *) sym->symbol, 0); 1311 else 1312 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 1313 PARSE_EVENTS__TERM_TYPE_USER, 1314 (char *) "event", (char *) sym->symbol, 0); 1315 } 1316 1317 int parse_events_term__clone(struct parse_events_term **new, 1318 struct parse_events_term *term) 1319 { 1320 return new_term(new, term->type_val, term->type_term, term->config, 1321 term->val.str, term->val.num); 1322 } 1323 1324 void parse_events__free_terms(struct list_head *terms) 1325 { 1326 struct parse_events_term *term, *h; 1327 1328 list_for_each_entry_safe(term, h, terms, list) 1329 free(term); 1330 } 1331