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 449 if (!sysfs) 450 return NULL; 451 452 snprintf(path, PATH_MAX, 453 "%s/bus/event_source/devices/%s/cpumask", sysfs, name); 454 455 if (stat(path, &st) < 0) 456 return NULL; 457 458 file = fopen(path, "r"); 459 if (!file) 460 return NULL; 461 462 cpus = cpu_map__read(file); 463 fclose(file); 464 return cpus; 465 } 466 467 struct perf_event_attr * __weak 468 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused) 469 { 470 return NULL; 471 } 472 473 static struct perf_pmu *pmu_lookup(const char *name) 474 { 475 struct perf_pmu *pmu; 476 LIST_HEAD(format); 477 LIST_HEAD(aliases); 478 __u32 type; 479 480 /* 481 * The pmu data we store & need consists of the pmu 482 * type value and format definitions. Load both right 483 * now. 484 */ 485 if (pmu_format(name, &format)) 486 return NULL; 487 488 if (pmu_aliases(name, &aliases)) 489 return NULL; 490 491 if (pmu_type(name, &type)) 492 return NULL; 493 494 pmu = zalloc(sizeof(*pmu)); 495 if (!pmu) 496 return NULL; 497 498 pmu->cpus = pmu_cpumask(name); 499 500 INIT_LIST_HEAD(&pmu->format); 501 INIT_LIST_HEAD(&pmu->aliases); 502 list_splice(&format, &pmu->format); 503 list_splice(&aliases, &pmu->aliases); 504 pmu->name = strdup(name); 505 pmu->type = type; 506 list_add_tail(&pmu->list, &pmus); 507 508 pmu->default_config = perf_pmu__get_default_config(pmu); 509 510 return pmu; 511 } 512 513 static struct perf_pmu *pmu_find(const char *name) 514 { 515 struct perf_pmu *pmu; 516 517 list_for_each_entry(pmu, &pmus, list) 518 if (!strcmp(pmu->name, name)) 519 return pmu; 520 521 return NULL; 522 } 523 524 struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) 525 { 526 /* 527 * pmu iterator: If pmu is NULL, we start at the begin, 528 * otherwise return the next pmu. Returns NULL on end. 529 */ 530 if (!pmu) { 531 pmu_read_sysfs(); 532 pmu = list_prepare_entry(pmu, &pmus, list); 533 } 534 list_for_each_entry_continue(pmu, &pmus, list) 535 return pmu; 536 return NULL; 537 } 538 539 struct perf_pmu *perf_pmu__find(const char *name) 540 { 541 struct perf_pmu *pmu; 542 543 /* 544 * Once PMU is loaded it stays in the list, 545 * so we keep us from multiple reading/parsing 546 * the pmu format definitions. 547 */ 548 pmu = pmu_find(name); 549 if (pmu) 550 return pmu; 551 552 return pmu_lookup(name); 553 } 554 555 static struct perf_pmu_format * 556 pmu_find_format(struct list_head *formats, const char *name) 557 { 558 struct perf_pmu_format *format; 559 560 list_for_each_entry(format, formats, list) 561 if (!strcmp(format->name, name)) 562 return format; 563 564 return NULL; 565 } 566 567 __u64 perf_pmu__format_bits(struct list_head *formats, const char *name) 568 { 569 struct perf_pmu_format *format = pmu_find_format(formats, name); 570 __u64 bits = 0; 571 int fbit; 572 573 if (!format) 574 return 0; 575 576 for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS) 577 bits |= 1ULL << fbit; 578 579 return bits; 580 } 581 582 /* 583 * Sets value based on the format definition (format parameter) 584 * and unformated value (value parameter). 585 */ 586 static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v, 587 bool zero) 588 { 589 unsigned long fbit, vbit; 590 591 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) { 592 593 if (!test_bit(fbit, format)) 594 continue; 595 596 if (value & (1llu << vbit++)) 597 *v |= (1llu << fbit); 598 else if (zero) 599 *v &= ~(1llu << fbit); 600 } 601 } 602 603 static __u64 pmu_format_max_value(const unsigned long *format) 604 { 605 int w; 606 607 w = bitmap_weight(format, PERF_PMU_FORMAT_BITS); 608 if (!w) 609 return 0; 610 if (w < 64) 611 return (1ULL << w) - 1; 612 return -1; 613 } 614 615 /* 616 * Term is a string term, and might be a param-term. Try to look up it's value 617 * in the remaining terms. 618 * - We have a term like "base-or-format-term=param-term", 619 * - We need to find the value supplied for "param-term" (with param-term named 620 * in a config string) later on in the term list. 621 */ 622 static int pmu_resolve_param_term(struct parse_events_term *term, 623 struct list_head *head_terms, 624 __u64 *value) 625 { 626 struct parse_events_term *t; 627 628 list_for_each_entry(t, head_terms, list) { 629 if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { 630 if (!strcmp(t->config, term->config)) { 631 t->used = true; 632 *value = t->val.num; 633 return 0; 634 } 635 } 636 } 637 638 if (verbose) 639 printf("Required parameter '%s' not specified\n", term->config); 640 641 return -1; 642 } 643 644 static char *pmu_formats_string(struct list_head *formats) 645 { 646 struct perf_pmu_format *format; 647 char *str; 648 struct strbuf buf; 649 unsigned i = 0; 650 651 if (!formats) 652 return NULL; 653 654 strbuf_init(&buf, 0); 655 /* sysfs exported terms */ 656 list_for_each_entry(format, formats, list) 657 strbuf_addf(&buf, i++ ? ",%s" : "%s", 658 format->name); 659 660 str = strbuf_detach(&buf, NULL); 661 strbuf_release(&buf); 662 663 return str; 664 } 665 666 /* 667 * Setup one of config[12] attr members based on the 668 * user input data - term parameter. 669 */ 670 static int pmu_config_term(struct list_head *formats, 671 struct perf_event_attr *attr, 672 struct parse_events_term *term, 673 struct list_head *head_terms, 674 bool zero, struct parse_events_error *err) 675 { 676 struct perf_pmu_format *format; 677 __u64 *vp; 678 __u64 val, max_val; 679 680 /* 681 * If this is a parameter we've already used for parameterized-eval, 682 * skip it in normal eval. 683 */ 684 if (term->used) 685 return 0; 686 687 /* 688 * Hardcoded terms should be already in, so nothing 689 * to be done for them. 690 */ 691 if (parse_events__is_hardcoded_term(term)) 692 return 0; 693 694 format = pmu_find_format(formats, term->config); 695 if (!format) { 696 if (verbose) 697 printf("Invalid event/parameter '%s'\n", term->config); 698 if (err) { 699 char *pmu_term = pmu_formats_string(formats); 700 701 err->idx = term->err_term; 702 err->str = strdup("unknown term"); 703 err->help = parse_events_formats_error_string(pmu_term); 704 free(pmu_term); 705 } 706 return -EINVAL; 707 } 708 709 switch (format->value) { 710 case PERF_PMU_FORMAT_VALUE_CONFIG: 711 vp = &attr->config; 712 break; 713 case PERF_PMU_FORMAT_VALUE_CONFIG1: 714 vp = &attr->config1; 715 break; 716 case PERF_PMU_FORMAT_VALUE_CONFIG2: 717 vp = &attr->config2; 718 break; 719 default: 720 return -EINVAL; 721 } 722 723 /* 724 * Either directly use a numeric term, or try to translate string terms 725 * using event parameters. 726 */ 727 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) 728 val = term->val.num; 729 else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 730 if (strcmp(term->val.str, "?")) { 731 if (verbose) { 732 pr_info("Invalid sysfs entry %s=%s\n", 733 term->config, term->val.str); 734 } 735 if (err) { 736 err->idx = term->err_val; 737 err->str = strdup("expected numeric value"); 738 } 739 return -EINVAL; 740 } 741 742 if (pmu_resolve_param_term(term, head_terms, &val)) 743 return -EINVAL; 744 } else 745 return -EINVAL; 746 747 max_val = pmu_format_max_value(format->bits); 748 if (val > max_val) { 749 if (err) { 750 err->idx = term->err_val; 751 if (asprintf(&err->str, 752 "value too big for format, maximum is %llu", 753 (unsigned long long)max_val) < 0) 754 err->str = strdup("value too big for format"); 755 return -EINVAL; 756 } 757 /* 758 * Assume we don't care if !err, in which case the value will be 759 * silently truncated. 760 */ 761 } 762 763 pmu_format_value(format->bits, val, vp, zero); 764 return 0; 765 } 766 767 int perf_pmu__config_terms(struct list_head *formats, 768 struct perf_event_attr *attr, 769 struct list_head *head_terms, 770 bool zero, struct parse_events_error *err) 771 { 772 struct parse_events_term *term; 773 774 list_for_each_entry(term, head_terms, list) { 775 if (pmu_config_term(formats, attr, term, head_terms, 776 zero, err)) 777 return -EINVAL; 778 } 779 780 return 0; 781 } 782 783 /* 784 * Configures event's 'attr' parameter based on the: 785 * 1) users input - specified in terms parameter 786 * 2) pmu format definitions - specified by pmu parameter 787 */ 788 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, 789 struct list_head *head_terms, 790 struct parse_events_error *err) 791 { 792 bool zero = !!pmu->default_config; 793 794 attr->type = pmu->type; 795 return perf_pmu__config_terms(&pmu->format, attr, head_terms, 796 zero, err); 797 } 798 799 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, 800 struct parse_events_term *term) 801 { 802 struct perf_pmu_alias *alias; 803 char *name; 804 805 if (parse_events__is_hardcoded_term(term)) 806 return NULL; 807 808 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { 809 if (term->val.num != 1) 810 return NULL; 811 if (pmu_find_format(&pmu->format, term->config)) 812 return NULL; 813 name = term->config; 814 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 815 if (strcasecmp(term->config, "event")) 816 return NULL; 817 name = term->val.str; 818 } else { 819 return NULL; 820 } 821 822 list_for_each_entry(alias, &pmu->aliases, list) { 823 if (!strcasecmp(alias->name, name)) 824 return alias; 825 } 826 return NULL; 827 } 828 829 830 static int check_info_data(struct perf_pmu_alias *alias, 831 struct perf_pmu_info *info) 832 { 833 /* 834 * Only one term in event definition can 835 * define unit, scale and snapshot, fail 836 * if there's more than one. 837 */ 838 if ((info->unit && alias->unit) || 839 (info->scale && alias->scale) || 840 (info->snapshot && alias->snapshot)) 841 return -EINVAL; 842 843 if (alias->unit) 844 info->unit = alias->unit; 845 846 if (alias->scale) 847 info->scale = alias->scale; 848 849 if (alias->snapshot) 850 info->snapshot = alias->snapshot; 851 852 return 0; 853 } 854 855 /* 856 * Find alias in the terms list and replace it with the terms 857 * defined for the alias 858 */ 859 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, 860 struct perf_pmu_info *info) 861 { 862 struct parse_events_term *term, *h; 863 struct perf_pmu_alias *alias; 864 int ret; 865 866 info->per_pkg = false; 867 868 /* 869 * Mark unit and scale as not set 870 * (different from default values, see below) 871 */ 872 info->unit = NULL; 873 info->scale = 0.0; 874 info->snapshot = false; 875 876 list_for_each_entry_safe(term, h, head_terms, list) { 877 alias = pmu_find_alias(pmu, term); 878 if (!alias) 879 continue; 880 ret = pmu_alias_terms(alias, &term->list); 881 if (ret) 882 return ret; 883 884 ret = check_info_data(alias, info); 885 if (ret) 886 return ret; 887 888 if (alias->per_pkg) 889 info->per_pkg = true; 890 891 list_del(&term->list); 892 free(term); 893 } 894 895 /* 896 * if no unit or scale foundin aliases, then 897 * set defaults as for evsel 898 * unit cannot left to NULL 899 */ 900 if (info->unit == NULL) 901 info->unit = ""; 902 903 if (info->scale == 0.0) 904 info->scale = 1.0; 905 906 return 0; 907 } 908 909 int perf_pmu__new_format(struct list_head *list, char *name, 910 int config, unsigned long *bits) 911 { 912 struct perf_pmu_format *format; 913 914 format = zalloc(sizeof(*format)); 915 if (!format) 916 return -ENOMEM; 917 918 format->name = strdup(name); 919 format->value = config; 920 memcpy(format->bits, bits, sizeof(format->bits)); 921 922 list_add_tail(&format->list, list); 923 return 0; 924 } 925 926 void perf_pmu__set_format(unsigned long *bits, long from, long to) 927 { 928 long b; 929 930 if (!to) 931 to = from; 932 933 memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS)); 934 for (b = from; b <= to; b++) 935 set_bit(b, bits); 936 } 937 938 static int sub_non_neg(int a, int b) 939 { 940 if (b > a) 941 return 0; 942 return a - b; 943 } 944 945 static char *format_alias(char *buf, int len, struct perf_pmu *pmu, 946 struct perf_pmu_alias *alias) 947 { 948 struct parse_events_term *term; 949 int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name); 950 951 list_for_each_entry(term, &alias->terms, list) { 952 if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) 953 used += snprintf(buf + used, sub_non_neg(len, used), 954 ",%s=%s", term->config, 955 term->val.str); 956 } 957 958 if (sub_non_neg(len, used) > 0) { 959 buf[used] = '/'; 960 used++; 961 } 962 if (sub_non_neg(len, used) > 0) { 963 buf[used] = '\0'; 964 used++; 965 } else 966 buf[len - 1] = '\0'; 967 968 return buf; 969 } 970 971 static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, 972 struct perf_pmu_alias *alias) 973 { 974 snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name); 975 return buf; 976 } 977 978 static int cmp_string(const void *a, const void *b) 979 { 980 const char * const *as = a; 981 const char * const *bs = b; 982 return strcmp(*as, *bs); 983 } 984 985 void print_pmu_events(const char *event_glob, bool name_only) 986 { 987 struct perf_pmu *pmu; 988 struct perf_pmu_alias *alias; 989 char buf[1024]; 990 int printed = 0; 991 int len, j; 992 char **aliases; 993 994 pmu = NULL; 995 len = 0; 996 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 997 list_for_each_entry(alias, &pmu->aliases, list) 998 len++; 999 if (pmu->selectable) 1000 len++; 1001 } 1002 aliases = zalloc(sizeof(char *) * len); 1003 if (!aliases) 1004 goto out_enomem; 1005 pmu = NULL; 1006 j = 0; 1007 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 1008 list_for_each_entry(alias, &pmu->aliases, list) { 1009 char *name = format_alias(buf, sizeof(buf), pmu, alias); 1010 bool is_cpu = !strcmp(pmu->name, "cpu"); 1011 1012 if (event_glob != NULL && 1013 !(strglobmatch(name, event_glob) || 1014 (!is_cpu && strglobmatch(alias->name, 1015 event_glob)))) 1016 continue; 1017 1018 if (is_cpu && !name_only) 1019 name = format_alias_or(buf, sizeof(buf), pmu, alias); 1020 1021 aliases[j] = strdup(name); 1022 if (aliases[j] == NULL) 1023 goto out_enomem; 1024 j++; 1025 } 1026 if (pmu->selectable && 1027 (event_glob == NULL || strglobmatch(pmu->name, event_glob))) { 1028 char *s; 1029 if (asprintf(&s, "%s//", pmu->name) < 0) 1030 goto out_enomem; 1031 aliases[j] = s; 1032 j++; 1033 } 1034 } 1035 len = j; 1036 qsort(aliases, len, sizeof(char *), cmp_string); 1037 for (j = 0; j < len; j++) { 1038 if (name_only) { 1039 printf("%s ", aliases[j]); 1040 continue; 1041 } 1042 printf(" %-50s [Kernel PMU event]\n", aliases[j]); 1043 printed++; 1044 } 1045 if (printed && pager_in_use()) 1046 printf("\n"); 1047 out_free: 1048 for (j = 0; j < len; j++) 1049 zfree(&aliases[j]); 1050 zfree(&aliases); 1051 return; 1052 1053 out_enomem: 1054 printf("FATAL: not enough memory to print PMU events\n"); 1055 if (aliases) 1056 goto out_free; 1057 } 1058 1059 bool pmu_have_event(const char *pname, const char *name) 1060 { 1061 struct perf_pmu *pmu; 1062 struct perf_pmu_alias *alias; 1063 1064 pmu = NULL; 1065 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 1066 if (strcmp(pname, pmu->name)) 1067 continue; 1068 list_for_each_entry(alias, &pmu->aliases, list) 1069 if (!strcmp(alias->name, name)) 1070 return true; 1071 } 1072 return false; 1073 } 1074 1075 static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name) 1076 { 1077 struct stat st; 1078 char path[PATH_MAX]; 1079 const char *sysfs; 1080 1081 sysfs = sysfs__mountpoint(); 1082 if (!sysfs) 1083 return NULL; 1084 1085 snprintf(path, PATH_MAX, 1086 "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name); 1087 1088 if (stat(path, &st) < 0) 1089 return NULL; 1090 1091 return fopen(path, "r"); 1092 } 1093 1094 int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, 1095 ...) 1096 { 1097 va_list args; 1098 FILE *file; 1099 int ret = EOF; 1100 1101 va_start(args, fmt); 1102 file = perf_pmu__open_file(pmu, name); 1103 if (file) { 1104 ret = vfscanf(file, fmt, args); 1105 fclose(file); 1106 } 1107 va_end(args); 1108 return ret; 1109 } 1110