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