1 #include "../../../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 "string.h" 10 #include "symbol.h" 11 #include "cache.h" 12 #include "header.h" 13 #include "debugfs.h" 14 15 struct event_symbol { 16 u8 type; 17 u64 config; 18 const char *symbol; 19 const char *alias; 20 }; 21 22 enum event_result { 23 EVT_FAILED, 24 EVT_HANDLED, 25 EVT_HANDLED_ALL 26 }; 27 28 char debugfs_path[MAXPATHLEN]; 29 30 #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x 31 #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 32 33 static struct event_symbol event_symbols[] = { 34 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, 35 { CHW(STALLED_CYCLES_FRONTEND), "stalled-cycles-frontend", "idle-cycles-frontend" }, 36 { CHW(STALLED_CYCLES_BACKEND), "stalled-cycles-backend", "idle-cycles-backend" }, 37 { CHW(INSTRUCTIONS), "instructions", "" }, 38 { CHW(CACHE_REFERENCES), "cache-references", "" }, 39 { CHW(CACHE_MISSES), "cache-misses", "" }, 40 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, 41 { CHW(BRANCH_MISSES), "branch-misses", "" }, 42 { CHW(BUS_CYCLES), "bus-cycles", "" }, 43 44 { CSW(CPU_CLOCK), "cpu-clock", "" }, 45 { CSW(TASK_CLOCK), "task-clock", "" }, 46 { CSW(PAGE_FAULTS), "page-faults", "faults" }, 47 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, 48 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, 49 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, 50 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 51 { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" }, 52 { CSW(EMULATION_FAULTS), "emulation-faults", "" }, 53 }; 54 55 #define __PERF_EVENT_FIELD(config, name) \ 56 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 57 58 #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 59 #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 60 #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 61 #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 62 63 static const char *hw_event_names[PERF_COUNT_HW_MAX] = { 64 "cycles", 65 "instructions", 66 "cache-references", 67 "cache-misses", 68 "branches", 69 "branch-misses", 70 "bus-cycles", 71 "stalled-cycles-frontend", 72 "stalled-cycles-backend", 73 }; 74 75 static const char *sw_event_names[PERF_COUNT_SW_MAX] = { 76 "cpu-clock", 77 "task-clock", 78 "page-faults", 79 "context-switches", 80 "CPU-migrations", 81 "minor-faults", 82 "major-faults", 83 "alignment-faults", 84 "emulation-faults", 85 }; 86 87 #define MAX_ALIASES 8 88 89 static const char *hw_cache[][MAX_ALIASES] = { 90 { "L1-dcache", "l1-d", "l1d", "L1-data", }, 91 { "L1-icache", "l1-i", "l1i", "L1-instruction", }, 92 { "LLC", "L2" }, 93 { "dTLB", "d-tlb", "Data-TLB", }, 94 { "iTLB", "i-tlb", "Instruction-TLB", }, 95 { "branch", "branches", "bpu", "btb", "bpc", }, 96 }; 97 98 static const char *hw_cache_op[][MAX_ALIASES] = { 99 { "load", "loads", "read", }, 100 { "store", "stores", "write", }, 101 { "prefetch", "prefetches", "speculative-read", "speculative-load", }, 102 }; 103 104 static const char *hw_cache_result[][MAX_ALIASES] = { 105 { "refs", "Reference", "ops", "access", }, 106 { "misses", "miss", }, 107 }; 108 109 #define C(x) PERF_COUNT_HW_CACHE_##x 110 #define CACHE_READ (1 << C(OP_READ)) 111 #define CACHE_WRITE (1 << C(OP_WRITE)) 112 #define CACHE_PREFETCH (1 << C(OP_PREFETCH)) 113 #define COP(x) (1 << x) 114 115 /* 116 * cache operartion stat 117 * L1I : Read and prefetch only 118 * ITLB and BPU : Read-only 119 */ 120 static unsigned long hw_cache_stat[C(MAX)] = { 121 [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 122 [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), 123 [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 124 [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 125 [C(ITLB)] = (CACHE_READ), 126 [C(BPU)] = (CACHE_READ), 127 }; 128 129 #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 130 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 131 if (sys_dirent.d_type == DT_DIR && \ 132 (strcmp(sys_dirent.d_name, ".")) && \ 133 (strcmp(sys_dirent.d_name, ".."))) 134 135 static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 136 { 137 char evt_path[MAXPATHLEN]; 138 int fd; 139 140 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path, 141 sys_dir->d_name, evt_dir->d_name); 142 fd = open(evt_path, O_RDONLY); 143 if (fd < 0) 144 return -EINVAL; 145 close(fd); 146 147 return 0; 148 } 149 150 #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ 151 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 152 if (evt_dirent.d_type == DT_DIR && \ 153 (strcmp(evt_dirent.d_name, ".")) && \ 154 (strcmp(evt_dirent.d_name, "..")) && \ 155 (!tp_event_has_id(&sys_dirent, &evt_dirent))) 156 157 #define MAX_EVENT_LENGTH 512 158 159 160 struct tracepoint_path *tracepoint_id_to_path(u64 config) 161 { 162 struct tracepoint_path *path = NULL; 163 DIR *sys_dir, *evt_dir; 164 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 165 char id_buf[4]; 166 int fd; 167 u64 id; 168 char evt_path[MAXPATHLEN]; 169 char dir_path[MAXPATHLEN]; 170 171 if (debugfs_valid_mountpoint(debugfs_path)) 172 return NULL; 173 174 sys_dir = opendir(debugfs_path); 175 if (!sys_dir) 176 return NULL; 177 178 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 179 180 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path, 181 sys_dirent.d_name); 182 evt_dir = opendir(dir_path); 183 if (!evt_dir) 184 continue; 185 186 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 187 188 snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 189 evt_dirent.d_name); 190 fd = open(evt_path, O_RDONLY); 191 if (fd < 0) 192 continue; 193 if (read(fd, id_buf, sizeof(id_buf)) < 0) { 194 close(fd); 195 continue; 196 } 197 close(fd); 198 id = atoll(id_buf); 199 if (id == config) { 200 closedir(evt_dir); 201 closedir(sys_dir); 202 path = zalloc(sizeof(*path)); 203 path->system = malloc(MAX_EVENT_LENGTH); 204 if (!path->system) { 205 free(path); 206 return NULL; 207 } 208 path->name = malloc(MAX_EVENT_LENGTH); 209 if (!path->name) { 210 free(path->system); 211 free(path); 212 return NULL; 213 } 214 strncpy(path->system, sys_dirent.d_name, 215 MAX_EVENT_LENGTH); 216 strncpy(path->name, evt_dirent.d_name, 217 MAX_EVENT_LENGTH); 218 return path; 219 } 220 } 221 closedir(evt_dir); 222 } 223 224 closedir(sys_dir); 225 return NULL; 226 } 227 228 #define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1) 229 static const char *tracepoint_id_to_name(u64 config) 230 { 231 static char buf[TP_PATH_LEN]; 232 struct tracepoint_path *path; 233 234 path = tracepoint_id_to_path(config); 235 if (path) { 236 snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name); 237 free(path->name); 238 free(path->system); 239 free(path); 240 } else 241 snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown"); 242 243 return buf; 244 } 245 246 static int is_cache_op_valid(u8 cache_type, u8 cache_op) 247 { 248 if (hw_cache_stat[cache_type] & COP(cache_op)) 249 return 1; /* valid */ 250 else 251 return 0; /* invalid */ 252 } 253 254 static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result) 255 { 256 static char name[50]; 257 258 if (cache_result) { 259 sprintf(name, "%s-%s-%s", hw_cache[cache_type][0], 260 hw_cache_op[cache_op][0], 261 hw_cache_result[cache_result][0]); 262 } else { 263 sprintf(name, "%s-%s", hw_cache[cache_type][0], 264 hw_cache_op[cache_op][1]); 265 } 266 267 return name; 268 } 269 270 const char *event_type(int type) 271 { 272 switch (type) { 273 case PERF_TYPE_HARDWARE: 274 return "hardware"; 275 276 case PERF_TYPE_SOFTWARE: 277 return "software"; 278 279 case PERF_TYPE_TRACEPOINT: 280 return "tracepoint"; 281 282 case PERF_TYPE_HW_CACHE: 283 return "hardware-cache"; 284 285 default: 286 break; 287 } 288 289 return "unknown"; 290 } 291 292 const char *event_name(struct perf_evsel *evsel) 293 { 294 u64 config = evsel->attr.config; 295 int type = evsel->attr.type; 296 297 if (evsel->name) 298 return evsel->name; 299 300 return __event_name(type, config); 301 } 302 303 const char *__event_name(int type, u64 config) 304 { 305 static char buf[32]; 306 307 if (type == PERF_TYPE_RAW) { 308 sprintf(buf, "raw 0x%" PRIx64, config); 309 return buf; 310 } 311 312 switch (type) { 313 case PERF_TYPE_HARDWARE: 314 if (config < PERF_COUNT_HW_MAX && hw_event_names[config]) 315 return hw_event_names[config]; 316 return "unknown-hardware"; 317 318 case PERF_TYPE_HW_CACHE: { 319 u8 cache_type, cache_op, cache_result; 320 321 cache_type = (config >> 0) & 0xff; 322 if (cache_type > PERF_COUNT_HW_CACHE_MAX) 323 return "unknown-ext-hardware-cache-type"; 324 325 cache_op = (config >> 8) & 0xff; 326 if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX) 327 return "unknown-ext-hardware-cache-op"; 328 329 cache_result = (config >> 16) & 0xff; 330 if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX) 331 return "unknown-ext-hardware-cache-result"; 332 333 if (!is_cache_op_valid(cache_type, cache_op)) 334 return "invalid-cache"; 335 336 return event_cache_name(cache_type, cache_op, cache_result); 337 } 338 339 case PERF_TYPE_SOFTWARE: 340 if (config < PERF_COUNT_SW_MAX && sw_event_names[config]) 341 return sw_event_names[config]; 342 return "unknown-software"; 343 344 case PERF_TYPE_TRACEPOINT: 345 return tracepoint_id_to_name(config); 346 347 default: 348 break; 349 } 350 351 return "unknown"; 352 } 353 354 static int parse_aliases(const char **str, const char *names[][MAX_ALIASES], int size) 355 { 356 int i, j; 357 int n, longest = -1; 358 359 for (i = 0; i < size; i++) { 360 for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { 361 n = strlen(names[i][j]); 362 if (n > longest && !strncasecmp(*str, names[i][j], n)) 363 longest = n; 364 } 365 if (longest > 0) { 366 *str += longest; 367 return i; 368 } 369 } 370 371 return -1; 372 } 373 374 static enum event_result 375 parse_generic_hw_event(const char **str, struct perf_event_attr *attr) 376 { 377 const char *s = *str; 378 int cache_type = -1, cache_op = -1, cache_result = -1; 379 380 cache_type = parse_aliases(&s, hw_cache, PERF_COUNT_HW_CACHE_MAX); 381 /* 382 * No fallback - if we cannot get a clear cache type 383 * then bail out: 384 */ 385 if (cache_type == -1) 386 return EVT_FAILED; 387 388 while ((cache_op == -1 || cache_result == -1) && *s == '-') { 389 ++s; 390 391 if (cache_op == -1) { 392 cache_op = parse_aliases(&s, hw_cache_op, 393 PERF_COUNT_HW_CACHE_OP_MAX); 394 if (cache_op >= 0) { 395 if (!is_cache_op_valid(cache_type, cache_op)) 396 return 0; 397 continue; 398 } 399 } 400 401 if (cache_result == -1) { 402 cache_result = parse_aliases(&s, hw_cache_result, 403 PERF_COUNT_HW_CACHE_RESULT_MAX); 404 if (cache_result >= 0) 405 continue; 406 } 407 408 /* 409 * Can't parse this as a cache op or result, so back up 410 * to the '-'. 411 */ 412 --s; 413 break; 414 } 415 416 /* 417 * Fall back to reads: 418 */ 419 if (cache_op == -1) 420 cache_op = PERF_COUNT_HW_CACHE_OP_READ; 421 422 /* 423 * Fall back to accesses: 424 */ 425 if (cache_result == -1) 426 cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 427 428 attr->config = cache_type | (cache_op << 8) | (cache_result << 16); 429 attr->type = PERF_TYPE_HW_CACHE; 430 431 *str = s; 432 return EVT_HANDLED; 433 } 434 435 static enum event_result 436 parse_single_tracepoint_event(char *sys_name, 437 const char *evt_name, 438 unsigned int evt_length, 439 struct perf_event_attr *attr, 440 const char **strp) 441 { 442 char evt_path[MAXPATHLEN]; 443 char id_buf[4]; 444 u64 id; 445 int fd; 446 447 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path, 448 sys_name, evt_name); 449 450 fd = open(evt_path, O_RDONLY); 451 if (fd < 0) 452 return EVT_FAILED; 453 454 if (read(fd, id_buf, sizeof(id_buf)) < 0) { 455 close(fd); 456 return EVT_FAILED; 457 } 458 459 close(fd); 460 id = atoll(id_buf); 461 attr->config = id; 462 attr->type = PERF_TYPE_TRACEPOINT; 463 *strp += strlen(sys_name) + evt_length + 1; /* + 1 for the ':' */ 464 465 attr->sample_type |= PERF_SAMPLE_RAW; 466 attr->sample_type |= PERF_SAMPLE_TIME; 467 attr->sample_type |= PERF_SAMPLE_CPU; 468 469 attr->sample_period = 1; 470 471 472 return EVT_HANDLED; 473 } 474 475 /* sys + ':' + event + ':' + flags*/ 476 #define MAX_EVOPT_LEN (MAX_EVENT_LENGTH * 2 + 2 + 128) 477 static enum event_result 478 parse_multiple_tracepoint_event(const struct option *opt, char *sys_name, 479 const char *evt_exp, char *flags) 480 { 481 char evt_path[MAXPATHLEN]; 482 struct dirent *evt_ent; 483 DIR *evt_dir; 484 485 snprintf(evt_path, MAXPATHLEN, "%s/%s", debugfs_path, sys_name); 486 evt_dir = opendir(evt_path); 487 488 if (!evt_dir) { 489 perror("Can't open event dir"); 490 return EVT_FAILED; 491 } 492 493 while ((evt_ent = readdir(evt_dir))) { 494 char event_opt[MAX_EVOPT_LEN + 1]; 495 int len; 496 497 if (!strcmp(evt_ent->d_name, ".") 498 || !strcmp(evt_ent->d_name, "..") 499 || !strcmp(evt_ent->d_name, "enable") 500 || !strcmp(evt_ent->d_name, "filter")) 501 continue; 502 503 if (!strglobmatch(evt_ent->d_name, evt_exp)) 504 continue; 505 506 len = snprintf(event_opt, MAX_EVOPT_LEN, "%s:%s%s%s", sys_name, 507 evt_ent->d_name, flags ? ":" : "", 508 flags ?: ""); 509 if (len < 0) 510 return EVT_FAILED; 511 512 if (parse_events(opt, event_opt, 0)) 513 return EVT_FAILED; 514 } 515 516 return EVT_HANDLED_ALL; 517 } 518 519 static enum event_result 520 parse_tracepoint_event(const struct option *opt, const char **strp, 521 struct perf_event_attr *attr) 522 { 523 const char *evt_name; 524 char *flags = NULL, *comma_loc; 525 char sys_name[MAX_EVENT_LENGTH]; 526 unsigned int sys_length, evt_length; 527 528 if (debugfs_valid_mountpoint(debugfs_path)) 529 return 0; 530 531 evt_name = strchr(*strp, ':'); 532 if (!evt_name) 533 return EVT_FAILED; 534 535 sys_length = evt_name - *strp; 536 if (sys_length >= MAX_EVENT_LENGTH) 537 return 0; 538 539 strncpy(sys_name, *strp, sys_length); 540 sys_name[sys_length] = '\0'; 541 evt_name = evt_name + 1; 542 543 comma_loc = strchr(evt_name, ','); 544 if (comma_loc) { 545 /* take the event name up to the comma */ 546 evt_name = strndup(evt_name, comma_loc - evt_name); 547 } 548 flags = strchr(evt_name, ':'); 549 if (flags) { 550 /* split it out: */ 551 evt_name = strndup(evt_name, flags - evt_name); 552 flags++; 553 } 554 555 evt_length = strlen(evt_name); 556 if (evt_length >= MAX_EVENT_LENGTH) 557 return EVT_FAILED; 558 if (strpbrk(evt_name, "*?")) { 559 *strp += strlen(sys_name) + evt_length + 1; /* 1 == the ':' */ 560 return parse_multiple_tracepoint_event(opt, sys_name, evt_name, 561 flags); 562 } else { 563 return parse_single_tracepoint_event(sys_name, evt_name, 564 evt_length, attr, strp); 565 } 566 } 567 568 static enum event_result 569 parse_breakpoint_type(const char *type, const char **strp, 570 struct perf_event_attr *attr) 571 { 572 int i; 573 574 for (i = 0; i < 3; i++) { 575 if (!type[i]) 576 break; 577 578 switch (type[i]) { 579 case 'r': 580 attr->bp_type |= HW_BREAKPOINT_R; 581 break; 582 case 'w': 583 attr->bp_type |= HW_BREAKPOINT_W; 584 break; 585 case 'x': 586 attr->bp_type |= HW_BREAKPOINT_X; 587 break; 588 default: 589 return EVT_FAILED; 590 } 591 } 592 if (!attr->bp_type) /* Default */ 593 attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 594 595 *strp = type + i; 596 597 return EVT_HANDLED; 598 } 599 600 static enum event_result 601 parse_breakpoint_event(const char **strp, struct perf_event_attr *attr) 602 { 603 const char *target; 604 const char *type; 605 char *endaddr; 606 u64 addr; 607 enum event_result err; 608 609 target = strchr(*strp, ':'); 610 if (!target) 611 return EVT_FAILED; 612 613 if (strncmp(*strp, "mem", target - *strp) != 0) 614 return EVT_FAILED; 615 616 target++; 617 618 addr = strtoull(target, &endaddr, 0); 619 if (target == endaddr) 620 return EVT_FAILED; 621 622 attr->bp_addr = addr; 623 *strp = endaddr; 624 625 type = strchr(target, ':'); 626 627 /* If no type is defined, just rw as default */ 628 if (!type) { 629 attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 630 } else { 631 err = parse_breakpoint_type(++type, strp, attr); 632 if (err == EVT_FAILED) 633 return EVT_FAILED; 634 } 635 636 /* 637 * We should find a nice way to override the access length 638 * Provide some defaults for now 639 */ 640 if (attr->bp_type == HW_BREAKPOINT_X) 641 attr->bp_len = sizeof(long); 642 else 643 attr->bp_len = HW_BREAKPOINT_LEN_4; 644 645 attr->type = PERF_TYPE_BREAKPOINT; 646 647 return EVT_HANDLED; 648 } 649 650 static int check_events(const char *str, unsigned int i) 651 { 652 int n; 653 654 n = strlen(event_symbols[i].symbol); 655 if (!strncasecmp(str, event_symbols[i].symbol, n)) 656 return n; 657 658 n = strlen(event_symbols[i].alias); 659 if (n) { 660 if (!strncasecmp(str, event_symbols[i].alias, n)) 661 return n; 662 } 663 664 return 0; 665 } 666 667 static enum event_result 668 parse_symbolic_event(const char **strp, struct perf_event_attr *attr) 669 { 670 const char *str = *strp; 671 unsigned int i; 672 int n; 673 674 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { 675 n = check_events(str, i); 676 if (n > 0) { 677 attr->type = event_symbols[i].type; 678 attr->config = event_symbols[i].config; 679 *strp = str + n; 680 return EVT_HANDLED; 681 } 682 } 683 return EVT_FAILED; 684 } 685 686 static enum event_result 687 parse_raw_event(const char **strp, struct perf_event_attr *attr) 688 { 689 const char *str = *strp; 690 u64 config; 691 int n; 692 693 if (*str != 'r') 694 return EVT_FAILED; 695 n = hex2u64(str + 1, &config); 696 if (n > 0) { 697 *strp = str + n + 1; 698 attr->type = PERF_TYPE_RAW; 699 attr->config = config; 700 return EVT_HANDLED; 701 } 702 return EVT_FAILED; 703 } 704 705 static enum event_result 706 parse_numeric_event(const char **strp, struct perf_event_attr *attr) 707 { 708 const char *str = *strp; 709 char *endp; 710 unsigned long type; 711 u64 config; 712 713 type = strtoul(str, &endp, 0); 714 if (endp > str && type < PERF_TYPE_MAX && *endp == ':') { 715 str = endp + 1; 716 config = strtoul(str, &endp, 0); 717 if (endp > str) { 718 attr->type = type; 719 attr->config = config; 720 *strp = endp; 721 return EVT_HANDLED; 722 } 723 } 724 return EVT_FAILED; 725 } 726 727 static int 728 parse_event_modifier(const char **strp, struct perf_event_attr *attr) 729 { 730 const char *str = *strp; 731 int exclude = 0; 732 int eu = 0, ek = 0, eh = 0, precise = 0; 733 734 if (!*str) 735 return 0; 736 737 if (*str == ',') 738 return 0; 739 740 if (*str++ != ':') 741 return -1; 742 743 while (*str) { 744 if (*str == 'u') { 745 if (!exclude) 746 exclude = eu = ek = eh = 1; 747 eu = 0; 748 } else if (*str == 'k') { 749 if (!exclude) 750 exclude = eu = ek = eh = 1; 751 ek = 0; 752 } else if (*str == 'h') { 753 if (!exclude) 754 exclude = eu = ek = eh = 1; 755 eh = 0; 756 } else if (*str == 'p') { 757 precise++; 758 } else 759 break; 760 761 ++str; 762 } 763 if (str < *strp + 2) 764 return -1; 765 766 *strp = str; 767 768 attr->exclude_user = eu; 769 attr->exclude_kernel = ek; 770 attr->exclude_hv = eh; 771 attr->precise_ip = precise; 772 773 return 0; 774 } 775 776 /* 777 * Each event can have multiple symbolic names. 778 * Symbolic names are (almost) exactly matched. 779 */ 780 static enum event_result 781 parse_event_symbols(const struct option *opt, const char **str, 782 struct perf_event_attr *attr) 783 { 784 enum event_result ret; 785 786 ret = parse_tracepoint_event(opt, str, attr); 787 if (ret != EVT_FAILED) 788 goto modifier; 789 790 ret = parse_raw_event(str, attr); 791 if (ret != EVT_FAILED) 792 goto modifier; 793 794 ret = parse_numeric_event(str, attr); 795 if (ret != EVT_FAILED) 796 goto modifier; 797 798 ret = parse_symbolic_event(str, attr); 799 if (ret != EVT_FAILED) 800 goto modifier; 801 802 ret = parse_generic_hw_event(str, attr); 803 if (ret != EVT_FAILED) 804 goto modifier; 805 806 ret = parse_breakpoint_event(str, attr); 807 if (ret != EVT_FAILED) 808 goto modifier; 809 810 fprintf(stderr, "invalid or unsupported event: '%s'\n", *str); 811 fprintf(stderr, "Run 'perf list' for a list of valid events\n"); 812 return EVT_FAILED; 813 814 modifier: 815 if (parse_event_modifier(str, attr) < 0) { 816 fprintf(stderr, "invalid event modifier: '%s'\n", *str); 817 fprintf(stderr, "Run 'perf list' for a list of valid events and modifiers\n"); 818 819 return EVT_FAILED; 820 } 821 822 return ret; 823 } 824 825 int parse_events(const struct option *opt, const char *str, int unset __used) 826 { 827 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 828 struct perf_event_attr attr; 829 enum event_result ret; 830 const char *ostr; 831 832 for (;;) { 833 ostr = str; 834 memset(&attr, 0, sizeof(attr)); 835 ret = parse_event_symbols(opt, &str, &attr); 836 if (ret == EVT_FAILED) 837 return -1; 838 839 if (!(*str == 0 || *str == ',' || isspace(*str))) 840 return -1; 841 842 if (ret != EVT_HANDLED_ALL) { 843 struct perf_evsel *evsel; 844 evsel = perf_evsel__new(&attr, evlist->nr_entries); 845 if (evsel == NULL) 846 return -1; 847 perf_evlist__add(evlist, evsel); 848 849 evsel->name = calloc(str - ostr + 1, 1); 850 if (!evsel->name) 851 return -1; 852 strncpy(evsel->name, ostr, str - ostr); 853 } 854 855 if (*str == 0) 856 break; 857 if (*str == ',') 858 ++str; 859 while (isspace(*str)) 860 ++str; 861 } 862 863 return 0; 864 } 865 866 int parse_filter(const struct option *opt, const char *str, 867 int unset __used) 868 { 869 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 870 struct perf_evsel *last = NULL; 871 872 if (evlist->nr_entries > 0) 873 last = list_entry(evlist->entries.prev, struct perf_evsel, node); 874 875 if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { 876 fprintf(stderr, 877 "-F option should follow a -e tracepoint option\n"); 878 return -1; 879 } 880 881 last->filter = strdup(str); 882 if (last->filter == NULL) { 883 fprintf(stderr, "not enough memory to hold filter string\n"); 884 return -1; 885 } 886 887 return 0; 888 } 889 890 static const char * const event_type_descriptors[] = { 891 "Hardware event", 892 "Software event", 893 "Tracepoint event", 894 "Hardware cache event", 895 "Raw hardware event descriptor", 896 "Hardware breakpoint", 897 }; 898 899 /* 900 * Print the events from <debugfs_mount_point>/tracing/events 901 */ 902 903 void print_tracepoint_events(const char *subsys_glob, const char *event_glob) 904 { 905 DIR *sys_dir, *evt_dir; 906 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 907 char evt_path[MAXPATHLEN]; 908 char dir_path[MAXPATHLEN]; 909 910 if (debugfs_valid_mountpoint(debugfs_path)) 911 return; 912 913 sys_dir = opendir(debugfs_path); 914 if (!sys_dir) 915 return; 916 917 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 918 if (subsys_glob != NULL && 919 !strglobmatch(sys_dirent.d_name, subsys_glob)) 920 continue; 921 922 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path, 923 sys_dirent.d_name); 924 evt_dir = opendir(dir_path); 925 if (!evt_dir) 926 continue; 927 928 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 929 if (event_glob != NULL && 930 !strglobmatch(evt_dirent.d_name, event_glob)) 931 continue; 932 933 snprintf(evt_path, MAXPATHLEN, "%s:%s", 934 sys_dirent.d_name, evt_dirent.d_name); 935 printf(" %-50s [%s]\n", evt_path, 936 event_type_descriptors[PERF_TYPE_TRACEPOINT]); 937 } 938 closedir(evt_dir); 939 } 940 closedir(sys_dir); 941 } 942 943 /* 944 * Check whether event is in <debugfs_mount_point>/tracing/events 945 */ 946 947 int is_valid_tracepoint(const char *event_string) 948 { 949 DIR *sys_dir, *evt_dir; 950 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 951 char evt_path[MAXPATHLEN]; 952 char dir_path[MAXPATHLEN]; 953 954 if (debugfs_valid_mountpoint(debugfs_path)) 955 return 0; 956 957 sys_dir = opendir(debugfs_path); 958 if (!sys_dir) 959 return 0; 960 961 for_each_subsystem(sys_dir, sys_dirent, sys_next) { 962 963 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path, 964 sys_dirent.d_name); 965 evt_dir = opendir(dir_path); 966 if (!evt_dir) 967 continue; 968 969 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 970 snprintf(evt_path, MAXPATHLEN, "%s:%s", 971 sys_dirent.d_name, evt_dirent.d_name); 972 if (!strcmp(evt_path, event_string)) { 973 closedir(evt_dir); 974 closedir(sys_dir); 975 return 1; 976 } 977 } 978 closedir(evt_dir); 979 } 980 closedir(sys_dir); 981 return 0; 982 } 983 984 void print_events_type(u8 type) 985 { 986 struct event_symbol *syms = event_symbols; 987 unsigned int i; 988 char name[64]; 989 990 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 991 if (type != syms->type) 992 continue; 993 994 if (strlen(syms->alias)) 995 snprintf(name, sizeof(name), "%s OR %s", 996 syms->symbol, syms->alias); 997 else 998 snprintf(name, sizeof(name), "%s", syms->symbol); 999 1000 printf(" %-50s [%s]\n", name, 1001 event_type_descriptors[type]); 1002 } 1003 } 1004 1005 int print_hwcache_events(const char *event_glob) 1006 { 1007 unsigned int type, op, i, printed = 0; 1008 1009 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 1010 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 1011 /* skip invalid cache type */ 1012 if (!is_cache_op_valid(type, op)) 1013 continue; 1014 1015 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 1016 char *name = event_cache_name(type, op, i); 1017 1018 if (event_glob != NULL && !strglobmatch(name, event_glob)) 1019 continue; 1020 1021 printf(" %-50s [%s]\n", name, 1022 event_type_descriptors[PERF_TYPE_HW_CACHE]); 1023 ++printed; 1024 } 1025 } 1026 } 1027 1028 return printed; 1029 } 1030 1031 #define MAX_NAME_LEN 100 1032 1033 /* 1034 * Print the help text for the event symbols: 1035 */ 1036 void print_events(const char *event_glob) 1037 { 1038 unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; 1039 struct event_symbol *syms = event_symbols; 1040 char name[MAX_NAME_LEN]; 1041 1042 printf("\n"); 1043 printf("List of pre-defined events (to be used in -e):\n"); 1044 1045 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 1046 type = syms->type; 1047 1048 if (type != prev_type && printed) { 1049 printf("\n"); 1050 printed = 0; 1051 ntypes_printed++; 1052 } 1053 1054 if (event_glob != NULL && 1055 !(strglobmatch(syms->symbol, event_glob) || 1056 (syms->alias && strglobmatch(syms->alias, event_glob)))) 1057 continue; 1058 1059 if (strlen(syms->alias)) 1060 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 1061 else 1062 strncpy(name, syms->symbol, MAX_NAME_LEN); 1063 printf(" %-50s [%s]\n", name, 1064 event_type_descriptors[type]); 1065 1066 prev_type = type; 1067 ++printed; 1068 } 1069 1070 if (ntypes_printed) { 1071 printed = 0; 1072 printf("\n"); 1073 } 1074 print_hwcache_events(event_glob); 1075 1076 if (event_glob != NULL) 1077 return; 1078 1079 printf("\n"); 1080 printf(" %-50s [%s]\n", 1081 "rNNN (see 'perf list --help' on how to encode it)", 1082 event_type_descriptors[PERF_TYPE_RAW]); 1083 printf("\n"); 1084 1085 printf(" %-50s [%s]\n", 1086 "mem:<addr>[:access]", 1087 event_type_descriptors[PERF_TYPE_BREAKPOINT]); 1088 printf("\n"); 1089 1090 print_tracepoint_events(NULL, NULL); 1091 1092 exit(129); 1093 } 1094