1 #include <linux/list.h> 2 #include <sys/types.h> 3 #include <unistd.h> 4 #include <stdio.h> 5 #include <dirent.h> 6 #include <api/fs/fs.h> 7 #include <locale.h> 8 #include "util.h" 9 #include "pmu.h" 10 #include "parse-events.h" 11 #include "cpumap.h" 12 13 #define UNIT_MAX_LEN 31 /* max length for event unit name */ 14 15 struct perf_pmu_alias { 16 char *name; 17 struct list_head terms; 18 struct list_head list; 19 char unit[UNIT_MAX_LEN+1]; 20 double scale; 21 }; 22 23 struct perf_pmu_format { 24 char *name; 25 int value; 26 DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); 27 struct list_head list; 28 }; 29 30 #define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/" 31 32 int perf_pmu_parse(struct list_head *list, char *name); 33 extern FILE *perf_pmu_in; 34 35 static LIST_HEAD(pmus); 36 37 /* 38 * Parse & process all the sysfs attributes located under 39 * the directory specified in 'dir' parameter. 40 */ 41 int perf_pmu__format_parse(char *dir, struct list_head *head) 42 { 43 struct dirent *evt_ent; 44 DIR *format_dir; 45 int ret = 0; 46 47 format_dir = opendir(dir); 48 if (!format_dir) 49 return -EINVAL; 50 51 while (!ret && (evt_ent = readdir(format_dir))) { 52 char path[PATH_MAX]; 53 char *name = evt_ent->d_name; 54 FILE *file; 55 56 if (!strcmp(name, ".") || !strcmp(name, "..")) 57 continue; 58 59 snprintf(path, PATH_MAX, "%s/%s", dir, name); 60 61 ret = -EINVAL; 62 file = fopen(path, "r"); 63 if (!file) 64 break; 65 66 perf_pmu_in = file; 67 ret = perf_pmu_parse(head, name); 68 fclose(file); 69 } 70 71 closedir(format_dir); 72 return ret; 73 } 74 75 /* 76 * Reading/parsing the default pmu format definition, which should be 77 * located at: 78 * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes. 79 */ 80 static int pmu_format(const char *name, struct list_head *format) 81 { 82 struct stat st; 83 char path[PATH_MAX]; 84 const char *sysfs = sysfs__mountpoint(); 85 86 if (!sysfs) 87 return -1; 88 89 snprintf(path, PATH_MAX, 90 "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name); 91 92 if (stat(path, &st) < 0) 93 return 0; /* no error if format does not exist */ 94 95 if (perf_pmu__format_parse(path, format)) 96 return -1; 97 98 return 0; 99 } 100 101 static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name) 102 { 103 struct stat st; 104 ssize_t sret; 105 char scale[128]; 106 int fd, ret = -1; 107 char path[PATH_MAX]; 108 const char *lc; 109 110 snprintf(path, PATH_MAX, "%s/%s.scale", dir, name); 111 112 fd = open(path, O_RDONLY); 113 if (fd == -1) 114 return -1; 115 116 if (fstat(fd, &st) < 0) 117 goto error; 118 119 sret = read(fd, scale, sizeof(scale)-1); 120 if (sret < 0) 121 goto error; 122 123 scale[sret] = '\0'; 124 /* 125 * save current locale 126 */ 127 lc = setlocale(LC_NUMERIC, NULL); 128 129 /* 130 * force to C locale to ensure kernel 131 * scale string is converted correctly. 132 * kernel uses default C locale. 133 */ 134 setlocale(LC_NUMERIC, "C"); 135 136 alias->scale = strtod(scale, NULL); 137 138 /* restore locale */ 139 setlocale(LC_NUMERIC, lc); 140 141 ret = 0; 142 error: 143 close(fd); 144 return ret; 145 } 146 147 static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name) 148 { 149 char path[PATH_MAX]; 150 ssize_t sret; 151 int fd; 152 153 snprintf(path, PATH_MAX, "%s/%s.unit", dir, name); 154 155 fd = open(path, O_RDONLY); 156 if (fd == -1) 157 return -1; 158 159 sret = read(fd, alias->unit, UNIT_MAX_LEN); 160 if (sret < 0) 161 goto error; 162 163 close(fd); 164 165 alias->unit[sret] = '\0'; 166 167 return 0; 168 error: 169 close(fd); 170 alias->unit[0] = '\0'; 171 return -1; 172 } 173 174 static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file) 175 { 176 struct perf_pmu_alias *alias; 177 char buf[256]; 178 int ret; 179 180 ret = fread(buf, 1, sizeof(buf), file); 181 if (ret == 0) 182 return -EINVAL; 183 buf[ret] = 0; 184 185 alias = malloc(sizeof(*alias)); 186 if (!alias) 187 return -ENOMEM; 188 189 INIT_LIST_HEAD(&alias->terms); 190 alias->scale = 1.0; 191 alias->unit[0] = '\0'; 192 193 ret = parse_events_terms(&alias->terms, buf); 194 if (ret) { 195 free(alias); 196 return ret; 197 } 198 199 alias->name = strdup(name); 200 /* 201 * load unit name and scale if available 202 */ 203 perf_pmu__parse_unit(alias, dir, name); 204 perf_pmu__parse_scale(alias, dir, name); 205 206 list_add_tail(&alias->list, list); 207 208 return 0; 209 } 210 211 /* 212 * Process all the sysfs attributes located under the directory 213 * specified in 'dir' parameter. 214 */ 215 static int pmu_aliases_parse(char *dir, struct list_head *head) 216 { 217 struct dirent *evt_ent; 218 DIR *event_dir; 219 size_t len; 220 int ret = 0; 221 222 event_dir = opendir(dir); 223 if (!event_dir) 224 return -EINVAL; 225 226 while (!ret && (evt_ent = readdir(event_dir))) { 227 char path[PATH_MAX]; 228 char *name = evt_ent->d_name; 229 FILE *file; 230 231 if (!strcmp(name, ".") || !strcmp(name, "..")) 232 continue; 233 234 /* 235 * skip .unit and .scale info files 236 * parsed in perf_pmu__new_alias() 237 */ 238 len = strlen(name); 239 if (len > 5 && !strcmp(name + len - 5, ".unit")) 240 continue; 241 if (len > 6 && !strcmp(name + len - 6, ".scale")) 242 continue; 243 244 snprintf(path, PATH_MAX, "%s/%s", dir, name); 245 246 ret = -EINVAL; 247 file = fopen(path, "r"); 248 if (!file) 249 break; 250 251 ret = perf_pmu__new_alias(head, dir, name, file); 252 fclose(file); 253 } 254 255 closedir(event_dir); 256 return ret; 257 } 258 259 /* 260 * Reading the pmu event aliases definition, which should be located at: 261 * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes. 262 */ 263 static int pmu_aliases(const char *name, struct list_head *head) 264 { 265 struct stat st; 266 char path[PATH_MAX]; 267 const char *sysfs = sysfs__mountpoint(); 268 269 if (!sysfs) 270 return -1; 271 272 snprintf(path, PATH_MAX, 273 "%s/bus/event_source/devices/%s/events", sysfs, name); 274 275 if (stat(path, &st) < 0) 276 return 0; /* no error if 'events' does not exist */ 277 278 if (pmu_aliases_parse(path, head)) 279 return -1; 280 281 return 0; 282 } 283 284 static int pmu_alias_terms(struct perf_pmu_alias *alias, 285 struct list_head *terms) 286 { 287 struct parse_events_term *term, *cloned; 288 LIST_HEAD(list); 289 int ret; 290 291 list_for_each_entry(term, &alias->terms, list) { 292 ret = parse_events_term__clone(&cloned, term); 293 if (ret) { 294 parse_events__free_terms(&list); 295 return ret; 296 } 297 list_add_tail(&cloned->list, &list); 298 } 299 list_splice(&list, terms); 300 return 0; 301 } 302 303 /* 304 * Reading/parsing the default pmu type value, which should be 305 * located at: 306 * /sys/bus/event_source/devices/<dev>/type as sysfs attribute. 307 */ 308 static int pmu_type(const char *name, __u32 *type) 309 { 310 struct stat st; 311 char path[PATH_MAX]; 312 FILE *file; 313 int ret = 0; 314 const char *sysfs = sysfs__mountpoint(); 315 316 if (!sysfs) 317 return -1; 318 319 snprintf(path, PATH_MAX, 320 "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name); 321 322 if (stat(path, &st) < 0) 323 return -1; 324 325 file = fopen(path, "r"); 326 if (!file) 327 return -EINVAL; 328 329 if (1 != fscanf(file, "%u", type)) 330 ret = -1; 331 332 fclose(file); 333 return ret; 334 } 335 336 /* Add all pmus in sysfs to pmu list: */ 337 static void pmu_read_sysfs(void) 338 { 339 char path[PATH_MAX]; 340 DIR *dir; 341 struct dirent *dent; 342 const char *sysfs = sysfs__mountpoint(); 343 344 if (!sysfs) 345 return; 346 347 snprintf(path, PATH_MAX, 348 "%s" EVENT_SOURCE_DEVICE_PATH, sysfs); 349 350 dir = opendir(path); 351 if (!dir) 352 return; 353 354 while ((dent = readdir(dir))) { 355 if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) 356 continue; 357 /* add to static LIST_HEAD(pmus): */ 358 perf_pmu__find(dent->d_name); 359 } 360 361 closedir(dir); 362 } 363 364 static struct cpu_map *pmu_cpumask(const char *name) 365 { 366 struct stat st; 367 char path[PATH_MAX]; 368 FILE *file; 369 struct cpu_map *cpus; 370 const char *sysfs = sysfs__mountpoint(); 371 372 if (!sysfs) 373 return NULL; 374 375 snprintf(path, PATH_MAX, 376 "%s/bus/event_source/devices/%s/cpumask", sysfs, name); 377 378 if (stat(path, &st) < 0) 379 return NULL; 380 381 file = fopen(path, "r"); 382 if (!file) 383 return NULL; 384 385 cpus = cpu_map__read(file); 386 fclose(file); 387 return cpus; 388 } 389 390 static struct perf_pmu *pmu_lookup(const char *name) 391 { 392 struct perf_pmu *pmu; 393 LIST_HEAD(format); 394 LIST_HEAD(aliases); 395 __u32 type; 396 397 /* 398 * The pmu data we store & need consists of the pmu 399 * type value and format definitions. Load both right 400 * now. 401 */ 402 if (pmu_format(name, &format)) 403 return NULL; 404 405 if (pmu_aliases(name, &aliases)) 406 return NULL; 407 408 if (pmu_type(name, &type)) 409 return NULL; 410 411 pmu = zalloc(sizeof(*pmu)); 412 if (!pmu) 413 return NULL; 414 415 pmu->cpus = pmu_cpumask(name); 416 417 INIT_LIST_HEAD(&pmu->format); 418 INIT_LIST_HEAD(&pmu->aliases); 419 list_splice(&format, &pmu->format); 420 list_splice(&aliases, &pmu->aliases); 421 pmu->name = strdup(name); 422 pmu->type = type; 423 list_add_tail(&pmu->list, &pmus); 424 return pmu; 425 } 426 427 static struct perf_pmu *pmu_find(const char *name) 428 { 429 struct perf_pmu *pmu; 430 431 list_for_each_entry(pmu, &pmus, list) 432 if (!strcmp(pmu->name, name)) 433 return pmu; 434 435 return NULL; 436 } 437 438 struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) 439 { 440 /* 441 * pmu iterator: If pmu is NULL, we start at the begin, 442 * otherwise return the next pmu. Returns NULL on end. 443 */ 444 if (!pmu) { 445 pmu_read_sysfs(); 446 pmu = list_prepare_entry(pmu, &pmus, list); 447 } 448 list_for_each_entry_continue(pmu, &pmus, list) 449 return pmu; 450 return NULL; 451 } 452 453 struct perf_pmu *perf_pmu__find(const char *name) 454 { 455 struct perf_pmu *pmu; 456 457 /* 458 * Once PMU is loaded it stays in the list, 459 * so we keep us from multiple reading/parsing 460 * the pmu format definitions. 461 */ 462 pmu = pmu_find(name); 463 if (pmu) 464 return pmu; 465 466 return pmu_lookup(name); 467 } 468 469 static struct perf_pmu_format * 470 pmu_find_format(struct list_head *formats, char *name) 471 { 472 struct perf_pmu_format *format; 473 474 list_for_each_entry(format, formats, list) 475 if (!strcmp(format->name, name)) 476 return format; 477 478 return NULL; 479 } 480 481 /* 482 * Returns value based on the format definition (format parameter) 483 * and unformated value (value parameter). 484 * 485 * TODO maybe optimize a little ;) 486 */ 487 static __u64 pmu_format_value(unsigned long *format, __u64 value) 488 { 489 unsigned long fbit, vbit; 490 __u64 v = 0; 491 492 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) { 493 494 if (!test_bit(fbit, format)) 495 continue; 496 497 if (!(value & (1llu << vbit++))) 498 continue; 499 500 v |= (1llu << fbit); 501 } 502 503 return v; 504 } 505 506 /* 507 * Setup one of config[12] attr members based on the 508 * user input data - term parameter. 509 */ 510 static int pmu_config_term(struct list_head *formats, 511 struct perf_event_attr *attr, 512 struct parse_events_term *term) 513 { 514 struct perf_pmu_format *format; 515 __u64 *vp; 516 517 /* 518 * Support only for hardcoded and numnerial terms. 519 * Hardcoded terms should be already in, so nothing 520 * to be done for them. 521 */ 522 if (parse_events__is_hardcoded_term(term)) 523 return 0; 524 525 if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM) 526 return -EINVAL; 527 528 format = pmu_find_format(formats, term->config); 529 if (!format) 530 return -EINVAL; 531 532 switch (format->value) { 533 case PERF_PMU_FORMAT_VALUE_CONFIG: 534 vp = &attr->config; 535 break; 536 case PERF_PMU_FORMAT_VALUE_CONFIG1: 537 vp = &attr->config1; 538 break; 539 case PERF_PMU_FORMAT_VALUE_CONFIG2: 540 vp = &attr->config2; 541 break; 542 default: 543 return -EINVAL; 544 } 545 546 /* 547 * XXX If we ever decide to go with string values for 548 * non-hardcoded terms, here's the place to translate 549 * them into value. 550 */ 551 *vp |= pmu_format_value(format->bits, term->val.num); 552 return 0; 553 } 554 555 int perf_pmu__config_terms(struct list_head *formats, 556 struct perf_event_attr *attr, 557 struct list_head *head_terms) 558 { 559 struct parse_events_term *term; 560 561 list_for_each_entry(term, head_terms, list) 562 if (pmu_config_term(formats, attr, term)) 563 return -EINVAL; 564 565 return 0; 566 } 567 568 /* 569 * Configures event's 'attr' parameter based on the: 570 * 1) users input - specified in terms parameter 571 * 2) pmu format definitions - specified by pmu parameter 572 */ 573 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, 574 struct list_head *head_terms) 575 { 576 attr->type = pmu->type; 577 return perf_pmu__config_terms(&pmu->format, attr, head_terms); 578 } 579 580 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, 581 struct parse_events_term *term) 582 { 583 struct perf_pmu_alias *alias; 584 char *name; 585 586 if (parse_events__is_hardcoded_term(term)) 587 return NULL; 588 589 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { 590 if (term->val.num != 1) 591 return NULL; 592 if (pmu_find_format(&pmu->format, term->config)) 593 return NULL; 594 name = term->config; 595 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 596 if (strcasecmp(term->config, "event")) 597 return NULL; 598 name = term->val.str; 599 } else { 600 return NULL; 601 } 602 603 list_for_each_entry(alias, &pmu->aliases, list) { 604 if (!strcasecmp(alias->name, name)) 605 return alias; 606 } 607 return NULL; 608 } 609 610 611 static int check_unit_scale(struct perf_pmu_alias *alias, 612 const char **unit, double *scale) 613 { 614 /* 615 * Only one term in event definition can 616 * define unit and scale, fail if there's 617 * more than one. 618 */ 619 if ((*unit && alias->unit) || 620 (*scale && alias->scale)) 621 return -EINVAL; 622 623 if (alias->unit) 624 *unit = alias->unit; 625 626 if (alias->scale) 627 *scale = alias->scale; 628 629 return 0; 630 } 631 632 /* 633 * Find alias in the terms list and replace it with the terms 634 * defined for the alias 635 */ 636 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, 637 const char **unit, double *scale) 638 { 639 struct parse_events_term *term, *h; 640 struct perf_pmu_alias *alias; 641 int ret; 642 643 /* 644 * Mark unit and scale as not set 645 * (different from default values, see below) 646 */ 647 *unit = NULL; 648 *scale = 0.0; 649 650 list_for_each_entry_safe(term, h, head_terms, list) { 651 alias = pmu_find_alias(pmu, term); 652 if (!alias) 653 continue; 654 ret = pmu_alias_terms(alias, &term->list); 655 if (ret) 656 return ret; 657 658 ret = check_unit_scale(alias, unit, scale); 659 if (ret) 660 return ret; 661 662 list_del(&term->list); 663 free(term); 664 } 665 666 /* 667 * if no unit or scale foundin aliases, then 668 * set defaults as for evsel 669 * unit cannot left to NULL 670 */ 671 if (*unit == NULL) 672 *unit = ""; 673 674 if (*scale == 0.0) 675 *scale = 1.0; 676 677 return 0; 678 } 679 680 int perf_pmu__new_format(struct list_head *list, char *name, 681 int config, unsigned long *bits) 682 { 683 struct perf_pmu_format *format; 684 685 format = zalloc(sizeof(*format)); 686 if (!format) 687 return -ENOMEM; 688 689 format->name = strdup(name); 690 format->value = config; 691 memcpy(format->bits, bits, sizeof(format->bits)); 692 693 list_add_tail(&format->list, list); 694 return 0; 695 } 696 697 void perf_pmu__set_format(unsigned long *bits, long from, long to) 698 { 699 long b; 700 701 if (!to) 702 to = from; 703 704 memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS)); 705 for (b = from; b <= to; b++) 706 set_bit(b, bits); 707 } 708 709 static char *format_alias(char *buf, int len, struct perf_pmu *pmu, 710 struct perf_pmu_alias *alias) 711 { 712 snprintf(buf, len, "%s/%s/", pmu->name, alias->name); 713 return buf; 714 } 715 716 static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, 717 struct perf_pmu_alias *alias) 718 { 719 snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name); 720 return buf; 721 } 722 723 static int cmp_string(const void *a, const void *b) 724 { 725 const char * const *as = a; 726 const char * const *bs = b; 727 return strcmp(*as, *bs); 728 } 729 730 void print_pmu_events(const char *event_glob, bool name_only) 731 { 732 struct perf_pmu *pmu; 733 struct perf_pmu_alias *alias; 734 char buf[1024]; 735 int printed = 0; 736 int len, j; 737 char **aliases; 738 739 pmu = NULL; 740 len = 0; 741 while ((pmu = perf_pmu__scan(pmu)) != NULL) 742 list_for_each_entry(alias, &pmu->aliases, list) 743 len++; 744 aliases = malloc(sizeof(char *) * len); 745 if (!aliases) 746 return; 747 pmu = NULL; 748 j = 0; 749 while ((pmu = perf_pmu__scan(pmu)) != NULL) 750 list_for_each_entry(alias, &pmu->aliases, list) { 751 char *name = format_alias(buf, sizeof(buf), pmu, alias); 752 bool is_cpu = !strcmp(pmu->name, "cpu"); 753 754 if (event_glob != NULL && 755 !(strglobmatch(name, event_glob) || 756 (!is_cpu && strglobmatch(alias->name, 757 event_glob)))) 758 continue; 759 aliases[j] = name; 760 if (is_cpu && !name_only) 761 aliases[j] = format_alias_or(buf, sizeof(buf), 762 pmu, alias); 763 aliases[j] = strdup(aliases[j]); 764 j++; 765 } 766 len = j; 767 qsort(aliases, len, sizeof(char *), cmp_string); 768 for (j = 0; j < len; j++) { 769 if (name_only) { 770 printf("%s ", aliases[j]); 771 continue; 772 } 773 printf(" %-50s [Kernel PMU event]\n", aliases[j]); 774 zfree(&aliases[j]); 775 printed++; 776 } 777 if (printed) 778 printf("\n"); 779 free(aliases); 780 } 781 782 bool pmu_have_event(const char *pname, const char *name) 783 { 784 struct perf_pmu *pmu; 785 struct perf_pmu_alias *alias; 786 787 pmu = NULL; 788 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 789 if (strcmp(pname, pmu->name)) 790 continue; 791 list_for_each_entry(alias, &pmu->aliases, list) 792 if (!strcmp(alias->name, name)) 793 return true; 794 } 795 return false; 796 } 797