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