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