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