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