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