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