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