1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/list.h> 3 #include <linux/compiler.h> 4 #include <linux/string.h> 5 #include <linux/zalloc.h> 6 #include <subcmd/pager.h> 7 #include <sys/types.h> 8 #include <errno.h> 9 #include <fcntl.h> 10 #include <sys/stat.h> 11 #include <unistd.h> 12 #include <stdio.h> 13 #include <stdbool.h> 14 #include <stdarg.h> 15 #include <dirent.h> 16 #include <api/fs/fs.h> 17 #include <locale.h> 18 #include <regex.h> 19 #include <perf/cpumap.h> 20 #include "debug.h" 21 #include "pmu.h" 22 #include "parse-events.h" 23 #include "cpumap.h" 24 #include "header.h" 25 #include "pmu-events/pmu-events.h" 26 #include "string2.h" 27 #include "strbuf.h" 28 29 struct perf_pmu_format { 30 char *name; 31 int value; 32 DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); 33 struct list_head list; 34 }; 35 36 int perf_pmu_parse(struct list_head *list, char *name); 37 extern FILE *perf_pmu_in; 38 39 static LIST_HEAD(pmus); 40 41 /* 42 * Parse & process all the sysfs attributes located under 43 * the directory specified in 'dir' parameter. 44 */ 45 int perf_pmu__format_parse(char *dir, struct list_head *head) 46 { 47 struct dirent *evt_ent; 48 DIR *format_dir; 49 int ret = 0; 50 51 format_dir = opendir(dir); 52 if (!format_dir) 53 return -EINVAL; 54 55 while (!ret && (evt_ent = readdir(format_dir))) { 56 char path[PATH_MAX]; 57 char *name = evt_ent->d_name; 58 FILE *file; 59 60 if (!strcmp(name, ".") || !strcmp(name, "..")) 61 continue; 62 63 snprintf(path, PATH_MAX, "%s/%s", dir, name); 64 65 ret = -EINVAL; 66 file = fopen(path, "r"); 67 if (!file) 68 break; 69 70 perf_pmu_in = file; 71 ret = perf_pmu_parse(head, name); 72 fclose(file); 73 } 74 75 closedir(format_dir); 76 return ret; 77 } 78 79 /* 80 * Reading/parsing the default pmu format definition, which should be 81 * located at: 82 * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes. 83 */ 84 static int pmu_format(const char *name, struct list_head *format) 85 { 86 struct stat st; 87 char path[PATH_MAX]; 88 const char *sysfs = sysfs__mountpoint(); 89 90 if (!sysfs) 91 return -1; 92 93 snprintf(path, PATH_MAX, 94 "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name); 95 96 if (stat(path, &st) < 0) 97 return 0; /* no error if format does not exist */ 98 99 if (perf_pmu__format_parse(path, format)) 100 return -1; 101 102 return 0; 103 } 104 105 int perf_pmu__convert_scale(const char *scale, char **end, double *sval) 106 { 107 char *lc; 108 int ret = 0; 109 110 /* 111 * save current locale 112 */ 113 lc = setlocale(LC_NUMERIC, NULL); 114 115 /* 116 * The lc string may be allocated in static storage, 117 * so get a dynamic copy to make it survive setlocale 118 * call below. 119 */ 120 lc = strdup(lc); 121 if (!lc) { 122 ret = -ENOMEM; 123 goto out; 124 } 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 *sval = strtod(scale, end); 134 135 out: 136 /* restore locale */ 137 setlocale(LC_NUMERIC, lc); 138 free(lc); 139 return ret; 140 } 141 142 static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name) 143 { 144 struct stat st; 145 ssize_t sret; 146 char scale[128]; 147 int fd, ret = -1; 148 char path[PATH_MAX]; 149 150 scnprintf(path, PATH_MAX, "%s/%s.scale", dir, name); 151 152 fd = open(path, O_RDONLY); 153 if (fd == -1) 154 return -1; 155 156 if (fstat(fd, &st) < 0) 157 goto error; 158 159 sret = read(fd, scale, sizeof(scale)-1); 160 if (sret < 0) 161 goto error; 162 163 if (scale[sret - 1] == '\n') 164 scale[sret - 1] = '\0'; 165 else 166 scale[sret] = '\0'; 167 168 ret = perf_pmu__convert_scale(scale, NULL, &alias->scale); 169 error: 170 close(fd); 171 return ret; 172 } 173 174 static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name) 175 { 176 char path[PATH_MAX]; 177 ssize_t sret; 178 int fd; 179 180 scnprintf(path, PATH_MAX, "%s/%s.unit", dir, name); 181 182 fd = open(path, O_RDONLY); 183 if (fd == -1) 184 return -1; 185 186 sret = read(fd, alias->unit, UNIT_MAX_LEN); 187 if (sret < 0) 188 goto error; 189 190 close(fd); 191 192 if (alias->unit[sret - 1] == '\n') 193 alias->unit[sret - 1] = '\0'; 194 else 195 alias->unit[sret] = '\0'; 196 197 return 0; 198 error: 199 close(fd); 200 alias->unit[0] = '\0'; 201 return -1; 202 } 203 204 static int 205 perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name) 206 { 207 char path[PATH_MAX]; 208 int fd; 209 210 scnprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name); 211 212 fd = open(path, O_RDONLY); 213 if (fd == -1) 214 return -1; 215 216 close(fd); 217 218 alias->per_pkg = true; 219 return 0; 220 } 221 222 static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias, 223 char *dir, char *name) 224 { 225 char path[PATH_MAX]; 226 int fd; 227 228 scnprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name); 229 230 fd = open(path, O_RDONLY); 231 if (fd == -1) 232 return -1; 233 234 alias->snapshot = true; 235 close(fd); 236 return 0; 237 } 238 239 static void perf_pmu_assign_str(char *name, const char *field, char **old_str, 240 char **new_str) 241 { 242 if (!*old_str) 243 goto set_new; 244 245 if (*new_str) { /* Have new string, check with old */ 246 if (strcasecmp(*old_str, *new_str)) 247 pr_debug("alias %s differs in field '%s'\n", 248 name, field); 249 zfree(old_str); 250 } else /* Nothing new --> keep old string */ 251 return; 252 set_new: 253 *old_str = *new_str; 254 *new_str = NULL; 255 } 256 257 static void perf_pmu_update_alias(struct perf_pmu_alias *old, 258 struct perf_pmu_alias *newalias) 259 { 260 perf_pmu_assign_str(old->name, "desc", &old->desc, &newalias->desc); 261 perf_pmu_assign_str(old->name, "long_desc", &old->long_desc, 262 &newalias->long_desc); 263 perf_pmu_assign_str(old->name, "topic", &old->topic, &newalias->topic); 264 perf_pmu_assign_str(old->name, "metric_expr", &old->metric_expr, 265 &newalias->metric_expr); 266 perf_pmu_assign_str(old->name, "metric_name", &old->metric_name, 267 &newalias->metric_name); 268 perf_pmu_assign_str(old->name, "value", &old->str, &newalias->str); 269 old->scale = newalias->scale; 270 old->per_pkg = newalias->per_pkg; 271 old->snapshot = newalias->snapshot; 272 memcpy(old->unit, newalias->unit, sizeof(old->unit)); 273 } 274 275 /* Delete an alias entry. */ 276 static void perf_pmu_free_alias(struct perf_pmu_alias *newalias) 277 { 278 zfree(&newalias->name); 279 zfree(&newalias->desc); 280 zfree(&newalias->long_desc); 281 zfree(&newalias->topic); 282 zfree(&newalias->str); 283 zfree(&newalias->metric_expr); 284 zfree(&newalias->metric_name); 285 parse_events_terms__purge(&newalias->terms); 286 free(newalias); 287 } 288 289 /* Merge an alias, search in alias list. If this name is already 290 * present merge both of them to combine all information. 291 */ 292 static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias, 293 struct list_head *alist) 294 { 295 struct perf_pmu_alias *a; 296 297 list_for_each_entry(a, alist, list) { 298 if (!strcasecmp(newalias->name, a->name)) { 299 perf_pmu_update_alias(a, newalias); 300 perf_pmu_free_alias(newalias); 301 return true; 302 } 303 } 304 return false; 305 } 306 307 static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, 308 char *desc, char *val, 309 char *long_desc, char *topic, 310 char *unit, char *perpkg, 311 char *metric_expr, 312 char *metric_name) 313 { 314 struct parse_events_term *term; 315 struct perf_pmu_alias *alias; 316 int ret; 317 int num; 318 char newval[256]; 319 320 alias = malloc(sizeof(*alias)); 321 if (!alias) 322 return -ENOMEM; 323 324 INIT_LIST_HEAD(&alias->terms); 325 alias->scale = 1.0; 326 alias->unit[0] = '\0'; 327 alias->per_pkg = false; 328 alias->snapshot = false; 329 330 ret = parse_events_terms(&alias->terms, val); 331 if (ret) { 332 pr_err("Cannot parse alias %s: %d\n", val, ret); 333 free(alias); 334 return ret; 335 } 336 337 /* Scan event and remove leading zeroes, spaces, newlines, some 338 * platforms have terms specified as 339 * event=0x0091 (read from files ../<PMU>/events/<FILE> 340 * and terms specified as event=0x91 (read from JSON files). 341 * 342 * Rebuild string to make alias->str member comparable. 343 */ 344 memset(newval, 0, sizeof(newval)); 345 ret = 0; 346 list_for_each_entry(term, &alias->terms, list) { 347 if (ret) 348 ret += scnprintf(newval + ret, sizeof(newval) - ret, 349 ","); 350 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) 351 ret += scnprintf(newval + ret, sizeof(newval) - ret, 352 "%s=%#x", term->config, term->val.num); 353 else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) 354 ret += scnprintf(newval + ret, sizeof(newval) - ret, 355 "%s=%s", term->config, term->val.str); 356 } 357 358 alias->name = strdup(name); 359 if (dir) { 360 /* 361 * load unit name and scale if available 362 */ 363 perf_pmu__parse_unit(alias, dir, name); 364 perf_pmu__parse_scale(alias, dir, name); 365 perf_pmu__parse_per_pkg(alias, dir, name); 366 perf_pmu__parse_snapshot(alias, dir, name); 367 } 368 369 alias->metric_expr = metric_expr ? strdup(metric_expr) : NULL; 370 alias->metric_name = metric_name ? strdup(metric_name): NULL; 371 alias->desc = desc ? strdup(desc) : NULL; 372 alias->long_desc = long_desc ? strdup(long_desc) : 373 desc ? strdup(desc) : NULL; 374 alias->topic = topic ? strdup(topic) : NULL; 375 if (unit) { 376 if (perf_pmu__convert_scale(unit, &unit, &alias->scale) < 0) 377 return -1; 378 snprintf(alias->unit, sizeof(alias->unit), "%s", unit); 379 } 380 alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1; 381 alias->str = strdup(newval); 382 383 if (!perf_pmu_merge_alias(alias, list)) 384 list_add_tail(&alias->list, list); 385 386 return 0; 387 } 388 389 static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) 390 { 391 char buf[256]; 392 int ret; 393 394 ret = fread(buf, 1, sizeof(buf), file); 395 if (ret == 0) 396 return -EINVAL; 397 398 buf[ret] = 0; 399 400 /* Remove trailing newline from sysfs file */ 401 strim(buf); 402 403 return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL, 404 NULL, NULL, NULL); 405 } 406 407 static inline bool pmu_alias_info_file(char *name) 408 { 409 size_t len; 410 411 len = strlen(name); 412 if (len > 5 && !strcmp(name + len - 5, ".unit")) 413 return true; 414 if (len > 6 && !strcmp(name + len - 6, ".scale")) 415 return true; 416 if (len > 8 && !strcmp(name + len - 8, ".per-pkg")) 417 return true; 418 if (len > 9 && !strcmp(name + len - 9, ".snapshot")) 419 return true; 420 421 return false; 422 } 423 424 /* 425 * Process all the sysfs attributes located under the directory 426 * specified in 'dir' parameter. 427 */ 428 static int pmu_aliases_parse(char *dir, struct list_head *head) 429 { 430 struct dirent *evt_ent; 431 DIR *event_dir; 432 433 event_dir = opendir(dir); 434 if (!event_dir) 435 return -EINVAL; 436 437 while ((evt_ent = readdir(event_dir))) { 438 char path[PATH_MAX]; 439 char *name = evt_ent->d_name; 440 FILE *file; 441 442 if (!strcmp(name, ".") || !strcmp(name, "..")) 443 continue; 444 445 /* 446 * skip info files parsed in perf_pmu__new_alias() 447 */ 448 if (pmu_alias_info_file(name)) 449 continue; 450 451 scnprintf(path, PATH_MAX, "%s/%s", dir, name); 452 453 file = fopen(path, "r"); 454 if (!file) { 455 pr_debug("Cannot open %s\n", path); 456 continue; 457 } 458 459 if (perf_pmu__new_alias(head, dir, name, file) < 0) 460 pr_debug("Cannot set up %s\n", name); 461 fclose(file); 462 } 463 464 closedir(event_dir); 465 return 0; 466 } 467 468 /* 469 * Reading the pmu event aliases definition, which should be located at: 470 * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes. 471 */ 472 static int pmu_aliases(const char *name, struct list_head *head) 473 { 474 struct stat st; 475 char path[PATH_MAX]; 476 const char *sysfs = sysfs__mountpoint(); 477 478 if (!sysfs) 479 return -1; 480 481 snprintf(path, PATH_MAX, 482 "%s/bus/event_source/devices/%s/events", sysfs, name); 483 484 if (stat(path, &st) < 0) 485 return 0; /* no error if 'events' does not exist */ 486 487 if (pmu_aliases_parse(path, head)) 488 return -1; 489 490 return 0; 491 } 492 493 static int pmu_alias_terms(struct perf_pmu_alias *alias, 494 struct list_head *terms) 495 { 496 struct parse_events_term *term, *cloned; 497 LIST_HEAD(list); 498 int ret; 499 500 list_for_each_entry(term, &alias->terms, list) { 501 ret = parse_events_term__clone(&cloned, term); 502 if (ret) { 503 parse_events_terms__purge(&list); 504 return ret; 505 } 506 /* 507 * Weak terms don't override command line options, 508 * which we don't want for implicit terms in aliases. 509 */ 510 cloned->weak = true; 511 list_add_tail(&cloned->list, &list); 512 } 513 list_splice(&list, terms); 514 return 0; 515 } 516 517 /* 518 * Reading/parsing the default pmu type value, which should be 519 * located at: 520 * /sys/bus/event_source/devices/<dev>/type as sysfs attribute. 521 */ 522 static int pmu_type(const char *name, __u32 *type) 523 { 524 struct stat st; 525 char path[PATH_MAX]; 526 FILE *file; 527 int ret = 0; 528 const char *sysfs = sysfs__mountpoint(); 529 530 if (!sysfs) 531 return -1; 532 533 snprintf(path, PATH_MAX, 534 "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name); 535 536 if (stat(path, &st) < 0) 537 return -1; 538 539 file = fopen(path, "r"); 540 if (!file) 541 return -EINVAL; 542 543 if (1 != fscanf(file, "%u", type)) 544 ret = -1; 545 546 fclose(file); 547 return ret; 548 } 549 550 /* Add all pmus in sysfs to pmu list: */ 551 static void pmu_read_sysfs(void) 552 { 553 char path[PATH_MAX]; 554 DIR *dir; 555 struct dirent *dent; 556 const char *sysfs = sysfs__mountpoint(); 557 558 if (!sysfs) 559 return; 560 561 snprintf(path, PATH_MAX, 562 "%s" EVENT_SOURCE_DEVICE_PATH, sysfs); 563 564 dir = opendir(path); 565 if (!dir) 566 return; 567 568 while ((dent = readdir(dir))) { 569 if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) 570 continue; 571 /* add to static LIST_HEAD(pmus): */ 572 perf_pmu__find(dent->d_name); 573 } 574 575 closedir(dir); 576 } 577 578 static struct perf_cpu_map *__pmu_cpumask(const char *path) 579 { 580 FILE *file; 581 struct perf_cpu_map *cpus; 582 583 file = fopen(path, "r"); 584 if (!file) 585 return NULL; 586 587 cpus = perf_cpu_map__read(file); 588 fclose(file); 589 return cpus; 590 } 591 592 /* 593 * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64) 594 * may have a "cpus" file. 595 */ 596 #define CPUS_TEMPLATE_UNCORE "%s/bus/event_source/devices/%s/cpumask" 597 #define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus" 598 599 static struct perf_cpu_map *pmu_cpumask(const char *name) 600 { 601 char path[PATH_MAX]; 602 struct perf_cpu_map *cpus; 603 const char *sysfs = sysfs__mountpoint(); 604 const char *templates[] = { 605 CPUS_TEMPLATE_UNCORE, 606 CPUS_TEMPLATE_CPU, 607 NULL 608 }; 609 const char **template; 610 611 if (!sysfs) 612 return NULL; 613 614 for (template = templates; *template; template++) { 615 snprintf(path, PATH_MAX, *template, sysfs, name); 616 cpus = __pmu_cpumask(path); 617 if (cpus) 618 return cpus; 619 } 620 621 return NULL; 622 } 623 624 static bool pmu_is_uncore(const char *name) 625 { 626 char path[PATH_MAX]; 627 struct perf_cpu_map *cpus; 628 const char *sysfs = sysfs__mountpoint(); 629 630 snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); 631 cpus = __pmu_cpumask(path); 632 perf_cpu_map__put(cpus); 633 634 return !!cpus; 635 } 636 637 /* 638 * PMU CORE devices have different name other than cpu in sysfs on some 639 * platforms. 640 * Looking for possible sysfs files to identify the arm core device. 641 */ 642 static int is_arm_pmu_core(const char *name) 643 { 644 struct stat st; 645 char path[PATH_MAX]; 646 const char *sysfs = sysfs__mountpoint(); 647 648 if (!sysfs) 649 return 0; 650 651 /* Look for cpu sysfs (specific to arm) */ 652 scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus", 653 sysfs, name); 654 if (stat(path, &st) == 0) 655 return 1; 656 657 return 0; 658 } 659 660 static char *perf_pmu__getcpuid(struct perf_pmu *pmu) 661 { 662 char *cpuid; 663 static bool printed; 664 665 cpuid = getenv("PERF_CPUID"); 666 if (cpuid) 667 cpuid = strdup(cpuid); 668 if (!cpuid) 669 cpuid = get_cpuid_str(pmu); 670 if (!cpuid) 671 return NULL; 672 673 if (!printed) { 674 pr_debug("Using CPUID %s\n", cpuid); 675 printed = true; 676 } 677 return cpuid; 678 } 679 680 struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu) 681 { 682 struct pmu_events_map *map; 683 char *cpuid = perf_pmu__getcpuid(pmu); 684 int i; 685 686 /* on some platforms which uses cpus map, cpuid can be NULL for 687 * PMUs other than CORE PMUs. 688 */ 689 if (!cpuid) 690 return NULL; 691 692 i = 0; 693 for (;;) { 694 map = &pmu_events_map[i++]; 695 if (!map->table) { 696 map = NULL; 697 break; 698 } 699 700 if (!strcmp_cpuid_str(map->cpuid, cpuid)) 701 break; 702 } 703 free(cpuid); 704 return map; 705 } 706 707 static bool pmu_uncore_alias_match(const char *pmu_name, const char *name) 708 { 709 char *tmp = NULL, *tok, *str; 710 bool res; 711 712 str = strdup(pmu_name); 713 if (!str) 714 return false; 715 716 /* 717 * uncore alias may be from different PMU with common prefix 718 */ 719 tok = strtok_r(str, ",", &tmp); 720 if (strncmp(pmu_name, tok, strlen(tok))) { 721 res = false; 722 goto out; 723 } 724 725 /* 726 * Match more complex aliases where the alias name is a comma-delimited 727 * list of tokens, orderly contained in the matching PMU name. 728 * 729 * Example: For alias "socket,pmuname" and PMU "socketX_pmunameY", we 730 * match "socket" in "socketX_pmunameY" and then "pmuname" in 731 * "pmunameY". 732 */ 733 for (; tok; name += strlen(tok), tok = strtok_r(NULL, ",", &tmp)) { 734 name = strstr(name, tok); 735 if (!name) { 736 res = false; 737 goto out; 738 } 739 } 740 741 res = true; 742 out: 743 free(str); 744 return res; 745 } 746 747 /* 748 * From the pmu_events_map, find the table of PMU events that corresponds 749 * to the current running CPU. Then, add all PMU events from that table 750 * as aliases. 751 */ 752 static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu) 753 { 754 int i; 755 struct pmu_events_map *map; 756 const char *name = pmu->name; 757 758 map = perf_pmu__find_map(pmu); 759 if (!map) 760 return; 761 762 /* 763 * Found a matching PMU events table. Create aliases 764 */ 765 i = 0; 766 while (1) { 767 const char *cpu_name = is_arm_pmu_core(name) ? name : "cpu"; 768 struct pmu_event *pe = &map->table[i++]; 769 const char *pname = pe->pmu ? pe->pmu : cpu_name; 770 771 if (!pe->name) { 772 if (pe->metric_group || pe->metric_name) 773 continue; 774 break; 775 } 776 777 if (pmu_is_uncore(name) && 778 pmu_uncore_alias_match(pname, name)) 779 goto new_alias; 780 781 if (strcmp(pname, name)) 782 continue; 783 784 new_alias: 785 /* need type casts to override 'const' */ 786 __perf_pmu__new_alias(head, NULL, (char *)pe->name, 787 (char *)pe->desc, (char *)pe->event, 788 (char *)pe->long_desc, (char *)pe->topic, 789 (char *)pe->unit, (char *)pe->perpkg, 790 (char *)pe->metric_expr, 791 (char *)pe->metric_name); 792 } 793 } 794 795 struct perf_event_attr * __weak 796 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused) 797 { 798 return NULL; 799 } 800 801 static int pmu_max_precise(const char *name) 802 { 803 char path[PATH_MAX]; 804 int max_precise = -1; 805 806 scnprintf(path, PATH_MAX, 807 "bus/event_source/devices/%s/caps/max_precise", 808 name); 809 810 sysfs__read_int(path, &max_precise); 811 return max_precise; 812 } 813 814 static struct perf_pmu *pmu_lookup(const char *name) 815 { 816 struct perf_pmu *pmu; 817 LIST_HEAD(format); 818 LIST_HEAD(aliases); 819 __u32 type; 820 821 /* 822 * The pmu data we store & need consists of the pmu 823 * type value and format definitions. Load both right 824 * now. 825 */ 826 if (pmu_format(name, &format)) 827 return NULL; 828 829 /* 830 * Check the type first to avoid unnecessary work. 831 */ 832 if (pmu_type(name, &type)) 833 return NULL; 834 835 if (pmu_aliases(name, &aliases)) 836 return NULL; 837 838 pmu = zalloc(sizeof(*pmu)); 839 if (!pmu) 840 return NULL; 841 842 pmu->cpus = pmu_cpumask(name); 843 pmu->name = strdup(name); 844 pmu->type = type; 845 pmu->is_uncore = pmu_is_uncore(name); 846 pmu->max_precise = pmu_max_precise(name); 847 pmu_add_cpu_aliases(&aliases, pmu); 848 849 INIT_LIST_HEAD(&pmu->format); 850 INIT_LIST_HEAD(&pmu->aliases); 851 list_splice(&format, &pmu->format); 852 list_splice(&aliases, &pmu->aliases); 853 list_add_tail(&pmu->list, &pmus); 854 855 pmu->default_config = perf_pmu__get_default_config(pmu); 856 857 return pmu; 858 } 859 860 static struct perf_pmu *pmu_find(const char *name) 861 { 862 struct perf_pmu *pmu; 863 864 list_for_each_entry(pmu, &pmus, list) 865 if (!strcmp(pmu->name, name)) 866 return pmu; 867 868 return NULL; 869 } 870 871 struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) 872 { 873 /* 874 * pmu iterator: If pmu is NULL, we start at the begin, 875 * otherwise return the next pmu. Returns NULL on end. 876 */ 877 if (!pmu) { 878 pmu_read_sysfs(); 879 pmu = list_prepare_entry(pmu, &pmus, list); 880 } 881 list_for_each_entry_continue(pmu, &pmus, list) 882 return pmu; 883 return NULL; 884 } 885 886 struct perf_pmu *perf_pmu__find(const char *name) 887 { 888 struct perf_pmu *pmu; 889 890 /* 891 * Once PMU is loaded it stays in the list, 892 * so we keep us from multiple reading/parsing 893 * the pmu format definitions. 894 */ 895 pmu = pmu_find(name); 896 if (pmu) 897 return pmu; 898 899 return pmu_lookup(name); 900 } 901 902 static struct perf_pmu_format * 903 pmu_find_format(struct list_head *formats, const char *name) 904 { 905 struct perf_pmu_format *format; 906 907 list_for_each_entry(format, formats, list) 908 if (!strcmp(format->name, name)) 909 return format; 910 911 return NULL; 912 } 913 914 __u64 perf_pmu__format_bits(struct list_head *formats, const char *name) 915 { 916 struct perf_pmu_format *format = pmu_find_format(formats, name); 917 __u64 bits = 0; 918 int fbit; 919 920 if (!format) 921 return 0; 922 923 for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS) 924 bits |= 1ULL << fbit; 925 926 return bits; 927 } 928 929 /* 930 * Sets value based on the format definition (format parameter) 931 * and unformated value (value parameter). 932 */ 933 static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v, 934 bool zero) 935 { 936 unsigned long fbit, vbit; 937 938 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) { 939 940 if (!test_bit(fbit, format)) 941 continue; 942 943 if (value & (1llu << vbit++)) 944 *v |= (1llu << fbit); 945 else if (zero) 946 *v &= ~(1llu << fbit); 947 } 948 } 949 950 static __u64 pmu_format_max_value(const unsigned long *format) 951 { 952 int w; 953 954 w = bitmap_weight(format, PERF_PMU_FORMAT_BITS); 955 if (!w) 956 return 0; 957 if (w < 64) 958 return (1ULL << w) - 1; 959 return -1; 960 } 961 962 /* 963 * Term is a string term, and might be a param-term. Try to look up it's value 964 * in the remaining terms. 965 * - We have a term like "base-or-format-term=param-term", 966 * - We need to find the value supplied for "param-term" (with param-term named 967 * in a config string) later on in the term list. 968 */ 969 static int pmu_resolve_param_term(struct parse_events_term *term, 970 struct list_head *head_terms, 971 __u64 *value) 972 { 973 struct parse_events_term *t; 974 975 list_for_each_entry(t, head_terms, list) { 976 if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { 977 if (!strcmp(t->config, term->config)) { 978 t->used = true; 979 *value = t->val.num; 980 return 0; 981 } 982 } 983 } 984 985 if (verbose > 0) 986 printf("Required parameter '%s' not specified\n", term->config); 987 988 return -1; 989 } 990 991 static char *pmu_formats_string(struct list_head *formats) 992 { 993 struct perf_pmu_format *format; 994 char *str = NULL; 995 struct strbuf buf = STRBUF_INIT; 996 unsigned i = 0; 997 998 if (!formats) 999 return NULL; 1000 1001 /* sysfs exported terms */ 1002 list_for_each_entry(format, formats, list) 1003 if (strbuf_addf(&buf, i++ ? ",%s" : "%s", format->name) < 0) 1004 goto error; 1005 1006 str = strbuf_detach(&buf, NULL); 1007 error: 1008 strbuf_release(&buf); 1009 1010 return str; 1011 } 1012 1013 /* 1014 * Setup one of config[12] attr members based on the 1015 * user input data - term parameter. 1016 */ 1017 static int pmu_config_term(struct list_head *formats, 1018 struct perf_event_attr *attr, 1019 struct parse_events_term *term, 1020 struct list_head *head_terms, 1021 bool zero, struct parse_events_error *err) 1022 { 1023 struct perf_pmu_format *format; 1024 __u64 *vp; 1025 __u64 val, max_val; 1026 1027 /* 1028 * If this is a parameter we've already used for parameterized-eval, 1029 * skip it in normal eval. 1030 */ 1031 if (term->used) 1032 return 0; 1033 1034 /* 1035 * Hardcoded terms should be already in, so nothing 1036 * to be done for them. 1037 */ 1038 if (parse_events__is_hardcoded_term(term)) 1039 return 0; 1040 1041 format = pmu_find_format(formats, term->config); 1042 if (!format) { 1043 if (verbose > 0) 1044 printf("Invalid event/parameter '%s'\n", term->config); 1045 if (err) { 1046 char *pmu_term = pmu_formats_string(formats); 1047 1048 err->idx = term->err_term; 1049 err->str = strdup("unknown term"); 1050 err->help = parse_events_formats_error_string(pmu_term); 1051 free(pmu_term); 1052 } 1053 return -EINVAL; 1054 } 1055 1056 switch (format->value) { 1057 case PERF_PMU_FORMAT_VALUE_CONFIG: 1058 vp = &attr->config; 1059 break; 1060 case PERF_PMU_FORMAT_VALUE_CONFIG1: 1061 vp = &attr->config1; 1062 break; 1063 case PERF_PMU_FORMAT_VALUE_CONFIG2: 1064 vp = &attr->config2; 1065 break; 1066 default: 1067 return -EINVAL; 1068 } 1069 1070 /* 1071 * Either directly use a numeric term, or try to translate string terms 1072 * using event parameters. 1073 */ 1074 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { 1075 if (term->no_value && 1076 bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) { 1077 if (err) { 1078 err->idx = term->err_val; 1079 err->str = strdup("no value assigned for term"); 1080 } 1081 return -EINVAL; 1082 } 1083 1084 val = term->val.num; 1085 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 1086 if (strcmp(term->val.str, "?")) { 1087 if (verbose > 0) { 1088 pr_info("Invalid sysfs entry %s=%s\n", 1089 term->config, term->val.str); 1090 } 1091 if (err) { 1092 err->idx = term->err_val; 1093 err->str = strdup("expected numeric value"); 1094 } 1095 return -EINVAL; 1096 } 1097 1098 if (pmu_resolve_param_term(term, head_terms, &val)) 1099 return -EINVAL; 1100 } else 1101 return -EINVAL; 1102 1103 max_val = pmu_format_max_value(format->bits); 1104 if (val > max_val) { 1105 if (err) { 1106 err->idx = term->err_val; 1107 if (asprintf(&err->str, 1108 "value too big for format, maximum is %llu", 1109 (unsigned long long)max_val) < 0) 1110 err->str = strdup("value too big for format"); 1111 return -EINVAL; 1112 } 1113 /* 1114 * Assume we don't care if !err, in which case the value will be 1115 * silently truncated. 1116 */ 1117 } 1118 1119 pmu_format_value(format->bits, val, vp, zero); 1120 return 0; 1121 } 1122 1123 int perf_pmu__config_terms(struct list_head *formats, 1124 struct perf_event_attr *attr, 1125 struct list_head *head_terms, 1126 bool zero, struct parse_events_error *err) 1127 { 1128 struct parse_events_term *term; 1129 1130 list_for_each_entry(term, head_terms, list) { 1131 if (pmu_config_term(formats, attr, term, head_terms, 1132 zero, err)) 1133 return -EINVAL; 1134 } 1135 1136 return 0; 1137 } 1138 1139 /* 1140 * Configures event's 'attr' parameter based on the: 1141 * 1) users input - specified in terms parameter 1142 * 2) pmu format definitions - specified by pmu parameter 1143 */ 1144 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, 1145 struct list_head *head_terms, 1146 struct parse_events_error *err) 1147 { 1148 bool zero = !!pmu->default_config; 1149 1150 attr->type = pmu->type; 1151 return perf_pmu__config_terms(&pmu->format, attr, head_terms, 1152 zero, err); 1153 } 1154 1155 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, 1156 struct parse_events_term *term) 1157 { 1158 struct perf_pmu_alias *alias; 1159 char *name; 1160 1161 if (parse_events__is_hardcoded_term(term)) 1162 return NULL; 1163 1164 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { 1165 if (term->val.num != 1) 1166 return NULL; 1167 if (pmu_find_format(&pmu->format, term->config)) 1168 return NULL; 1169 name = term->config; 1170 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 1171 if (strcasecmp(term->config, "event")) 1172 return NULL; 1173 name = term->val.str; 1174 } else { 1175 return NULL; 1176 } 1177 1178 list_for_each_entry(alias, &pmu->aliases, list) { 1179 if (!strcasecmp(alias->name, name)) 1180 return alias; 1181 } 1182 return NULL; 1183 } 1184 1185 1186 static int check_info_data(struct perf_pmu_alias *alias, 1187 struct perf_pmu_info *info) 1188 { 1189 /* 1190 * Only one term in event definition can 1191 * define unit, scale and snapshot, fail 1192 * if there's more than one. 1193 */ 1194 if ((info->unit && alias->unit[0]) || 1195 (info->scale && alias->scale) || 1196 (info->snapshot && alias->snapshot)) 1197 return -EINVAL; 1198 1199 if (alias->unit[0]) 1200 info->unit = alias->unit; 1201 1202 if (alias->scale) 1203 info->scale = alias->scale; 1204 1205 if (alias->snapshot) 1206 info->snapshot = alias->snapshot; 1207 1208 return 0; 1209 } 1210 1211 /* 1212 * Find alias in the terms list and replace it with the terms 1213 * defined for the alias 1214 */ 1215 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, 1216 struct perf_pmu_info *info) 1217 { 1218 struct parse_events_term *term, *h; 1219 struct perf_pmu_alias *alias; 1220 int ret; 1221 1222 info->per_pkg = false; 1223 1224 /* 1225 * Mark unit and scale as not set 1226 * (different from default values, see below) 1227 */ 1228 info->unit = NULL; 1229 info->scale = 0.0; 1230 info->snapshot = false; 1231 info->metric_expr = NULL; 1232 info->metric_name = NULL; 1233 1234 list_for_each_entry_safe(term, h, head_terms, list) { 1235 alias = pmu_find_alias(pmu, term); 1236 if (!alias) 1237 continue; 1238 ret = pmu_alias_terms(alias, &term->list); 1239 if (ret) 1240 return ret; 1241 1242 ret = check_info_data(alias, info); 1243 if (ret) 1244 return ret; 1245 1246 if (alias->per_pkg) 1247 info->per_pkg = true; 1248 info->metric_expr = alias->metric_expr; 1249 info->metric_name = alias->metric_name; 1250 1251 list_del_init(&term->list); 1252 free(term); 1253 } 1254 1255 /* 1256 * if no unit or scale foundin aliases, then 1257 * set defaults as for evsel 1258 * unit cannot left to NULL 1259 */ 1260 if (info->unit == NULL) 1261 info->unit = ""; 1262 1263 if (info->scale == 0.0) 1264 info->scale = 1.0; 1265 1266 return 0; 1267 } 1268 1269 int perf_pmu__new_format(struct list_head *list, char *name, 1270 int config, unsigned long *bits) 1271 { 1272 struct perf_pmu_format *format; 1273 1274 format = zalloc(sizeof(*format)); 1275 if (!format) 1276 return -ENOMEM; 1277 1278 format->name = strdup(name); 1279 format->value = config; 1280 memcpy(format->bits, bits, sizeof(format->bits)); 1281 1282 list_add_tail(&format->list, list); 1283 return 0; 1284 } 1285 1286 void perf_pmu__set_format(unsigned long *bits, long from, long to) 1287 { 1288 long b; 1289 1290 if (!to) 1291 to = from; 1292 1293 memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS)); 1294 for (b = from; b <= to; b++) 1295 set_bit(b, bits); 1296 } 1297 1298 static int sub_non_neg(int a, int b) 1299 { 1300 if (b > a) 1301 return 0; 1302 return a - b; 1303 } 1304 1305 static char *format_alias(char *buf, int len, struct perf_pmu *pmu, 1306 struct perf_pmu_alias *alias) 1307 { 1308 struct parse_events_term *term; 1309 int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name); 1310 1311 list_for_each_entry(term, &alias->terms, list) { 1312 if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) 1313 used += snprintf(buf + used, sub_non_neg(len, used), 1314 ",%s=%s", term->config, 1315 term->val.str); 1316 } 1317 1318 if (sub_non_neg(len, used) > 0) { 1319 buf[used] = '/'; 1320 used++; 1321 } 1322 if (sub_non_neg(len, used) > 0) { 1323 buf[used] = '\0'; 1324 used++; 1325 } else 1326 buf[len - 1] = '\0'; 1327 1328 return buf; 1329 } 1330 1331 static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, 1332 struct perf_pmu_alias *alias) 1333 { 1334 snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name); 1335 return buf; 1336 } 1337 1338 struct sevent { 1339 char *name; 1340 char *desc; 1341 char *topic; 1342 char *str; 1343 char *pmu; 1344 char *metric_expr; 1345 char *metric_name; 1346 }; 1347 1348 static int cmp_sevent(const void *a, const void *b) 1349 { 1350 const struct sevent *as = a; 1351 const struct sevent *bs = b; 1352 1353 /* Put extra events last */ 1354 if (!!as->desc != !!bs->desc) 1355 return !!as->desc - !!bs->desc; 1356 if (as->topic && bs->topic) { 1357 int n = strcmp(as->topic, bs->topic); 1358 1359 if (n) 1360 return n; 1361 } 1362 return strcmp(as->name, bs->name); 1363 } 1364 1365 static void wordwrap(char *s, int start, int max, int corr) 1366 { 1367 int column = start; 1368 int n; 1369 1370 while (*s) { 1371 int wlen = strcspn(s, " \t"); 1372 1373 if (column + wlen >= max && column > start) { 1374 printf("\n%*s", start, ""); 1375 column = start + corr; 1376 } 1377 n = printf("%s%.*s", column > start ? " " : "", wlen, s); 1378 if (n <= 0) 1379 break; 1380 s += wlen; 1381 column += n; 1382 s = skip_spaces(s); 1383 } 1384 } 1385 1386 void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, 1387 bool long_desc, bool details_flag) 1388 { 1389 struct perf_pmu *pmu; 1390 struct perf_pmu_alias *alias; 1391 char buf[1024]; 1392 int printed = 0; 1393 int len, j; 1394 struct sevent *aliases; 1395 int numdesc = 0; 1396 int columns = pager_get_columns(); 1397 char *topic = NULL; 1398 1399 pmu = NULL; 1400 len = 0; 1401 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 1402 list_for_each_entry(alias, &pmu->aliases, list) 1403 len++; 1404 if (pmu->selectable) 1405 len++; 1406 } 1407 aliases = zalloc(sizeof(struct sevent) * len); 1408 if (!aliases) 1409 goto out_enomem; 1410 pmu = NULL; 1411 j = 0; 1412 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 1413 list_for_each_entry(alias, &pmu->aliases, list) { 1414 char *name = alias->desc ? alias->name : 1415 format_alias(buf, sizeof(buf), pmu, alias); 1416 bool is_cpu = !strcmp(pmu->name, "cpu"); 1417 1418 if (event_glob != NULL && 1419 !(strglobmatch_nocase(name, event_glob) || 1420 (!is_cpu && strglobmatch_nocase(alias->name, 1421 event_glob)) || 1422 (alias->topic && 1423 strglobmatch_nocase(alias->topic, event_glob)))) 1424 continue; 1425 1426 if (is_cpu && !name_only && !alias->desc) 1427 name = format_alias_or(buf, sizeof(buf), pmu, alias); 1428 1429 aliases[j].name = name; 1430 if (is_cpu && !name_only && !alias->desc) 1431 aliases[j].name = format_alias_or(buf, 1432 sizeof(buf), 1433 pmu, alias); 1434 aliases[j].name = strdup(aliases[j].name); 1435 if (!aliases[j].name) 1436 goto out_enomem; 1437 1438 aliases[j].desc = long_desc ? alias->long_desc : 1439 alias->desc; 1440 aliases[j].topic = alias->topic; 1441 aliases[j].str = alias->str; 1442 aliases[j].pmu = pmu->name; 1443 aliases[j].metric_expr = alias->metric_expr; 1444 aliases[j].metric_name = alias->metric_name; 1445 j++; 1446 } 1447 if (pmu->selectable && 1448 (event_glob == NULL || strglobmatch(pmu->name, event_glob))) { 1449 char *s; 1450 if (asprintf(&s, "%s//", pmu->name) < 0) 1451 goto out_enomem; 1452 aliases[j].name = s; 1453 j++; 1454 } 1455 } 1456 len = j; 1457 qsort(aliases, len, sizeof(struct sevent), cmp_sevent); 1458 for (j = 0; j < len; j++) { 1459 /* Skip duplicates */ 1460 if (j > 0 && !strcmp(aliases[j].name, aliases[j - 1].name)) 1461 continue; 1462 if (name_only) { 1463 printf("%s ", aliases[j].name); 1464 continue; 1465 } 1466 if (aliases[j].desc && !quiet_flag) { 1467 if (numdesc++ == 0) 1468 printf("\n"); 1469 if (aliases[j].topic && (!topic || 1470 strcmp(topic, aliases[j].topic))) { 1471 printf("%s%s:\n", topic ? "\n" : "", 1472 aliases[j].topic); 1473 topic = aliases[j].topic; 1474 } 1475 printf(" %-50s\n", aliases[j].name); 1476 printf("%*s", 8, "["); 1477 wordwrap(aliases[j].desc, 8, columns, 0); 1478 printf("]\n"); 1479 if (details_flag) { 1480 printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str); 1481 if (aliases[j].metric_name) 1482 printf(" MetricName: %s", aliases[j].metric_name); 1483 if (aliases[j].metric_expr) 1484 printf(" MetricExpr: %s", aliases[j].metric_expr); 1485 putchar('\n'); 1486 } 1487 } else 1488 printf(" %-50s [Kernel PMU event]\n", aliases[j].name); 1489 printed++; 1490 } 1491 if (printed && pager_in_use()) 1492 printf("\n"); 1493 out_free: 1494 for (j = 0; j < len; j++) 1495 zfree(&aliases[j].name); 1496 zfree(&aliases); 1497 return; 1498 1499 out_enomem: 1500 printf("FATAL: not enough memory to print PMU events\n"); 1501 if (aliases) 1502 goto out_free; 1503 } 1504 1505 bool pmu_have_event(const char *pname, const char *name) 1506 { 1507 struct perf_pmu *pmu; 1508 struct perf_pmu_alias *alias; 1509 1510 pmu = NULL; 1511 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 1512 if (strcmp(pname, pmu->name)) 1513 continue; 1514 list_for_each_entry(alias, &pmu->aliases, list) 1515 if (!strcmp(alias->name, name)) 1516 return true; 1517 } 1518 return false; 1519 } 1520 1521 static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name) 1522 { 1523 struct stat st; 1524 char path[PATH_MAX]; 1525 const char *sysfs; 1526 1527 sysfs = sysfs__mountpoint(); 1528 if (!sysfs) 1529 return NULL; 1530 1531 snprintf(path, PATH_MAX, 1532 "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name); 1533 1534 if (stat(path, &st) < 0) 1535 return NULL; 1536 1537 return fopen(path, "r"); 1538 } 1539 1540 int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, 1541 ...) 1542 { 1543 va_list args; 1544 FILE *file; 1545 int ret = EOF; 1546 1547 va_start(args, fmt); 1548 file = perf_pmu__open_file(pmu, name); 1549 if (file) { 1550 ret = vfscanf(file, fmt, args); 1551 fclose(file); 1552 } 1553 va_end(args); 1554 return ret; 1555 } 1556