1 2 #include "../perf.h" 3 #include "util.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 10 extern char *strcasestr(const char *haystack, const char *needle); 11 12 int nr_counters; 13 14 struct perf_counter_attr attrs[MAX_COUNTERS]; 15 16 struct event_symbol { 17 u8 type; 18 u64 config; 19 char *symbol; 20 char *alias; 21 }; 22 23 char debugfs_path[MAXPATHLEN]; 24 25 #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x 26 #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 27 28 static struct event_symbol event_symbols[] = { 29 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, 30 { CHW(INSTRUCTIONS), "instructions", "" }, 31 { CHW(CACHE_REFERENCES), "cache-references", "" }, 32 { CHW(CACHE_MISSES), "cache-misses", "" }, 33 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, 34 { CHW(BRANCH_MISSES), "branch-misses", "" }, 35 { CHW(BUS_CYCLES), "bus-cycles", "" }, 36 37 { CSW(CPU_CLOCK), "cpu-clock", "" }, 38 { CSW(TASK_CLOCK), "task-clock", "" }, 39 { CSW(PAGE_FAULTS), "page-faults", "faults" }, 40 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, 41 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, 42 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, 43 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 44 }; 45 46 #define __PERF_COUNTER_FIELD(config, name) \ 47 ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT) 48 49 #define PERF_COUNTER_RAW(config) __PERF_COUNTER_FIELD(config, RAW) 50 #define PERF_COUNTER_CONFIG(config) __PERF_COUNTER_FIELD(config, CONFIG) 51 #define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE) 52 #define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT) 53 54 static char *hw_event_names[] = { 55 "cycles", 56 "instructions", 57 "cache-references", 58 "cache-misses", 59 "branches", 60 "branch-misses", 61 "bus-cycles", 62 }; 63 64 static char *sw_event_names[] = { 65 "cpu-clock-msecs", 66 "task-clock-msecs", 67 "page-faults", 68 "context-switches", 69 "CPU-migrations", 70 "minor-faults", 71 "major-faults", 72 }; 73 74 #define MAX_ALIASES 8 75 76 static char *hw_cache[][MAX_ALIASES] = { 77 { "L1-dcache", "l1-d", "l1d", "L1-data", }, 78 { "L1-icache", "l1-i", "l1i", "L1-instruction", }, 79 { "LLC", "L2" }, 80 { "dTLB", "d-tlb", "Data-TLB", }, 81 { "iTLB", "i-tlb", "Instruction-TLB", }, 82 { "branch", "branches", "bpu", "btb", "bpc", }, 83 }; 84 85 static char *hw_cache_op[][MAX_ALIASES] = { 86 { "load", "loads", "read", }, 87 { "store", "stores", "write", }, 88 { "prefetch", "prefetches", "speculative-read", "speculative-load", }, 89 }; 90 91 static char *hw_cache_result[][MAX_ALIASES] = { 92 { "refs", "Reference", "ops", "access", }, 93 { "misses", "miss", }, 94 }; 95 96 #define C(x) PERF_COUNT_HW_CACHE_##x 97 #define CACHE_READ (1 << C(OP_READ)) 98 #define CACHE_WRITE (1 << C(OP_WRITE)) 99 #define CACHE_PREFETCH (1 << C(OP_PREFETCH)) 100 #define COP(x) (1 << x) 101 102 /* 103 * cache operartion stat 104 * L1I : Read and prefetch only 105 * ITLB and BPU : Read-only 106 */ 107 static unsigned long hw_cache_stat[C(MAX)] = { 108 [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 109 [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), 110 [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 111 [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 112 [C(ITLB)] = (CACHE_READ), 113 [C(BPU)] = (CACHE_READ), 114 }; 115 116 #define for_each_subsystem(sys_dir, sys_dirent, sys_next, file, st) \ 117 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 118 if (snprintf(file, MAXPATHLEN, "%s/%s", debugfs_path, \ 119 sys_dirent.d_name) && \ 120 (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \ 121 (strcmp(sys_dirent.d_name, ".")) && \ 122 (strcmp(sys_dirent.d_name, ".."))) 123 124 #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, file, st) \ 125 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 126 if (snprintf(file, MAXPATHLEN, "%s/%s/%s", debugfs_path, \ 127 sys_dirent.d_name, evt_dirent.d_name) && \ 128 (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \ 129 (strcmp(evt_dirent.d_name, ".")) && \ 130 (strcmp(evt_dirent.d_name, ".."))) 131 132 #define MAX_EVENT_LENGTH 30 133 134 int valid_debugfs_mount(const char *debugfs) 135 { 136 struct statfs st_fs; 137 138 if (statfs(debugfs, &st_fs) < 0) 139 return -ENOENT; 140 else if (st_fs.f_type != (long) DEBUGFS_MAGIC) 141 return -ENOENT; 142 return 0; 143 } 144 145 static char *tracepoint_id_to_name(u64 config) 146 { 147 static char tracepoint_name[2 * MAX_EVENT_LENGTH]; 148 DIR *sys_dir, *evt_dir; 149 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 150 struct stat st; 151 char id_buf[4]; 152 int fd; 153 u64 id; 154 char evt_path[MAXPATHLEN]; 155 156 if (valid_debugfs_mount(debugfs_path)) 157 return "unkown"; 158 159 sys_dir = opendir(debugfs_path); 160 if (!sys_dir) 161 goto cleanup; 162 163 for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) { 164 evt_dir = opendir(evt_path); 165 if (!evt_dir) 166 goto cleanup; 167 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, 168 evt_path, st) { 169 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", 170 debugfs_path, sys_dirent.d_name, 171 evt_dirent.d_name); 172 fd = open(evt_path, O_RDONLY); 173 if (fd < 0) 174 continue; 175 if (read(fd, id_buf, sizeof(id_buf)) < 0) { 176 close(fd); 177 continue; 178 } 179 close(fd); 180 id = atoll(id_buf); 181 if (id == config) { 182 closedir(evt_dir); 183 closedir(sys_dir); 184 snprintf(tracepoint_name, 2 * MAX_EVENT_LENGTH, 185 "%s:%s", sys_dirent.d_name, 186 evt_dirent.d_name); 187 return tracepoint_name; 188 } 189 } 190 closedir(evt_dir); 191 } 192 193 cleanup: 194 closedir(sys_dir); 195 return "unkown"; 196 } 197 198 static int is_cache_op_valid(u8 cache_type, u8 cache_op) 199 { 200 if (hw_cache_stat[cache_type] & COP(cache_op)) 201 return 1; /* valid */ 202 else 203 return 0; /* invalid */ 204 } 205 206 static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result) 207 { 208 static char name[50]; 209 210 if (cache_result) { 211 sprintf(name, "%s-%s-%s", hw_cache[cache_type][0], 212 hw_cache_op[cache_op][0], 213 hw_cache_result[cache_result][0]); 214 } else { 215 sprintf(name, "%s-%s", hw_cache[cache_type][0], 216 hw_cache_op[cache_op][1]); 217 } 218 219 return name; 220 } 221 222 char *event_name(int counter) 223 { 224 u64 config = attrs[counter].config; 225 int type = attrs[counter].type; 226 static char buf[32]; 227 228 if (attrs[counter].type == PERF_TYPE_RAW) { 229 sprintf(buf, "raw 0x%llx", config); 230 return buf; 231 } 232 233 switch (type) { 234 case PERF_TYPE_HARDWARE: 235 if (config < PERF_COUNT_HW_MAX) 236 return hw_event_names[config]; 237 return "unknown-hardware"; 238 239 case PERF_TYPE_HW_CACHE: { 240 u8 cache_type, cache_op, cache_result; 241 242 cache_type = (config >> 0) & 0xff; 243 if (cache_type > PERF_COUNT_HW_CACHE_MAX) 244 return "unknown-ext-hardware-cache-type"; 245 246 cache_op = (config >> 8) & 0xff; 247 if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX) 248 return "unknown-ext-hardware-cache-op"; 249 250 cache_result = (config >> 16) & 0xff; 251 if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX) 252 return "unknown-ext-hardware-cache-result"; 253 254 if (!is_cache_op_valid(cache_type, cache_op)) 255 return "invalid-cache"; 256 257 return event_cache_name(cache_type, cache_op, cache_result); 258 } 259 260 case PERF_TYPE_SOFTWARE: 261 if (config < PERF_COUNT_SW_MAX) 262 return sw_event_names[config]; 263 return "unknown-software"; 264 265 case PERF_TYPE_TRACEPOINT: 266 return tracepoint_id_to_name(config); 267 268 default: 269 break; 270 } 271 272 return "unknown"; 273 } 274 275 static int parse_aliases(const char **str, char *names[][MAX_ALIASES], int size) 276 { 277 int i, j; 278 int n, longest = -1; 279 280 for (i = 0; i < size; i++) { 281 for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { 282 n = strlen(names[i][j]); 283 if (n > longest && !strncasecmp(*str, names[i][j], n)) 284 longest = n; 285 } 286 if (longest > 0) { 287 *str += longest; 288 return i; 289 } 290 } 291 292 return -1; 293 } 294 295 static int 296 parse_generic_hw_event(const char **str, struct perf_counter_attr *attr) 297 { 298 const char *s = *str; 299 int cache_type = -1, cache_op = -1, cache_result = -1; 300 301 cache_type = parse_aliases(&s, hw_cache, PERF_COUNT_HW_CACHE_MAX); 302 /* 303 * No fallback - if we cannot get a clear cache type 304 * then bail out: 305 */ 306 if (cache_type == -1) 307 return 0; 308 309 while ((cache_op == -1 || cache_result == -1) && *s == '-') { 310 ++s; 311 312 if (cache_op == -1) { 313 cache_op = parse_aliases(&s, hw_cache_op, 314 PERF_COUNT_HW_CACHE_OP_MAX); 315 if (cache_op >= 0) { 316 if (!is_cache_op_valid(cache_type, cache_op)) 317 return 0; 318 continue; 319 } 320 } 321 322 if (cache_result == -1) { 323 cache_result = parse_aliases(&s, hw_cache_result, 324 PERF_COUNT_HW_CACHE_RESULT_MAX); 325 if (cache_result >= 0) 326 continue; 327 } 328 329 /* 330 * Can't parse this as a cache op or result, so back up 331 * to the '-'. 332 */ 333 --s; 334 break; 335 } 336 337 /* 338 * Fall back to reads: 339 */ 340 if (cache_op == -1) 341 cache_op = PERF_COUNT_HW_CACHE_OP_READ; 342 343 /* 344 * Fall back to accesses: 345 */ 346 if (cache_result == -1) 347 cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 348 349 attr->config = cache_type | (cache_op << 8) | (cache_result << 16); 350 attr->type = PERF_TYPE_HW_CACHE; 351 352 *str = s; 353 return 1; 354 } 355 356 static int parse_tracepoint_event(const char **strp, 357 struct perf_counter_attr *attr) 358 { 359 const char *evt_name; 360 char sys_name[MAX_EVENT_LENGTH]; 361 char id_buf[4]; 362 int fd; 363 unsigned int sys_length, evt_length; 364 u64 id; 365 char evt_path[MAXPATHLEN]; 366 367 if (valid_debugfs_mount(debugfs_path)) 368 return 0; 369 370 evt_name = strchr(*strp, ':'); 371 if (!evt_name) 372 return 0; 373 374 sys_length = evt_name - *strp; 375 if (sys_length >= MAX_EVENT_LENGTH) 376 return 0; 377 378 strncpy(sys_name, *strp, sys_length); 379 sys_name[sys_length] = '\0'; 380 evt_name = evt_name + 1; 381 evt_length = strlen(evt_name); 382 if (evt_length >= MAX_EVENT_LENGTH) 383 return 0; 384 385 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path, 386 sys_name, evt_name); 387 fd = open(evt_path, O_RDONLY); 388 if (fd < 0) 389 return 0; 390 391 if (read(fd, id_buf, sizeof(id_buf)) < 0) { 392 close(fd); 393 return 0; 394 } 395 close(fd); 396 id = atoll(id_buf); 397 attr->config = id; 398 attr->type = PERF_TYPE_TRACEPOINT; 399 *strp = evt_name + evt_length; 400 return 1; 401 } 402 403 static int check_events(const char *str, unsigned int i) 404 { 405 int n; 406 407 n = strlen(event_symbols[i].symbol); 408 if (!strncmp(str, event_symbols[i].symbol, n)) 409 return n; 410 411 n = strlen(event_symbols[i].alias); 412 if (n) 413 if (!strncmp(str, event_symbols[i].alias, n)) 414 return n; 415 return 0; 416 } 417 418 static int 419 parse_symbolic_event(const char **strp, struct perf_counter_attr *attr) 420 { 421 const char *str = *strp; 422 unsigned int i; 423 int n; 424 425 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { 426 n = check_events(str, i); 427 if (n > 0) { 428 attr->type = event_symbols[i].type; 429 attr->config = event_symbols[i].config; 430 *strp = str + n; 431 return 1; 432 } 433 } 434 return 0; 435 } 436 437 static int parse_raw_event(const char **strp, struct perf_counter_attr *attr) 438 { 439 const char *str = *strp; 440 u64 config; 441 int n; 442 443 if (*str != 'r') 444 return 0; 445 n = hex2u64(str + 1, &config); 446 if (n > 0) { 447 *strp = str + n + 1; 448 attr->type = PERF_TYPE_RAW; 449 attr->config = config; 450 return 1; 451 } 452 return 0; 453 } 454 455 static int 456 parse_numeric_event(const char **strp, struct perf_counter_attr *attr) 457 { 458 const char *str = *strp; 459 char *endp; 460 unsigned long type; 461 u64 config; 462 463 type = strtoul(str, &endp, 0); 464 if (endp > str && type < PERF_TYPE_MAX && *endp == ':') { 465 str = endp + 1; 466 config = strtoul(str, &endp, 0); 467 if (endp > str) { 468 attr->type = type; 469 attr->config = config; 470 *strp = endp; 471 return 1; 472 } 473 } 474 return 0; 475 } 476 477 static int 478 parse_event_modifier(const char **strp, struct perf_counter_attr *attr) 479 { 480 const char *str = *strp; 481 int eu = 1, ek = 1, eh = 1; 482 483 if (*str++ != ':') 484 return 0; 485 while (*str) { 486 if (*str == 'u') 487 eu = 0; 488 else if (*str == 'k') 489 ek = 0; 490 else if (*str == 'h') 491 eh = 0; 492 else 493 break; 494 ++str; 495 } 496 if (str >= *strp + 2) { 497 *strp = str; 498 attr->exclude_user = eu; 499 attr->exclude_kernel = ek; 500 attr->exclude_hv = eh; 501 return 1; 502 } 503 return 0; 504 } 505 506 /* 507 * Each event can have multiple symbolic names. 508 * Symbolic names are (almost) exactly matched. 509 */ 510 static int parse_event_symbols(const char **str, struct perf_counter_attr *attr) 511 { 512 if (!(parse_tracepoint_event(str, attr) || 513 parse_raw_event(str, attr) || 514 parse_numeric_event(str, attr) || 515 parse_symbolic_event(str, attr) || 516 parse_generic_hw_event(str, attr))) 517 return 0; 518 519 parse_event_modifier(str, attr); 520 521 return 1; 522 } 523 524 int parse_events(const struct option *opt __used, const char *str, int unset __used) 525 { 526 struct perf_counter_attr attr; 527 528 for (;;) { 529 if (nr_counters == MAX_COUNTERS) 530 return -1; 531 532 memset(&attr, 0, sizeof(attr)); 533 if (!parse_event_symbols(&str, &attr)) 534 return -1; 535 536 if (!(*str == 0 || *str == ',' || isspace(*str))) 537 return -1; 538 539 attrs[nr_counters] = attr; 540 nr_counters++; 541 542 if (*str == 0) 543 break; 544 if (*str == ',') 545 ++str; 546 while (isspace(*str)) 547 ++str; 548 } 549 550 return 0; 551 } 552 553 static const char * const event_type_descriptors[] = { 554 "", 555 "Hardware event", 556 "Software event", 557 "Tracepoint event", 558 "Hardware cache event", 559 }; 560 561 /* 562 * Print the events from <debugfs_mount_point>/tracing/events 563 */ 564 565 static void print_tracepoint_events(void) 566 { 567 DIR *sys_dir, *evt_dir; 568 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 569 struct stat st; 570 char evt_path[MAXPATHLEN]; 571 572 if (valid_debugfs_mount(debugfs_path)) 573 return; 574 575 sys_dir = opendir(debugfs_path); 576 if (!sys_dir) 577 goto cleanup; 578 579 for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) { 580 evt_dir = opendir(evt_path); 581 if (!evt_dir) 582 goto cleanup; 583 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, 584 evt_path, st) { 585 snprintf(evt_path, MAXPATHLEN, "%s:%s", 586 sys_dirent.d_name, evt_dirent.d_name); 587 fprintf(stderr, " %-40s [%s]\n", evt_path, 588 event_type_descriptors[PERF_TYPE_TRACEPOINT+1]); 589 } 590 closedir(evt_dir); 591 } 592 593 cleanup: 594 closedir(sys_dir); 595 } 596 597 /* 598 * Print the help text for the event symbols: 599 */ 600 void print_events(void) 601 { 602 struct event_symbol *syms = event_symbols; 603 unsigned int i, type, op, prev_type = -1; 604 char name[40]; 605 606 fprintf(stderr, "\n"); 607 fprintf(stderr, "List of pre-defined events (to be used in -e):\n"); 608 609 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 610 type = syms->type + 1; 611 if (type >= ARRAY_SIZE(event_type_descriptors)) 612 type = 0; 613 614 if (type != prev_type) 615 fprintf(stderr, "\n"); 616 617 if (strlen(syms->alias)) 618 sprintf(name, "%s OR %s", syms->symbol, syms->alias); 619 else 620 strcpy(name, syms->symbol); 621 fprintf(stderr, " %-40s [%s]\n", name, 622 event_type_descriptors[type]); 623 624 prev_type = type; 625 } 626 627 fprintf(stderr, "\n"); 628 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 629 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 630 /* skip invalid cache type */ 631 if (!is_cache_op_valid(type, op)) 632 continue; 633 634 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 635 fprintf(stderr, " %-40s [%s]\n", 636 event_cache_name(type, op, i), 637 event_type_descriptors[4]); 638 } 639 } 640 } 641 642 fprintf(stderr, "\n"); 643 fprintf(stderr, " %-40s [raw hardware event descriptor]\n", 644 "rNNN"); 645 fprintf(stderr, "\n"); 646 647 print_tracepoint_events(); 648 649 exit(129); 650 } 651