1 #include <linux/list.h> 2 #include <linux/compiler.h> 3 #include <sys/types.h> 4 #include <unistd.h> 5 #include <stdio.h> 6 #include <stdbool.h> 7 #include <stdarg.h> 8 #include <dirent.h> 9 #include <api/fs/fs.h> 10 #include <locale.h> 11 #include "util.h" 12 #include "pmu.h" 13 #include "parse-events.h" 14 #include "cpumap.h" 15 #include "header.h" 16 #include "pmu-events/pmu-events.h" 17 #include "cache.h" 18 19 struct perf_pmu_format { 20 char *name; 21 int value; 22 DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); 23 struct list_head list; 24 }; 25 26 #define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/" 27 28 int perf_pmu_parse(struct list_head *list, char *name); 29 extern FILE *perf_pmu_in; 30 31 static LIST_HEAD(pmus); 32 33 /* 34 * Parse & process all the sysfs attributes located under 35 * the directory specified in 'dir' parameter. 36 */ 37 int perf_pmu__format_parse(char *dir, struct list_head *head) 38 { 39 struct dirent *evt_ent; 40 DIR *format_dir; 41 int ret = 0; 42 43 format_dir = opendir(dir); 44 if (!format_dir) 45 return -EINVAL; 46 47 while (!ret && (evt_ent = readdir(format_dir))) { 48 char path[PATH_MAX]; 49 char *name = evt_ent->d_name; 50 FILE *file; 51 52 if (!strcmp(name, ".") || !strcmp(name, "..")) 53 continue; 54 55 snprintf(path, PATH_MAX, "%s/%s", dir, name); 56 57 ret = -EINVAL; 58 file = fopen(path, "r"); 59 if (!file) 60 break; 61 62 perf_pmu_in = file; 63 ret = perf_pmu_parse(head, name); 64 fclose(file); 65 } 66 67 closedir(format_dir); 68 return ret; 69 } 70 71 /* 72 * Reading/parsing the default pmu format definition, which should be 73 * located at: 74 * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes. 75 */ 76 static int pmu_format(const char *name, struct list_head *format) 77 { 78 struct stat st; 79 char path[PATH_MAX]; 80 const char *sysfs = sysfs__mountpoint(); 81 82 if (!sysfs) 83 return -1; 84 85 snprintf(path, PATH_MAX, 86 "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name); 87 88 if (stat(path, &st) < 0) 89 return 0; /* no error if format does not exist */ 90 91 if (perf_pmu__format_parse(path, format)) 92 return -1; 93 94 return 0; 95 } 96 97 static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name) 98 { 99 struct stat st; 100 ssize_t sret; 101 char scale[128]; 102 int fd, ret = -1; 103 char path[PATH_MAX]; 104 char *lc; 105 106 snprintf(path, PATH_MAX, "%s/%s.scale", dir, name); 107 108 fd = open(path, O_RDONLY); 109 if (fd == -1) 110 return -1; 111 112 if (fstat(fd, &st) < 0) 113 goto error; 114 115 sret = read(fd, scale, sizeof(scale)-1); 116 if (sret < 0) 117 goto error; 118 119 if (scale[sret - 1] == '\n') 120 scale[sret - 1] = '\0'; 121 else 122 scale[sret] = '\0'; 123 124 /* 125 * save current locale 126 */ 127 lc = setlocale(LC_NUMERIC, NULL); 128 129 /* 130 * The lc string may be allocated in static storage, 131 * so get a dynamic copy to make it survive setlocale 132 * call below. 133 */ 134 lc = strdup(lc); 135 if (!lc) { 136 ret = -ENOMEM; 137 goto error; 138 } 139 140 /* 141 * force to C locale to ensure kernel 142 * scale string is converted correctly. 143 * kernel uses default C locale. 144 */ 145 setlocale(LC_NUMERIC, "C"); 146 147 alias->scale = strtod(scale, NULL); 148 149 /* restore locale */ 150 setlocale(LC_NUMERIC, lc); 151 152 free(lc); 153 154 ret = 0; 155 error: 156 close(fd); 157 return ret; 158 } 159 160 static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name) 161 { 162 char path[PATH_MAX]; 163 ssize_t sret; 164 int fd; 165 166 snprintf(path, PATH_MAX, "%s/%s.unit", dir, name); 167 168 fd = open(path, O_RDONLY); 169 if (fd == -1) 170 return -1; 171 172 sret = read(fd, alias->unit, UNIT_MAX_LEN); 173 if (sret < 0) 174 goto error; 175 176 close(fd); 177 178 if (alias->unit[sret - 1] == '\n') 179 alias->unit[sret - 1] = '\0'; 180 else 181 alias->unit[sret] = '\0'; 182 183 return 0; 184 error: 185 close(fd); 186 alias->unit[0] = '\0'; 187 return -1; 188 } 189 190 static int 191 perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name) 192 { 193 char path[PATH_MAX]; 194 int fd; 195 196 snprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name); 197 198 fd = open(path, O_RDONLY); 199 if (fd == -1) 200 return -1; 201 202 close(fd); 203 204 alias->per_pkg = true; 205 return 0; 206 } 207 208 static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias, 209 char *dir, char *name) 210 { 211 char path[PATH_MAX]; 212 int fd; 213 214 snprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name); 215 216 fd = open(path, O_RDONLY); 217 if (fd == -1) 218 return -1; 219 220 alias->snapshot = true; 221 close(fd); 222 return 0; 223 } 224 225 static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, 226 char *desc, char *val, char *long_desc, 227 char *topic) 228 { 229 struct perf_pmu_alias *alias; 230 int ret; 231 232 alias = malloc(sizeof(*alias)); 233 if (!alias) 234 return -ENOMEM; 235 236 INIT_LIST_HEAD(&alias->terms); 237 alias->scale = 1.0; 238 alias->unit[0] = '\0'; 239 alias->per_pkg = false; 240 alias->snapshot = false; 241 242 ret = parse_events_terms(&alias->terms, val); 243 if (ret) { 244 pr_err("Cannot parse alias %s: %d\n", val, ret); 245 free(alias); 246 return ret; 247 } 248 249 alias->name = strdup(name); 250 if (dir) { 251 /* 252 * load unit name and scale if available 253 */ 254 perf_pmu__parse_unit(alias, dir, name); 255 perf_pmu__parse_scale(alias, dir, name); 256 perf_pmu__parse_per_pkg(alias, dir, name); 257 perf_pmu__parse_snapshot(alias, dir, name); 258 } 259 260 alias->desc = desc ? strdup(desc) : NULL; 261 alias->long_desc = long_desc ? strdup(long_desc) : 262 desc ? strdup(desc) : NULL; 263 alias->topic = topic ? strdup(topic) : NULL; 264 265 list_add_tail(&alias->list, list); 266 267 return 0; 268 } 269 270 static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) 271 { 272 char buf[256]; 273 int ret; 274 275 ret = fread(buf, 1, sizeof(buf), file); 276 if (ret == 0) 277 return -EINVAL; 278 279 buf[ret] = 0; 280 281 return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL); 282 } 283 284 static inline bool pmu_alias_info_file(char *name) 285 { 286 size_t len; 287 288 len = strlen(name); 289 if (len > 5 && !strcmp(name + len - 5, ".unit")) 290 return true; 291 if (len > 6 && !strcmp(name + len - 6, ".scale")) 292 return true; 293 if (len > 8 && !strcmp(name + len - 8, ".per-pkg")) 294 return true; 295 if (len > 9 && !strcmp(name + len - 9, ".snapshot")) 296 return true; 297 298 return false; 299 } 300 301 /* 302 * Process all the sysfs attributes located under the directory 303 * specified in 'dir' parameter. 304 */ 305 static int pmu_aliases_parse(char *dir, struct list_head *head) 306 { 307 struct dirent *evt_ent; 308 DIR *event_dir; 309 310 event_dir = opendir(dir); 311 if (!event_dir) 312 return -EINVAL; 313 314 while ((evt_ent = readdir(event_dir))) { 315 char path[PATH_MAX]; 316 char *name = evt_ent->d_name; 317 FILE *file; 318 319 if (!strcmp(name, ".") || !strcmp(name, "..")) 320 continue; 321 322 /* 323 * skip info files parsed in perf_pmu__new_alias() 324 */ 325 if (pmu_alias_info_file(name)) 326 continue; 327 328 snprintf(path, PATH_MAX, "%s/%s", dir, name); 329 330 file = fopen(path, "r"); 331 if (!file) { 332 pr_debug("Cannot open %s\n", path); 333 continue; 334 } 335 336 if (perf_pmu__new_alias(head, dir, name, file) < 0) 337 pr_debug("Cannot set up %s\n", name); 338 fclose(file); 339 } 340 341 closedir(event_dir); 342 return 0; 343 } 344 345 /* 346 * Reading the pmu event aliases definition, which should be located at: 347 * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes. 348 */ 349 static int pmu_aliases(const char *name, struct list_head *head) 350 { 351 struct stat st; 352 char path[PATH_MAX]; 353 const char *sysfs = sysfs__mountpoint(); 354 355 if (!sysfs) 356 return -1; 357 358 snprintf(path, PATH_MAX, 359 "%s/bus/event_source/devices/%s/events", sysfs, name); 360 361 if (stat(path, &st) < 0) 362 return 0; /* no error if 'events' does not exist */ 363 364 if (pmu_aliases_parse(path, head)) 365 return -1; 366 367 return 0; 368 } 369 370 static int pmu_alias_terms(struct perf_pmu_alias *alias, 371 struct list_head *terms) 372 { 373 struct parse_events_term *term, *cloned; 374 LIST_HEAD(list); 375 int ret; 376 377 list_for_each_entry(term, &alias->terms, list) { 378 ret = parse_events_term__clone(&cloned, term); 379 if (ret) { 380 parse_events_terms__purge(&list); 381 return ret; 382 } 383 list_add_tail(&cloned->list, &list); 384 } 385 list_splice(&list, terms); 386 return 0; 387 } 388 389 /* 390 * Reading/parsing the default pmu type value, which should be 391 * located at: 392 * /sys/bus/event_source/devices/<dev>/type as sysfs attribute. 393 */ 394 static int pmu_type(const char *name, __u32 *type) 395 { 396 struct stat st; 397 char path[PATH_MAX]; 398 FILE *file; 399 int ret = 0; 400 const char *sysfs = sysfs__mountpoint(); 401 402 if (!sysfs) 403 return -1; 404 405 snprintf(path, PATH_MAX, 406 "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name); 407 408 if (stat(path, &st) < 0) 409 return -1; 410 411 file = fopen(path, "r"); 412 if (!file) 413 return -EINVAL; 414 415 if (1 != fscanf(file, "%u", type)) 416 ret = -1; 417 418 fclose(file); 419 return ret; 420 } 421 422 /* Add all pmus in sysfs to pmu list: */ 423 static void pmu_read_sysfs(void) 424 { 425 char path[PATH_MAX]; 426 DIR *dir; 427 struct dirent *dent; 428 const char *sysfs = sysfs__mountpoint(); 429 430 if (!sysfs) 431 return; 432 433 snprintf(path, PATH_MAX, 434 "%s" EVENT_SOURCE_DEVICE_PATH, sysfs); 435 436 dir = opendir(path); 437 if (!dir) 438 return; 439 440 while ((dent = readdir(dir))) { 441 if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) 442 continue; 443 /* add to static LIST_HEAD(pmus): */ 444 perf_pmu__find(dent->d_name); 445 } 446 447 closedir(dir); 448 } 449 450 static struct cpu_map *pmu_cpumask(const char *name) 451 { 452 struct stat st; 453 char path[PATH_MAX]; 454 FILE *file; 455 struct cpu_map *cpus; 456 const char *sysfs = sysfs__mountpoint(); 457 const char *templates[] = { 458 "%s/bus/event_source/devices/%s/cpumask", 459 "%s/bus/event_source/devices/%s/cpus", 460 NULL 461 }; 462 const char **template; 463 464 if (!sysfs) 465 return NULL; 466 467 for (template = templates; *template; template++) { 468 snprintf(path, PATH_MAX, *template, sysfs, name); 469 if (stat(path, &st) == 0) 470 break; 471 } 472 473 if (!*template) 474 return NULL; 475 476 file = fopen(path, "r"); 477 if (!file) 478 return NULL; 479 480 cpus = cpu_map__read(file); 481 fclose(file); 482 return cpus; 483 } 484 485 /* 486 * Return the CPU id as a raw string. 487 * 488 * Each architecture should provide a more precise id string that 489 * can be use to match the architecture's "mapfile". 490 */ 491 char * __weak get_cpuid_str(void) 492 { 493 return NULL; 494 } 495 496 /* 497 * From the pmu_events_map, find the table of PMU events that corresponds 498 * to the current running CPU. Then, add all PMU events from that table 499 * as aliases. 500 */ 501 static void pmu_add_cpu_aliases(struct list_head *head) 502 { 503 int i; 504 struct pmu_events_map *map; 505 struct pmu_event *pe; 506 char *cpuid; 507 508 cpuid = getenv("PERF_CPUID"); 509 if (cpuid) 510 cpuid = strdup(cpuid); 511 if (!cpuid) 512 cpuid = get_cpuid_str(); 513 if (!cpuid) 514 return; 515 516 pr_debug("Using CPUID %s\n", cpuid); 517 518 i = 0; 519 while (1) { 520 map = &pmu_events_map[i++]; 521 if (!map->table) 522 goto out; 523 524 if (!strcmp(map->cpuid, cpuid)) 525 break; 526 } 527 528 /* 529 * Found a matching PMU events table. Create aliases 530 */ 531 i = 0; 532 while (1) { 533 pe = &map->table[i++]; 534 if (!pe->name) 535 break; 536 537 /* need type casts to override 'const' */ 538 __perf_pmu__new_alias(head, NULL, (char *)pe->name, 539 (char *)pe->desc, (char *)pe->event, 540 (char *)pe->long_desc, (char *)pe->topic); 541 } 542 543 out: 544 free(cpuid); 545 } 546 547 struct perf_event_attr * __weak 548 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused) 549 { 550 return NULL; 551 } 552 553 static struct perf_pmu *pmu_lookup(const char *name) 554 { 555 struct perf_pmu *pmu; 556 LIST_HEAD(format); 557 LIST_HEAD(aliases); 558 __u32 type; 559 560 /* 561 * The pmu data we store & need consists of the pmu 562 * type value and format definitions. Load both right 563 * now. 564 */ 565 if (pmu_format(name, &format)) 566 return NULL; 567 568 if (pmu_aliases(name, &aliases)) 569 return NULL; 570 571 if (!strcmp(name, "cpu")) 572 pmu_add_cpu_aliases(&aliases); 573 574 if (pmu_type(name, &type)) 575 return NULL; 576 577 pmu = zalloc(sizeof(*pmu)); 578 if (!pmu) 579 return NULL; 580 581 pmu->cpus = pmu_cpumask(name); 582 583 INIT_LIST_HEAD(&pmu->format); 584 INIT_LIST_HEAD(&pmu->aliases); 585 list_splice(&format, &pmu->format); 586 list_splice(&aliases, &pmu->aliases); 587 pmu->name = strdup(name); 588 pmu->type = type; 589 list_add_tail(&pmu->list, &pmus); 590 591 pmu->default_config = perf_pmu__get_default_config(pmu); 592 593 return pmu; 594 } 595 596 static struct perf_pmu *pmu_find(const char *name) 597 { 598 struct perf_pmu *pmu; 599 600 list_for_each_entry(pmu, &pmus, list) 601 if (!strcmp(pmu->name, name)) 602 return pmu; 603 604 return NULL; 605 } 606 607 struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) 608 { 609 /* 610 * pmu iterator: If pmu is NULL, we start at the begin, 611 * otherwise return the next pmu. Returns NULL on end. 612 */ 613 if (!pmu) { 614 pmu_read_sysfs(); 615 pmu = list_prepare_entry(pmu, &pmus, list); 616 } 617 list_for_each_entry_continue(pmu, &pmus, list) 618 return pmu; 619 return NULL; 620 } 621 622 struct perf_pmu *perf_pmu__find(const char *name) 623 { 624 struct perf_pmu *pmu; 625 626 /* 627 * Once PMU is loaded it stays in the list, 628 * so we keep us from multiple reading/parsing 629 * the pmu format definitions. 630 */ 631 pmu = pmu_find(name); 632 if (pmu) 633 return pmu; 634 635 return pmu_lookup(name); 636 } 637 638 static struct perf_pmu_format * 639 pmu_find_format(struct list_head *formats, const char *name) 640 { 641 struct perf_pmu_format *format; 642 643 list_for_each_entry(format, formats, list) 644 if (!strcmp(format->name, name)) 645 return format; 646 647 return NULL; 648 } 649 650 __u64 perf_pmu__format_bits(struct list_head *formats, const char *name) 651 { 652 struct perf_pmu_format *format = pmu_find_format(formats, name); 653 __u64 bits = 0; 654 int fbit; 655 656 if (!format) 657 return 0; 658 659 for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS) 660 bits |= 1ULL << fbit; 661 662 return bits; 663 } 664 665 /* 666 * Sets value based on the format definition (format parameter) 667 * and unformated value (value parameter). 668 */ 669 static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v, 670 bool zero) 671 { 672 unsigned long fbit, vbit; 673 674 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) { 675 676 if (!test_bit(fbit, format)) 677 continue; 678 679 if (value & (1llu << vbit++)) 680 *v |= (1llu << fbit); 681 else if (zero) 682 *v &= ~(1llu << fbit); 683 } 684 } 685 686 static __u64 pmu_format_max_value(const unsigned long *format) 687 { 688 __u64 w = 0; 689 int fbit; 690 691 for_each_set_bit(fbit, format, PERF_PMU_FORMAT_BITS) 692 w |= (1ULL << fbit); 693 694 return w; 695 } 696 697 /* 698 * Term is a string term, and might be a param-term. Try to look up it's value 699 * in the remaining terms. 700 * - We have a term like "base-or-format-term=param-term", 701 * - We need to find the value supplied for "param-term" (with param-term named 702 * in a config string) later on in the term list. 703 */ 704 static int pmu_resolve_param_term(struct parse_events_term *term, 705 struct list_head *head_terms, 706 __u64 *value) 707 { 708 struct parse_events_term *t; 709 710 list_for_each_entry(t, head_terms, list) { 711 if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { 712 if (!strcmp(t->config, term->config)) { 713 t->used = true; 714 *value = t->val.num; 715 return 0; 716 } 717 } 718 } 719 720 if (verbose) 721 printf("Required parameter '%s' not specified\n", term->config); 722 723 return -1; 724 } 725 726 static char *pmu_formats_string(struct list_head *formats) 727 { 728 struct perf_pmu_format *format; 729 char *str = NULL; 730 struct strbuf buf = STRBUF_INIT; 731 unsigned i = 0; 732 733 if (!formats) 734 return NULL; 735 736 /* sysfs exported terms */ 737 list_for_each_entry(format, formats, list) 738 if (strbuf_addf(&buf, i++ ? ",%s" : "%s", format->name) < 0) 739 goto error; 740 741 str = strbuf_detach(&buf, NULL); 742 error: 743 strbuf_release(&buf); 744 745 return str; 746 } 747 748 /* 749 * Setup one of config[12] attr members based on the 750 * user input data - term parameter. 751 */ 752 static int pmu_config_term(struct list_head *formats, 753 struct perf_event_attr *attr, 754 struct parse_events_term *term, 755 struct list_head *head_terms, 756 bool zero, struct parse_events_error *err) 757 { 758 struct perf_pmu_format *format; 759 __u64 *vp; 760 __u64 val, max_val; 761 762 /* 763 * If this is a parameter we've already used for parameterized-eval, 764 * skip it in normal eval. 765 */ 766 if (term->used) 767 return 0; 768 769 /* 770 * Hardcoded terms should be already in, so nothing 771 * to be done for them. 772 */ 773 if (parse_events__is_hardcoded_term(term)) 774 return 0; 775 776 format = pmu_find_format(formats, term->config); 777 if (!format) { 778 if (verbose) 779 printf("Invalid event/parameter '%s'\n", term->config); 780 if (err) { 781 char *pmu_term = pmu_formats_string(formats); 782 783 err->idx = term->err_term; 784 err->str = strdup("unknown term"); 785 err->help = parse_events_formats_error_string(pmu_term); 786 free(pmu_term); 787 } 788 return -EINVAL; 789 } 790 791 switch (format->value) { 792 case PERF_PMU_FORMAT_VALUE_CONFIG: 793 vp = &attr->config; 794 break; 795 case PERF_PMU_FORMAT_VALUE_CONFIG1: 796 vp = &attr->config1; 797 break; 798 case PERF_PMU_FORMAT_VALUE_CONFIG2: 799 vp = &attr->config2; 800 break; 801 default: 802 return -EINVAL; 803 } 804 805 /* 806 * Either directly use a numeric term, or try to translate string terms 807 * using event parameters. 808 */ 809 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) 810 val = term->val.num; 811 else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 812 if (strcmp(term->val.str, "?")) { 813 if (verbose) { 814 pr_info("Invalid sysfs entry %s=%s\n", 815 term->config, term->val.str); 816 } 817 if (err) { 818 err->idx = term->err_val; 819 err->str = strdup("expected numeric value"); 820 } 821 return -EINVAL; 822 } 823 824 if (pmu_resolve_param_term(term, head_terms, &val)) 825 return -EINVAL; 826 } else 827 return -EINVAL; 828 829 max_val = pmu_format_max_value(format->bits); 830 if (val > max_val) { 831 if (err) { 832 err->idx = term->err_val; 833 if (asprintf(&err->str, 834 "value too big for format, maximum is %llu", 835 (unsigned long long)max_val) < 0) 836 err->str = strdup("value too big for format"); 837 return -EINVAL; 838 } 839 /* 840 * Assume we don't care if !err, in which case the value will be 841 * silently truncated. 842 */ 843 } 844 845 pmu_format_value(format->bits, val, vp, zero); 846 return 0; 847 } 848 849 int perf_pmu__config_terms(struct list_head *formats, 850 struct perf_event_attr *attr, 851 struct list_head *head_terms, 852 bool zero, struct parse_events_error *err) 853 { 854 struct parse_events_term *term; 855 856 list_for_each_entry(term, head_terms, list) { 857 if (pmu_config_term(formats, attr, term, head_terms, 858 zero, err)) 859 return -EINVAL; 860 } 861 862 return 0; 863 } 864 865 /* 866 * Configures event's 'attr' parameter based on the: 867 * 1) users input - specified in terms parameter 868 * 2) pmu format definitions - specified by pmu parameter 869 */ 870 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, 871 struct list_head *head_terms, 872 struct parse_events_error *err) 873 { 874 bool zero = !!pmu->default_config; 875 876 attr->type = pmu->type; 877 return perf_pmu__config_terms(&pmu->format, attr, head_terms, 878 zero, err); 879 } 880 881 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, 882 struct parse_events_term *term) 883 { 884 struct perf_pmu_alias *alias; 885 char *name; 886 887 if (parse_events__is_hardcoded_term(term)) 888 return NULL; 889 890 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { 891 if (term->val.num != 1) 892 return NULL; 893 if (pmu_find_format(&pmu->format, term->config)) 894 return NULL; 895 name = term->config; 896 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 897 if (strcasecmp(term->config, "event")) 898 return NULL; 899 name = term->val.str; 900 } else { 901 return NULL; 902 } 903 904 list_for_each_entry(alias, &pmu->aliases, list) { 905 if (!strcasecmp(alias->name, name)) 906 return alias; 907 } 908 return NULL; 909 } 910 911 912 static int check_info_data(struct perf_pmu_alias *alias, 913 struct perf_pmu_info *info) 914 { 915 /* 916 * Only one term in event definition can 917 * define unit, scale and snapshot, fail 918 * if there's more than one. 919 */ 920 if ((info->unit && alias->unit) || 921 (info->scale && alias->scale) || 922 (info->snapshot && alias->snapshot)) 923 return -EINVAL; 924 925 if (alias->unit) 926 info->unit = alias->unit; 927 928 if (alias->scale) 929 info->scale = alias->scale; 930 931 if (alias->snapshot) 932 info->snapshot = alias->snapshot; 933 934 return 0; 935 } 936 937 /* 938 * Find alias in the terms list and replace it with the terms 939 * defined for the alias 940 */ 941 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, 942 struct perf_pmu_info *info) 943 { 944 struct parse_events_term *term, *h; 945 struct perf_pmu_alias *alias; 946 int ret; 947 948 info->per_pkg = false; 949 950 /* 951 * Mark unit and scale as not set 952 * (different from default values, see below) 953 */ 954 info->unit = NULL; 955 info->scale = 0.0; 956 info->snapshot = false; 957 958 list_for_each_entry_safe(term, h, head_terms, list) { 959 alias = pmu_find_alias(pmu, term); 960 if (!alias) 961 continue; 962 ret = pmu_alias_terms(alias, &term->list); 963 if (ret) 964 return ret; 965 966 ret = check_info_data(alias, info); 967 if (ret) 968 return ret; 969 970 if (alias->per_pkg) 971 info->per_pkg = true; 972 973 list_del(&term->list); 974 free(term); 975 } 976 977 /* 978 * if no unit or scale foundin aliases, then 979 * set defaults as for evsel 980 * unit cannot left to NULL 981 */ 982 if (info->unit == NULL) 983 info->unit = ""; 984 985 if (info->scale == 0.0) 986 info->scale = 1.0; 987 988 return 0; 989 } 990 991 int perf_pmu__new_format(struct list_head *list, char *name, 992 int config, unsigned long *bits) 993 { 994 struct perf_pmu_format *format; 995 996 format = zalloc(sizeof(*format)); 997 if (!format) 998 return -ENOMEM; 999 1000 format->name = strdup(name); 1001 format->value = config; 1002 memcpy(format->bits, bits, sizeof(format->bits)); 1003 1004 list_add_tail(&format->list, list); 1005 return 0; 1006 } 1007 1008 void perf_pmu__set_format(unsigned long *bits, long from, long to) 1009 { 1010 long b; 1011 1012 if (!to) 1013 to = from; 1014 1015 memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS)); 1016 for (b = from; b <= to; b++) 1017 set_bit(b, bits); 1018 } 1019 1020 static int sub_non_neg(int a, int b) 1021 { 1022 if (b > a) 1023 return 0; 1024 return a - b; 1025 } 1026 1027 static char *format_alias(char *buf, int len, struct perf_pmu *pmu, 1028 struct perf_pmu_alias *alias) 1029 { 1030 struct parse_events_term *term; 1031 int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name); 1032 1033 list_for_each_entry(term, &alias->terms, list) { 1034 if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) 1035 used += snprintf(buf + used, sub_non_neg(len, used), 1036 ",%s=%s", term->config, 1037 term->val.str); 1038 } 1039 1040 if (sub_non_neg(len, used) > 0) { 1041 buf[used] = '/'; 1042 used++; 1043 } 1044 if (sub_non_neg(len, used) > 0) { 1045 buf[used] = '\0'; 1046 used++; 1047 } else 1048 buf[len - 1] = '\0'; 1049 1050 return buf; 1051 } 1052 1053 static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, 1054 struct perf_pmu_alias *alias) 1055 { 1056 snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name); 1057 return buf; 1058 } 1059 1060 struct sevent { 1061 char *name; 1062 char *desc; 1063 char *topic; 1064 }; 1065 1066 static int cmp_sevent(const void *a, const void *b) 1067 { 1068 const struct sevent *as = a; 1069 const struct sevent *bs = b; 1070 1071 /* Put extra events last */ 1072 if (!!as->desc != !!bs->desc) 1073 return !!as->desc - !!bs->desc; 1074 if (as->topic && bs->topic) { 1075 int n = strcmp(as->topic, bs->topic); 1076 1077 if (n) 1078 return n; 1079 } 1080 return strcmp(as->name, bs->name); 1081 } 1082 1083 static void wordwrap(char *s, int start, int max, int corr) 1084 { 1085 int column = start; 1086 int n; 1087 1088 while (*s) { 1089 int wlen = strcspn(s, " \t"); 1090 1091 if (column + wlen >= max && column > start) { 1092 printf("\n%*s", start, ""); 1093 column = start + corr; 1094 } 1095 n = printf("%s%.*s", column > start ? " " : "", wlen, s); 1096 if (n <= 0) 1097 break; 1098 s += wlen; 1099 column += n; 1100 while (isspace(*s)) 1101 s++; 1102 } 1103 } 1104 1105 void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, 1106 bool long_desc) 1107 { 1108 struct perf_pmu *pmu; 1109 struct perf_pmu_alias *alias; 1110 char buf[1024]; 1111 int printed = 0; 1112 int len, j; 1113 struct sevent *aliases; 1114 int numdesc = 0; 1115 int columns = pager_get_columns(); 1116 char *topic = NULL; 1117 1118 pmu = NULL; 1119 len = 0; 1120 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 1121 list_for_each_entry(alias, &pmu->aliases, list) 1122 len++; 1123 if (pmu->selectable) 1124 len++; 1125 } 1126 aliases = zalloc(sizeof(struct sevent) * len); 1127 if (!aliases) 1128 goto out_enomem; 1129 pmu = NULL; 1130 j = 0; 1131 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 1132 list_for_each_entry(alias, &pmu->aliases, list) { 1133 char *name = alias->desc ? alias->name : 1134 format_alias(buf, sizeof(buf), pmu, alias); 1135 bool is_cpu = !strcmp(pmu->name, "cpu"); 1136 1137 if (event_glob != NULL && 1138 !(strglobmatch(name, event_glob) || 1139 (!is_cpu && strglobmatch(alias->name, 1140 event_glob)))) 1141 continue; 1142 1143 if (is_cpu && !name_only && !alias->desc) 1144 name = format_alias_or(buf, sizeof(buf), pmu, alias); 1145 1146 aliases[j].name = name; 1147 if (is_cpu && !name_only && !alias->desc) 1148 aliases[j].name = format_alias_or(buf, 1149 sizeof(buf), 1150 pmu, alias); 1151 aliases[j].name = strdup(aliases[j].name); 1152 if (!aliases[j].name) 1153 goto out_enomem; 1154 1155 aliases[j].desc = long_desc ? alias->long_desc : 1156 alias->desc; 1157 aliases[j].topic = alias->topic; 1158 j++; 1159 } 1160 if (pmu->selectable && 1161 (event_glob == NULL || strglobmatch(pmu->name, event_glob))) { 1162 char *s; 1163 if (asprintf(&s, "%s//", pmu->name) < 0) 1164 goto out_enomem; 1165 aliases[j].name = s; 1166 j++; 1167 } 1168 } 1169 len = j; 1170 qsort(aliases, len, sizeof(struct sevent), cmp_sevent); 1171 for (j = 0; j < len; j++) { 1172 if (name_only) { 1173 printf("%s ", aliases[j].name); 1174 continue; 1175 } 1176 if (aliases[j].desc && !quiet_flag) { 1177 if (numdesc++ == 0) 1178 printf("\n"); 1179 if (aliases[j].topic && (!topic || 1180 strcmp(topic, aliases[j].topic))) { 1181 printf("%s%s:\n", topic ? "\n" : "", 1182 aliases[j].topic); 1183 topic = aliases[j].topic; 1184 } 1185 printf(" %-50s\n", aliases[j].name); 1186 printf("%*s", 8, "["); 1187 wordwrap(aliases[j].desc, 8, columns, 0); 1188 printf("]\n"); 1189 } else 1190 printf(" %-50s [Kernel PMU event]\n", aliases[j].name); 1191 printed++; 1192 } 1193 if (printed && pager_in_use()) 1194 printf("\n"); 1195 out_free: 1196 for (j = 0; j < len; j++) 1197 zfree(&aliases[j].name); 1198 zfree(&aliases); 1199 return; 1200 1201 out_enomem: 1202 printf("FATAL: not enough memory to print PMU events\n"); 1203 if (aliases) 1204 goto out_free; 1205 } 1206 1207 bool pmu_have_event(const char *pname, const char *name) 1208 { 1209 struct perf_pmu *pmu; 1210 struct perf_pmu_alias *alias; 1211 1212 pmu = NULL; 1213 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 1214 if (strcmp(pname, pmu->name)) 1215 continue; 1216 list_for_each_entry(alias, &pmu->aliases, list) 1217 if (!strcmp(alias->name, name)) 1218 return true; 1219 } 1220 return false; 1221 } 1222 1223 static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name) 1224 { 1225 struct stat st; 1226 char path[PATH_MAX]; 1227 const char *sysfs; 1228 1229 sysfs = sysfs__mountpoint(); 1230 if (!sysfs) 1231 return NULL; 1232 1233 snprintf(path, PATH_MAX, 1234 "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name); 1235 1236 if (stat(path, &st) < 0) 1237 return NULL; 1238 1239 return fopen(path, "r"); 1240 } 1241 1242 int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, 1243 ...) 1244 { 1245 va_list args; 1246 FILE *file; 1247 int ret = EOF; 1248 1249 va_start(args, fmt); 1250 file = perf_pmu__open_file(pmu, name); 1251 if (file) { 1252 ret = vfscanf(file, fmt, args); 1253 fclose(file); 1254 } 1255 va_end(args); 1256 return ret; 1257 } 1258