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