linux/tools/perf/util/parse-events.c
<<
>>
Prefs
   1#include "../../../include/linux/hw_breakpoint.h"
   2#include "util.h"
   3#include "../perf.h"
   4#include "evlist.h"
   5#include "evsel.h"
   6#include "parse-options.h"
   7#include "parse-events.h"
   8#include "exec_cmd.h"
   9#include "string.h"
  10#include "symbol.h"
  11#include "cache.h"
  12#include "header.h"
  13#include "debugfs.h"
  14#include "parse-events-flex.h"
  15#include "pmu.h"
  16
  17#define MAX_NAME_LEN 100
  18
  19struct event_symbol {
  20        u8              type;
  21        u64             config;
  22        const char      *symbol;
  23        const char      *alias;
  24};
  25
  26int parse_events_parse(struct list_head *list, struct list_head *list_tmp,
  27                       int *idx);
  28
  29#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x
  30#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
  31
  32static struct event_symbol event_symbols[] = {
  33  { CHW(CPU_CYCLES),                    "cpu-cycles",                   "cycles"                },
  34  { CHW(STALLED_CYCLES_FRONTEND),       "stalled-cycles-frontend",      "idle-cycles-frontend"  },
  35  { CHW(STALLED_CYCLES_BACKEND),        "stalled-cycles-backend",       "idle-cycles-backend"   },
  36  { CHW(INSTRUCTIONS),                  "instructions",                 ""                      },
  37  { CHW(CACHE_REFERENCES),              "cache-references",             ""                      },
  38  { CHW(CACHE_MISSES),                  "cache-misses",                 ""                      },
  39  { CHW(BRANCH_INSTRUCTIONS),           "branch-instructions",          "branches"              },
  40  { CHW(BRANCH_MISSES),                 "branch-misses",                ""                      },
  41  { CHW(BUS_CYCLES),                    "bus-cycles",                   ""                      },
  42  { CHW(REF_CPU_CYCLES),                "ref-cycles",                   ""                      },
  43
  44  { CSW(CPU_CLOCK),                     "cpu-clock",                    ""                      },
  45  { CSW(TASK_CLOCK),                    "task-clock",                   ""                      },
  46  { CSW(PAGE_FAULTS),                   "page-faults",                  "faults"                },
  47  { CSW(PAGE_FAULTS_MIN),               "minor-faults",                 ""                      },
  48  { CSW(PAGE_FAULTS_MAJ),               "major-faults",                 ""                      },
  49  { CSW(CONTEXT_SWITCHES),              "context-switches",             "cs"                    },
  50  { CSW(CPU_MIGRATIONS),                "cpu-migrations",               "migrations"            },
  51  { CSW(ALIGNMENT_FAULTS),              "alignment-faults",             ""                      },
  52  { CSW(EMULATION_FAULTS),              "emulation-faults",             ""                      },
  53};
  54
  55#define __PERF_EVENT_FIELD(config, name) \
  56        ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
  57
  58#define PERF_EVENT_RAW(config)          __PERF_EVENT_FIELD(config, RAW)
  59#define PERF_EVENT_CONFIG(config)       __PERF_EVENT_FIELD(config, CONFIG)
  60#define PERF_EVENT_TYPE(config)         __PERF_EVENT_FIELD(config, TYPE)
  61#define PERF_EVENT_ID(config)           __PERF_EVENT_FIELD(config, EVENT)
  62
  63static const char *hw_event_names[PERF_COUNT_HW_MAX] = {
  64        "cycles",
  65        "instructions",
  66        "cache-references",
  67        "cache-misses",
  68        "branches",
  69        "branch-misses",
  70        "bus-cycles",
  71        "stalled-cycles-frontend",
  72        "stalled-cycles-backend",
  73        "ref-cycles",
  74};
  75
  76static const char *sw_event_names[PERF_COUNT_SW_MAX] = {
  77        "cpu-clock",
  78        "task-clock",
  79        "page-faults",
  80        "context-switches",
  81        "CPU-migrations",
  82        "minor-faults",
  83        "major-faults",
  84        "alignment-faults",
  85        "emulation-faults",
  86};
  87
  88#define MAX_ALIASES 8
  89
  90static const char *hw_cache[PERF_COUNT_HW_CACHE_MAX][MAX_ALIASES] = {
  91 { "L1-dcache", "l1-d",         "l1d",          "L1-data",              },
  92 { "L1-icache", "l1-i",         "l1i",          "L1-instruction",       },
  93 { "LLC",       "L2",                                                   },
  94 { "dTLB",      "d-tlb",        "Data-TLB",                             },
  95 { "iTLB",      "i-tlb",        "Instruction-TLB",                      },
  96 { "branch",    "branches",     "bpu",          "btb",          "bpc",  },
  97 { "node",                                                              },
  98};
  99
 100static const char *hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][MAX_ALIASES] = {
 101 { "load",      "loads",        "read",                                 },
 102 { "store",     "stores",       "write",                                },
 103 { "prefetch",  "prefetches",   "speculative-read", "speculative-load", },
 104};
 105
 106static const char *hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX]
 107                                  [MAX_ALIASES] = {
 108 { "refs",      "Reference",    "ops",          "access",               },
 109 { "misses",    "miss",                                                 },
 110};
 111
 112#define C(x)            PERF_COUNT_HW_CACHE_##x
 113#define CACHE_READ      (1 << C(OP_READ))
 114#define CACHE_WRITE     (1 << C(OP_WRITE))
 115#define CACHE_PREFETCH  (1 << C(OP_PREFETCH))
 116#define COP(x)          (1 << x)
 117
 118/*
 119 * cache operartion stat
 120 * L1I : Read and prefetch only
 121 * ITLB and BPU : Read-only
 122 */
 123static unsigned long hw_cache_stat[C(MAX)] = {
 124 [C(L1D)]       = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
 125 [C(L1I)]       = (CACHE_READ | CACHE_PREFETCH),
 126 [C(LL)]        = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
 127 [C(DTLB)]      = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
 128 [C(ITLB)]      = (CACHE_READ),
 129 [C(BPU)]       = (CACHE_READ),
 130 [C(NODE)]      = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
 131};
 132
 133#define for_each_subsystem(sys_dir, sys_dirent, sys_next)              \
 134        while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next)        \
 135        if (sys_dirent.d_type == DT_DIR &&                                     \
 136           (strcmp(sys_dirent.d_name, ".")) &&                                 \
 137           (strcmp(sys_dirent.d_name, "..")))
 138
 139static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
 140{
 141        char evt_path[MAXPATHLEN];
 142        int fd;
 143
 144        snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path,
 145                        sys_dir->d_name, evt_dir->d_name);
 146        fd = open(evt_path, O_RDONLY);
 147        if (fd < 0)
 148                return -EINVAL;
 149        close(fd);
 150
 151        return 0;
 152}
 153
 154#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next)              \
 155        while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next)        \
 156        if (evt_dirent.d_type == DT_DIR &&                                     \
 157           (strcmp(evt_dirent.d_name, ".")) &&                                 \
 158           (strcmp(evt_dirent.d_name, "..")) &&                                \
 159           (!tp_event_has_id(&sys_dirent, &evt_dirent)))
 160
 161#define MAX_EVENT_LENGTH 512
 162
 163
 164struct tracepoint_path *tracepoint_id_to_path(u64 config)
 165{
 166        struct tracepoint_path *path = NULL;
 167        DIR *sys_dir, *evt_dir;
 168        struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
 169        char id_buf[24];
 170        int fd;
 171        u64 id;
 172        char evt_path[MAXPATHLEN];
 173        char dir_path[MAXPATHLEN];
 174
 175        if (debugfs_valid_mountpoint(tracing_events_path))
 176                return NULL;
 177
 178        sys_dir = opendir(tracing_events_path);
 179        if (!sys_dir)
 180                return NULL;
 181
 182        for_each_subsystem(sys_dir, sys_dirent, sys_next) {
 183
 184                snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
 185                         sys_dirent.d_name);
 186                evt_dir = opendir(dir_path);
 187                if (!evt_dir)
 188                        continue;
 189
 190                for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
 191
 192                        snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
 193                                 evt_dirent.d_name);
 194                        fd = open(evt_path, O_RDONLY);
 195                        if (fd < 0)
 196                                continue;
 197                        if (read(fd, id_buf, sizeof(id_buf)) < 0) {
 198                                close(fd);
 199                                continue;
 200                        }
 201                        close(fd);
 202                        id = atoll(id_buf);
 203                        if (id == config) {
 204                                closedir(evt_dir);
 205                                closedir(sys_dir);
 206                                path = zalloc(sizeof(*path));
 207                                path->system = malloc(MAX_EVENT_LENGTH);
 208                                if (!path->system) {
 209                                        free(path);
 210                                        return NULL;
 211                                }
 212                                path->name = malloc(MAX_EVENT_LENGTH);
 213                                if (!path->name) {
 214                                        free(path->system);
 215                                        free(path);
 216                                        return NULL;
 217                                }
 218                                strncpy(path->system, sys_dirent.d_name,
 219                                        MAX_EVENT_LENGTH);
 220                                strncpy(path->name, evt_dirent.d_name,
 221                                        MAX_EVENT_LENGTH);
 222                                return path;
 223                        }
 224                }
 225                closedir(evt_dir);
 226        }
 227
 228        closedir(sys_dir);
 229        return NULL;
 230}
 231
 232#define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1)
 233static const char *tracepoint_id_to_name(u64 config)
 234{
 235        static char buf[TP_PATH_LEN];
 236        struct tracepoint_path *path;
 237
 238        path = tracepoint_id_to_path(config);
 239        if (path) {
 240                snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name);
 241                free(path->name);
 242                free(path->system);
 243                free(path);
 244        } else
 245                snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown");
 246
 247        return buf;
 248}
 249
 250static int is_cache_op_valid(u8 cache_type, u8 cache_op)
 251{
 252        if (hw_cache_stat[cache_type] & COP(cache_op))
 253                return 1;       /* valid */
 254        else
 255                return 0;       /* invalid */
 256}
 257
 258static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
 259{
 260        static char name[50];
 261
 262        if (cache_result) {
 263                sprintf(name, "%s-%s-%s", hw_cache[cache_type][0],
 264                        hw_cache_op[cache_op][0],
 265                        hw_cache_result[cache_result][0]);
 266        } else {
 267                sprintf(name, "%s-%s", hw_cache[cache_type][0],
 268                        hw_cache_op[cache_op][1]);
 269        }
 270
 271        return name;
 272}
 273
 274const char *event_type(int type)
 275{
 276        switch (type) {
 277        case PERF_TYPE_HARDWARE:
 278                return "hardware";
 279
 280        case PERF_TYPE_SOFTWARE:
 281                return "software";
 282
 283        case PERF_TYPE_TRACEPOINT:
 284                return "tracepoint";
 285
 286        case PERF_TYPE_HW_CACHE:
 287                return "hardware-cache";
 288
 289        default:
 290                break;
 291        }
 292
 293        return "unknown";
 294}
 295
 296const char *event_name(struct perf_evsel *evsel)
 297{
 298        u64 config = evsel->attr.config;
 299        int type = evsel->attr.type;
 300
 301        if (evsel->name)
 302                return evsel->name;
 303
 304        return __event_name(type, config);
 305}
 306
 307const char *__event_name(int type, u64 config)
 308{
 309        static char buf[32];
 310
 311        if (type == PERF_TYPE_RAW) {
 312                sprintf(buf, "raw 0x%" PRIx64, config);
 313                return buf;
 314        }
 315
 316        switch (type) {
 317        case PERF_TYPE_HARDWARE:
 318                if (config < PERF_COUNT_HW_MAX && hw_event_names[config])
 319                        return hw_event_names[config];
 320                return "unknown-hardware";
 321
 322        case PERF_TYPE_HW_CACHE: {
 323                u8 cache_type, cache_op, cache_result;
 324
 325                cache_type   = (config >>  0) & 0xff;
 326                if (cache_type > PERF_COUNT_HW_CACHE_MAX)
 327                        return "unknown-ext-hardware-cache-type";
 328
 329                cache_op     = (config >>  8) & 0xff;
 330                if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX)
 331                        return "unknown-ext-hardware-cache-op";
 332
 333                cache_result = (config >> 16) & 0xff;
 334                if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX)
 335                        return "unknown-ext-hardware-cache-result";
 336
 337                if (!is_cache_op_valid(cache_type, cache_op))
 338                        return "invalid-cache";
 339
 340                return event_cache_name(cache_type, cache_op, cache_result);
 341        }
 342
 343        case PERF_TYPE_SOFTWARE:
 344                if (config < PERF_COUNT_SW_MAX && sw_event_names[config])
 345                        return sw_event_names[config];
 346                return "unknown-software";
 347
 348        case PERF_TYPE_TRACEPOINT:
 349                return tracepoint_id_to_name(config);
 350
 351        default:
 352                break;
 353        }
 354
 355        return "unknown";
 356}
 357
 358static int add_event(struct list_head *list, int *idx,
 359                     struct perf_event_attr *attr, char *name)
 360{
 361        struct perf_evsel *evsel;
 362
 363        event_attr_init(attr);
 364
 365        evsel = perf_evsel__new(attr, (*idx)++);
 366        if (!evsel)
 367                return -ENOMEM;
 368
 369        list_add_tail(&evsel->node, list);
 370
 371        evsel->name = strdup(name);
 372        return 0;
 373}
 374
 375static int parse_aliases(char *str, const char *names[][MAX_ALIASES], int size)
 376{
 377        int i, j;
 378        int n, longest = -1;
 379
 380        for (i = 0; i < size; i++) {
 381                for (j = 0; j < MAX_ALIASES && names[i][j]; j++) {
 382                        n = strlen(names[i][j]);
 383                        if (n > longest && !strncasecmp(str, names[i][j], n))
 384                                longest = n;
 385                }
 386                if (longest > 0)
 387                        return i;
 388        }
 389
 390        return -1;
 391}
 392
 393int parse_events_add_cache(struct list_head *list, int *idx,
 394                           char *type, char *op_result1, char *op_result2)
 395{
 396        struct perf_event_attr attr;
 397        char name[MAX_NAME_LEN];
 398        int cache_type = -1, cache_op = -1, cache_result = -1;
 399        char *op_result[2] = { op_result1, op_result2 };
 400        int i, n;
 401
 402        /*
 403         * No fallback - if we cannot get a clear cache type
 404         * then bail out:
 405         */
 406        cache_type = parse_aliases(type, hw_cache,
 407                                   PERF_COUNT_HW_CACHE_MAX);
 408        if (cache_type == -1)
 409                return -EINVAL;
 410
 411        n = snprintf(name, MAX_NAME_LEN, "%s", type);
 412
 413        for (i = 0; (i < 2) && (op_result[i]); i++) {
 414                char *str = op_result[i];
 415
 416                snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str);
 417
 418                if (cache_op == -1) {
 419                        cache_op = parse_aliases(str, hw_cache_op,
 420                                                 PERF_COUNT_HW_CACHE_OP_MAX);
 421                        if (cache_op >= 0) {
 422                                if (!is_cache_op_valid(cache_type, cache_op))
 423                                        return -EINVAL;
 424                                continue;
 425                        }
 426                }
 427
 428                if (cache_result == -1) {
 429                        cache_result = parse_aliases(str, hw_cache_result,
 430                                                PERF_COUNT_HW_CACHE_RESULT_MAX);
 431                        if (cache_result >= 0)
 432                                continue;
 433                }
 434        }
 435
 436        /*
 437         * Fall back to reads:
 438         */
 439        if (cache_op == -1)
 440                cache_op = PERF_COUNT_HW_CACHE_OP_READ;
 441
 442        /*
 443         * Fall back to accesses:
 444         */
 445        if (cache_result == -1)
 446                cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS;
 447
 448        memset(&attr, 0, sizeof(attr));
 449        attr.config = cache_type | (cache_op << 8) | (cache_result << 16);
 450        attr.type = PERF_TYPE_HW_CACHE;
 451        return add_event(list, idx, &attr, name);
 452}
 453
 454static int add_tracepoint(struct list_head *list, int *idx,
 455                          char *sys_name, char *evt_name)
 456{
 457        struct perf_event_attr attr;
 458        char name[MAX_NAME_LEN];
 459        char evt_path[MAXPATHLEN];
 460        char id_buf[4];
 461        u64 id;
 462        int fd;
 463
 464        snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path,
 465                 sys_name, evt_name);
 466
 467        fd = open(evt_path, O_RDONLY);
 468        if (fd < 0)
 469                return -1;
 470
 471        if (read(fd, id_buf, sizeof(id_buf)) < 0) {
 472                close(fd);
 473                return -1;
 474        }
 475
 476        close(fd);
 477        id = atoll(id_buf);
 478
 479        memset(&attr, 0, sizeof(attr));
 480        attr.config = id;
 481        attr.type = PERF_TYPE_TRACEPOINT;
 482        attr.sample_type |= PERF_SAMPLE_RAW;
 483        attr.sample_type |= PERF_SAMPLE_TIME;
 484        attr.sample_type |= PERF_SAMPLE_CPU;
 485        attr.sample_period = 1;
 486
 487        snprintf(name, MAX_NAME_LEN, "%s:%s", sys_name, evt_name);
 488        return add_event(list, idx, &attr, name);
 489}
 490
 491static int add_tracepoint_multi(struct list_head *list, int *idx,
 492                                char *sys_name, char *evt_name)
 493{
 494        char evt_path[MAXPATHLEN];
 495        struct dirent *evt_ent;
 496        DIR *evt_dir;
 497        int ret = 0;
 498
 499        snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name);
 500        evt_dir = opendir(evt_path);
 501        if (!evt_dir) {
 502                perror("Can't open event dir");
 503                return -1;
 504        }
 505
 506        while (!ret && (evt_ent = readdir(evt_dir))) {
 507                if (!strcmp(evt_ent->d_name, ".")
 508                    || !strcmp(evt_ent->d_name, "..")
 509                    || !strcmp(evt_ent->d_name, "enable")
 510                    || !strcmp(evt_ent->d_name, "filter"))
 511                        continue;
 512
 513                if (!strglobmatch(evt_ent->d_name, evt_name))
 514                        continue;
 515
 516                ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name);
 517        }
 518
 519        return ret;
 520}
 521
 522int parse_events_add_tracepoint(struct list_head *list, int *idx,
 523                                char *sys, char *event)
 524{
 525        int ret;
 526
 527        ret = debugfs_valid_mountpoint(tracing_events_path);
 528        if (ret)
 529                return ret;
 530
 531        return strpbrk(event, "*?") ?
 532               add_tracepoint_multi(list, idx, sys, event) :
 533               add_tracepoint(list, idx, sys, event);
 534}
 535
 536static int
 537parse_breakpoint_type(const char *type, struct perf_event_attr *attr)
 538{
 539        int i;
 540
 541        for (i = 0; i < 3; i++) {
 542                if (!type || !type[i])
 543                        break;
 544
 545                switch (type[i]) {
 546                case 'r':
 547                        attr->bp_type |= HW_BREAKPOINT_R;
 548                        break;
 549                case 'w':
 550                        attr->bp_type |= HW_BREAKPOINT_W;
 551                        break;
 552                case 'x':
 553                        attr->bp_type |= HW_BREAKPOINT_X;
 554                        break;
 555                default:
 556                        return -EINVAL;
 557                }
 558        }
 559
 560        if (!attr->bp_type) /* Default */
 561                attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;
 562
 563        return 0;
 564}
 565
 566int parse_events_add_breakpoint(struct list_head *list, int *idx,
 567                                void *ptr, char *type)
 568{
 569        struct perf_event_attr attr;
 570        char name[MAX_NAME_LEN];
 571
 572        memset(&attr, 0, sizeof(attr));
 573        attr.bp_addr = (unsigned long) ptr;
 574
 575        if (parse_breakpoint_type(type, &attr))
 576                return -EINVAL;
 577
 578        /*
 579         * We should find a nice way to override the access length
 580         * Provide some defaults for now
 581         */
 582        if (attr.bp_type == HW_BREAKPOINT_X)
 583                attr.bp_len = sizeof(long);
 584        else
 585                attr.bp_len = HW_BREAKPOINT_LEN_4;
 586
 587        attr.type = PERF_TYPE_BREAKPOINT;
 588
 589        snprintf(name, MAX_NAME_LEN, "mem:%p:%s", ptr, type ? type : "rw");
 590        return add_event(list, idx, &attr, name);
 591}
 592
 593static int config_term(struct perf_event_attr *attr,
 594                       struct parse_events__term *term)
 595{
 596        switch (term->type) {
 597        case PARSE_EVENTS__TERM_TYPE_CONFIG:
 598                attr->config = term->val.num;
 599                break;
 600        case PARSE_EVENTS__TERM_TYPE_CONFIG1:
 601                attr->config1 = term->val.num;
 602                break;
 603        case PARSE_EVENTS__TERM_TYPE_CONFIG2:
 604                attr->config2 = term->val.num;
 605                break;
 606        case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
 607                attr->sample_period = term->val.num;
 608                break;
 609        case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
 610                /*
 611                 * TODO uncomment when the field is available
 612                 * attr->branch_sample_type = term->val.num;
 613                 */
 614                break;
 615        default:
 616                return -EINVAL;
 617        }
 618        return 0;
 619}
 620
 621static int config_attr(struct perf_event_attr *attr,
 622                       struct list_head *head, int fail)
 623{
 624        struct parse_events__term *term;
 625
 626        list_for_each_entry(term, head, list)
 627                if (config_term(attr, term) && fail)
 628                        return -EINVAL;
 629
 630        return 0;
 631}
 632
 633int parse_events_add_numeric(struct list_head *list, int *idx,
 634                             unsigned long type, unsigned long config,
 635                             struct list_head *head_config)
 636{
 637        struct perf_event_attr attr;
 638
 639        memset(&attr, 0, sizeof(attr));
 640        attr.type = type;
 641        attr.config = config;
 642
 643        if (head_config &&
 644            config_attr(&attr, head_config, 1))
 645                return -EINVAL;
 646
 647        return add_event(list, idx, &attr,
 648                         (char *) __event_name(type, config));
 649}
 650
 651int parse_events_add_pmu(struct list_head *list, int *idx,
 652                         char *name, struct list_head *head_config)
 653{
 654        struct perf_event_attr attr;
 655        struct perf_pmu *pmu;
 656
 657        pmu = perf_pmu__find(name);
 658        if (!pmu)
 659                return -EINVAL;
 660
 661        memset(&attr, 0, sizeof(attr));
 662
 663        /*
 664         * Configure hardcoded terms first, no need to check
 665         * return value when called with fail == 0 ;)
 666         */
 667        config_attr(&attr, head_config, 0);
 668
 669        if (perf_pmu__config(pmu, &attr, head_config))
 670                return -EINVAL;
 671
 672        return add_event(list, idx, &attr, (char *) "pmu");
 673}
 674
 675void parse_events_update_lists(struct list_head *list_event,
 676                               struct list_head *list_all)
 677{
 678        /*
 679         * Called for single event definition. Update the
 680         * 'all event' list, and reinit the 'signle event'
 681         * list, for next event definition.
 682         */
 683        list_splice_tail(list_event, list_all);
 684        INIT_LIST_HEAD(list_event);
 685}
 686
 687int parse_events_modifier(struct list_head *list, char *str)
 688{
 689        struct perf_evsel *evsel;
 690        int exclude = 0, exclude_GH = 0;
 691        int eu = 0, ek = 0, eh = 0, eH = 0, eG = 0, precise = 0;
 692
 693        if (str == NULL)
 694                return 0;
 695
 696        while (*str) {
 697                if (*str == 'u') {
 698                        if (!exclude)
 699                                exclude = eu = ek = eh = 1;
 700                        eu = 0;
 701                } else if (*str == 'k') {
 702                        if (!exclude)
 703                                exclude = eu = ek = eh = 1;
 704                        ek = 0;
 705                } else if (*str == 'h') {
 706                        if (!exclude)
 707                                exclude = eu = ek = eh = 1;
 708                        eh = 0;
 709                } else if (*str == 'G') {
 710                        if (!exclude_GH)
 711                                exclude_GH = eG = eH = 1;
 712                        eG = 0;
 713                } else if (*str == 'H') {
 714                        if (!exclude_GH)
 715                                exclude_GH = eG = eH = 1;
 716                        eH = 0;
 717                } else if (*str == 'p') {
 718                        precise++;
 719                } else
 720                        break;
 721
 722                ++str;
 723        }
 724
 725        /*
 726         * precise ip:
 727         *
 728         *  0 - SAMPLE_IP can have arbitrary skid
 729         *  1 - SAMPLE_IP must have constant skid
 730         *  2 - SAMPLE_IP requested to have 0 skid
 731         *  3 - SAMPLE_IP must have 0 skid
 732         *
 733         *  See also PERF_RECORD_MISC_EXACT_IP
 734         */
 735        if (precise > 3)
 736                return -EINVAL;
 737
 738        list_for_each_entry(evsel, list, node) {
 739                evsel->attr.exclude_user   = eu;
 740                evsel->attr.exclude_kernel = ek;
 741                evsel->attr.exclude_hv     = eh;
 742                evsel->attr.precise_ip     = precise;
 743                evsel->attr.exclude_host   = eH;
 744                evsel->attr.exclude_guest  = eG;
 745        }
 746
 747        return 0;
 748}
 749
 750int parse_events(struct perf_evlist *evlist, const char *str, int unset __used)
 751{
 752        LIST_HEAD(list);
 753        LIST_HEAD(list_tmp);
 754        YY_BUFFER_STATE buffer;
 755        int ret, idx = evlist->nr_entries;
 756
 757        buffer = parse_events__scan_string(str);
 758
 759        ret = parse_events_parse(&list, &list_tmp, &idx);
 760
 761        parse_events__flush_buffer(buffer);
 762        parse_events__delete_buffer(buffer);
 763
 764        if (!ret) {
 765                int entries = idx - evlist->nr_entries;
 766                perf_evlist__splice_list_tail(evlist, &list, entries);
 767                return 0;
 768        }
 769
 770        /*
 771         * There are 2 users - builtin-record and builtin-test objects.
 772         * Both call perf_evlist__delete in case of error, so we dont
 773         * need to bother.
 774         */
 775        fprintf(stderr, "invalid or unsupported event: '%s'\n", str);
 776        fprintf(stderr, "Run 'perf list' for a list of valid events\n");
 777        return ret;
 778}
 779
 780int parse_events_option(const struct option *opt, const char *str,
 781                        int unset __used)
 782{
 783        struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
 784        return parse_events(evlist, str, unset);
 785}
 786
 787int parse_filter(const struct option *opt, const char *str,
 788                 int unset __used)
 789{
 790        struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
 791        struct perf_evsel *last = NULL;
 792
 793        if (evlist->nr_entries > 0)
 794                last = list_entry(evlist->entries.prev, struct perf_evsel, node);
 795
 796        if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) {
 797                fprintf(stderr,
 798                        "-F option should follow a -e tracepoint option\n");
 799                return -1;
 800        }
 801
 802        last->filter = strdup(str);
 803        if (last->filter == NULL) {
 804                fprintf(stderr, "not enough memory to hold filter string\n");
 805                return -1;
 806        }
 807
 808        return 0;
 809}
 810
 811static const char * const event_type_descriptors[] = {
 812        "Hardware event",
 813        "Software event",
 814        "Tracepoint event",
 815        "Hardware cache event",
 816        "Raw hardware event descriptor",
 817        "Hardware breakpoint",
 818};
 819
 820/*
 821 * Print the events from <debugfs_mount_point>/tracing/events
 822 */
 823
 824void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
 825{
 826        DIR *sys_dir, *evt_dir;
 827        struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
 828        char evt_path[MAXPATHLEN];
 829        char dir_path[MAXPATHLEN];
 830
 831        if (debugfs_valid_mountpoint(tracing_events_path))
 832                return;
 833
 834        sys_dir = opendir(tracing_events_path);
 835        if (!sys_dir)
 836                return;
 837
 838        for_each_subsystem(sys_dir, sys_dirent, sys_next) {
 839                if (subsys_glob != NULL && 
 840                    !strglobmatch(sys_dirent.d_name, subsys_glob))
 841                        continue;
 842
 843                snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
 844                         sys_dirent.d_name);
 845                evt_dir = opendir(dir_path);
 846                if (!evt_dir)
 847                        continue;
 848
 849                for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
 850                        if (event_glob != NULL && 
 851                            !strglobmatch(evt_dirent.d_name, event_glob))
 852                                continue;
 853
 854                        snprintf(evt_path, MAXPATHLEN, "%s:%s",
 855                                 sys_dirent.d_name, evt_dirent.d_name);
 856                        printf("  %-50s [%s]\n", evt_path,
 857                                event_type_descriptors[PERF_TYPE_TRACEPOINT]);
 858                }
 859                closedir(evt_dir);
 860        }
 861        closedir(sys_dir);
 862}
 863
 864/*
 865 * Check whether event is in <debugfs_mount_point>/tracing/events
 866 */
 867
 868int is_valid_tracepoint(const char *event_string)
 869{
 870        DIR *sys_dir, *evt_dir;
 871        struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
 872        char evt_path[MAXPATHLEN];
 873        char dir_path[MAXPATHLEN];
 874
 875        if (debugfs_valid_mountpoint(tracing_events_path))
 876                return 0;
 877
 878        sys_dir = opendir(tracing_events_path);
 879        if (!sys_dir)
 880                return 0;
 881
 882        for_each_subsystem(sys_dir, sys_dirent, sys_next) {
 883
 884                snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
 885                         sys_dirent.d_name);
 886                evt_dir = opendir(dir_path);
 887                if (!evt_dir)
 888                        continue;
 889
 890                for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
 891                        snprintf(evt_path, MAXPATHLEN, "%s:%s",
 892                                 sys_dirent.d_name, evt_dirent.d_name);
 893                        if (!strcmp(evt_path, event_string)) {
 894                                closedir(evt_dir);
 895                                closedir(sys_dir);
 896                                return 1;
 897                        }
 898                }
 899                closedir(evt_dir);
 900        }
 901        closedir(sys_dir);
 902        return 0;
 903}
 904
 905void print_events_type(u8 type)
 906{
 907        struct event_symbol *syms = event_symbols;
 908        unsigned int i;
 909        char name[64];
 910
 911        for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
 912                if (type != syms->type)
 913                        continue;
 914
 915                if (strlen(syms->alias))
 916                        snprintf(name, sizeof(name),  "%s OR %s",
 917                                 syms->symbol, syms->alias);
 918                else
 919                        snprintf(name, sizeof(name), "%s", syms->symbol);
 920
 921                printf("  %-50s [%s]\n", name,
 922                        event_type_descriptors[type]);
 923        }
 924}
 925
 926int print_hwcache_events(const char *event_glob)
 927{
 928        unsigned int type, op, i, printed = 0;
 929
 930        for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
 931                for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
 932                        /* skip invalid cache type */
 933                        if (!is_cache_op_valid(type, op))
 934                                continue;
 935
 936                        for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
 937                                char *name = event_cache_name(type, op, i);
 938
 939                                if (event_glob != NULL && !strglobmatch(name, event_glob))
 940                                        continue;
 941
 942                                printf("  %-50s [%s]\n", name,
 943                                        event_type_descriptors[PERF_TYPE_HW_CACHE]);
 944                                ++printed;
 945                        }
 946                }
 947        }
 948
 949        return printed;
 950}
 951
 952/*
 953 * Print the help text for the event symbols:
 954 */
 955void print_events(const char *event_glob)
 956{
 957        unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0;
 958        struct event_symbol *syms = event_symbols;
 959        char name[MAX_NAME_LEN];
 960
 961        printf("\n");
 962        printf("List of pre-defined events (to be used in -e):\n");
 963
 964        for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
 965                type = syms->type;
 966
 967                if (type != prev_type && printed) {
 968                        printf("\n");
 969                        printed = 0;
 970                        ntypes_printed++;
 971                }
 972
 973                if (event_glob != NULL && 
 974                    !(strglobmatch(syms->symbol, event_glob) ||
 975                      (syms->alias && strglobmatch(syms->alias, event_glob))))
 976                        continue;
 977
 978                if (strlen(syms->alias))
 979                        snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
 980                else
 981                        strncpy(name, syms->symbol, MAX_NAME_LEN);
 982                printf("  %-50s [%s]\n", name,
 983                        event_type_descriptors[type]);
 984
 985                prev_type = type;
 986                ++printed;
 987        }
 988
 989        if (ntypes_printed) {
 990                printed = 0;
 991                printf("\n");
 992        }
 993        print_hwcache_events(event_glob);
 994
 995        if (event_glob != NULL)
 996                return;
 997
 998        printf("\n");
 999        printf("  %-50s [%s]\n",
1000               "rNNN",
1001               event_type_descriptors[PERF_TYPE_RAW]);
1002        printf("  %-50s [%s]\n",
1003               "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
1004               event_type_descriptors[PERF_TYPE_RAW]);
1005        printf("   (see 'perf list --help' on how to encode it)\n");
1006        printf("\n");
1007
1008        printf("  %-50s [%s]\n",
1009                        "mem:<addr>[:access]",
1010                        event_type_descriptors[PERF_TYPE_BREAKPOINT]);
1011        printf("\n");
1012
1013        print_tracepoint_events(NULL, NULL);
1014}
1015
1016int parse_events__is_hardcoded_term(struct parse_events__term *term)
1017{
1018        return term->type <= PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX;
1019}
1020
1021int parse_events__new_term(struct parse_events__term **_term, int type,
1022                           char *config, char *str, long num)
1023{
1024        struct parse_events__term *term;
1025
1026        term = zalloc(sizeof(*term));
1027        if (!term)
1028                return -ENOMEM;
1029
1030        INIT_LIST_HEAD(&term->list);
1031        term->type = type;
1032        term->config = config;
1033
1034        switch (type) {
1035        case PARSE_EVENTS__TERM_TYPE_CONFIG:
1036        case PARSE_EVENTS__TERM_TYPE_CONFIG1:
1037        case PARSE_EVENTS__TERM_TYPE_CONFIG2:
1038        case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
1039        case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
1040        case PARSE_EVENTS__TERM_TYPE_NUM:
1041                term->val.num = num;
1042                break;
1043        case PARSE_EVENTS__TERM_TYPE_STR:
1044                term->val.str = str;
1045                break;
1046        default:
1047                return -EINVAL;
1048        }
1049
1050        *_term = term;
1051        return 0;
1052}
1053
1054void parse_events__free_terms(struct list_head *terms)
1055{
1056        struct parse_events__term *term, *h;
1057
1058        list_for_each_entry_safe(term, h, terms, list)
1059                free(term);
1060
1061        free(terms);
1062}
1063