1d2709c7cSDavid Howells #include <linux/hw_breakpoint.h> 286470930SIngo Molnar #include "util.h" 36b58e7f1SUlrich Drepper #include "../perf.h" 4361c99a6SArnaldo Carvalho de Melo #include "evlist.h" 569aad6f1SArnaldo Carvalho de Melo #include "evsel.h" 686470930SIngo Molnar #include "parse-options.h" 786470930SIngo Molnar #include "parse-events.h" 886470930SIngo Molnar #include "exec_cmd.h" 986470930SIngo Molnar #include "string.h" 105aab621bSArnaldo Carvalho de Melo #include "symbol.h" 115beeded1SJason Baron #include "cache.h" 128755a8f2SArjan van de Ven #include "header.h" 13549104f2SClark Williams #include "debugfs.h" 14ac20de6fSZheng Yan #include "parse-events-bison.h" 1590e2b22dSJiri Olsa #define YY_EXTRA_TYPE int 1689812fc8SJiri Olsa #include "parse-events-flex.h" 175f537a26SJiri Olsa #include "pmu.h" 1889812fc8SJiri Olsa 1989812fc8SJiri Olsa #define MAX_NAME_LEN 100 2086470930SIngo Molnar 2186470930SIngo Molnar struct event_symbol { 2283a0944fSIngo Molnar const char *symbol; 2383a0944fSIngo Molnar const char *alias; 2486470930SIngo Molnar }; 2586470930SIngo Molnar 2682ba1f2fSJiri Olsa #ifdef PARSER_DEBUG 2782ba1f2fSJiri Olsa extern int parse_events_debug; 2882ba1f2fSJiri Olsa #endif 29ac20de6fSZheng Yan int parse_events_parse(void *data, void *scanner); 30bcd3279fSFrederic Weisbecker 311dc12760SJiri Olsa static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = { 321dc12760SJiri Olsa [PERF_COUNT_HW_CPU_CYCLES] = { 331dc12760SJiri Olsa .symbol = "cpu-cycles", 341dc12760SJiri Olsa .alias = "cycles", 351dc12760SJiri Olsa }, 361dc12760SJiri Olsa [PERF_COUNT_HW_INSTRUCTIONS] = { 371dc12760SJiri Olsa .symbol = "instructions", 381dc12760SJiri Olsa .alias = "", 391dc12760SJiri Olsa }, 401dc12760SJiri Olsa [PERF_COUNT_HW_CACHE_REFERENCES] = { 411dc12760SJiri Olsa .symbol = "cache-references", 421dc12760SJiri Olsa .alias = "", 431dc12760SJiri Olsa }, 441dc12760SJiri Olsa [PERF_COUNT_HW_CACHE_MISSES] = { 451dc12760SJiri Olsa .symbol = "cache-misses", 461dc12760SJiri Olsa .alias = "", 471dc12760SJiri Olsa }, 481dc12760SJiri Olsa [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 491dc12760SJiri Olsa .symbol = "branch-instructions", 501dc12760SJiri Olsa .alias = "branches", 511dc12760SJiri Olsa }, 521dc12760SJiri Olsa [PERF_COUNT_HW_BRANCH_MISSES] = { 531dc12760SJiri Olsa .symbol = "branch-misses", 541dc12760SJiri Olsa .alias = "", 551dc12760SJiri Olsa }, 561dc12760SJiri Olsa [PERF_COUNT_HW_BUS_CYCLES] = { 571dc12760SJiri Olsa .symbol = "bus-cycles", 581dc12760SJiri Olsa .alias = "", 591dc12760SJiri Olsa }, 601dc12760SJiri Olsa [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = { 611dc12760SJiri Olsa .symbol = "stalled-cycles-frontend", 621dc12760SJiri Olsa .alias = "idle-cycles-frontend", 631dc12760SJiri Olsa }, 641dc12760SJiri Olsa [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = { 651dc12760SJiri Olsa .symbol = "stalled-cycles-backend", 661dc12760SJiri Olsa .alias = "idle-cycles-backend", 671dc12760SJiri Olsa }, 681dc12760SJiri Olsa [PERF_COUNT_HW_REF_CPU_CYCLES] = { 691dc12760SJiri Olsa .symbol = "ref-cycles", 701dc12760SJiri Olsa .alias = "", 711dc12760SJiri Olsa }, 721dc12760SJiri Olsa }; 7386470930SIngo Molnar 741dc12760SJiri Olsa static struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { 751dc12760SJiri Olsa [PERF_COUNT_SW_CPU_CLOCK] = { 761dc12760SJiri Olsa .symbol = "cpu-clock", 771dc12760SJiri Olsa .alias = "", 781dc12760SJiri Olsa }, 791dc12760SJiri Olsa [PERF_COUNT_SW_TASK_CLOCK] = { 801dc12760SJiri Olsa .symbol = "task-clock", 811dc12760SJiri Olsa .alias = "", 821dc12760SJiri Olsa }, 831dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS] = { 841dc12760SJiri Olsa .symbol = "page-faults", 851dc12760SJiri Olsa .alias = "faults", 861dc12760SJiri Olsa }, 871dc12760SJiri Olsa [PERF_COUNT_SW_CONTEXT_SWITCHES] = { 881dc12760SJiri Olsa .symbol = "context-switches", 891dc12760SJiri Olsa .alias = "cs", 901dc12760SJiri Olsa }, 911dc12760SJiri Olsa [PERF_COUNT_SW_CPU_MIGRATIONS] = { 921dc12760SJiri Olsa .symbol = "cpu-migrations", 931dc12760SJiri Olsa .alias = "migrations", 941dc12760SJiri Olsa }, 951dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS_MIN] = { 961dc12760SJiri Olsa .symbol = "minor-faults", 971dc12760SJiri Olsa .alias = "", 981dc12760SJiri Olsa }, 991dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS_MAJ] = { 1001dc12760SJiri Olsa .symbol = "major-faults", 1011dc12760SJiri Olsa .alias = "", 1021dc12760SJiri Olsa }, 1031dc12760SJiri Olsa [PERF_COUNT_SW_ALIGNMENT_FAULTS] = { 1041dc12760SJiri Olsa .symbol = "alignment-faults", 1051dc12760SJiri Olsa .alias = "", 1061dc12760SJiri Olsa }, 1071dc12760SJiri Olsa [PERF_COUNT_SW_EMULATION_FAULTS] = { 1081dc12760SJiri Olsa .symbol = "emulation-faults", 1091dc12760SJiri Olsa .alias = "", 1101dc12760SJiri Olsa }, 11186470930SIngo Molnar }; 11286470930SIngo Molnar 113cdd6c482SIngo Molnar #define __PERF_EVENT_FIELD(config, name) \ 114cdd6c482SIngo Molnar ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 11586470930SIngo Molnar 116cdd6c482SIngo Molnar #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 117cdd6c482SIngo Molnar #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 118cdd6c482SIngo Molnar #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 119cdd6c482SIngo Molnar #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 12086470930SIngo Molnar 1216b58e7f1SUlrich Drepper #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 122f6bdafefSJason Baron while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 1236b58e7f1SUlrich Drepper if (sys_dirent.d_type == DT_DIR && \ 124f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".")) && \ 125f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".."))) 126f6bdafefSJason Baron 127ae07b63fSPeter Zijlstra static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 128ae07b63fSPeter Zijlstra { 129ae07b63fSPeter Zijlstra char evt_path[MAXPATHLEN]; 130ae07b63fSPeter Zijlstra int fd; 131ae07b63fSPeter Zijlstra 132ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path, 133ae07b63fSPeter Zijlstra sys_dir->d_name, evt_dir->d_name); 134ae07b63fSPeter Zijlstra fd = open(evt_path, O_RDONLY); 135ae07b63fSPeter Zijlstra if (fd < 0) 136ae07b63fSPeter Zijlstra return -EINVAL; 137ae07b63fSPeter Zijlstra close(fd); 138ae07b63fSPeter Zijlstra 139ae07b63fSPeter Zijlstra return 0; 140ae07b63fSPeter Zijlstra } 141ae07b63fSPeter Zijlstra 1426b58e7f1SUlrich Drepper #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ 143f6bdafefSJason Baron while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 1446b58e7f1SUlrich Drepper if (evt_dirent.d_type == DT_DIR && \ 145f6bdafefSJason Baron (strcmp(evt_dirent.d_name, ".")) && \ 146ae07b63fSPeter Zijlstra (strcmp(evt_dirent.d_name, "..")) && \ 147ae07b63fSPeter Zijlstra (!tp_event_has_id(&sys_dirent, &evt_dirent))) 148f6bdafefSJason Baron 149270bbbe8SLi Zefan #define MAX_EVENT_LENGTH 512 150f6bdafefSJason Baron 151f6bdafefSJason Baron 1521ef2ed10SFrederic Weisbecker struct tracepoint_path *tracepoint_id_to_path(u64 config) 153f6bdafefSJason Baron { 1541ef2ed10SFrederic Weisbecker struct tracepoint_path *path = NULL; 155f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 156f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1578aa8a7c8SStephane Eranian char id_buf[24]; 158725b1368SEric Dumazet int fd; 159f6bdafefSJason Baron u64 id; 160f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 161725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 162f6bdafefSJason Baron 163ebf294bfSArnaldo Carvalho de Melo if (debugfs_valid_mountpoint(tracing_events_path)) 1641ef2ed10SFrederic Weisbecker return NULL; 165f6bdafefSJason Baron 166ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 167f6bdafefSJason Baron if (!sys_dir) 168725b1368SEric Dumazet return NULL; 169f6bdafefSJason Baron 1706b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 171725b1368SEric Dumazet 172ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 173725b1368SEric Dumazet sys_dirent.d_name); 174725b1368SEric Dumazet evt_dir = opendir(dir_path); 175725b1368SEric Dumazet if (!evt_dir) 1766b58e7f1SUlrich Drepper continue; 177725b1368SEric Dumazet 1786b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 179725b1368SEric Dumazet 180725b1368SEric Dumazet snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 181f6bdafefSJason Baron evt_dirent.d_name); 182725b1368SEric Dumazet fd = open(evt_path, O_RDONLY); 183f6bdafefSJason Baron if (fd < 0) 184f6bdafefSJason Baron continue; 185f6bdafefSJason Baron if (read(fd, id_buf, sizeof(id_buf)) < 0) { 186f6bdafefSJason Baron close(fd); 187f6bdafefSJason Baron continue; 188f6bdafefSJason Baron } 189f6bdafefSJason Baron close(fd); 190f6bdafefSJason Baron id = atoll(id_buf); 191f6bdafefSJason Baron if (id == config) { 192f6bdafefSJason Baron closedir(evt_dir); 193f6bdafefSJason Baron closedir(sys_dir); 19459b4caebSJulia Lawall path = zalloc(sizeof(*path)); 1951ef2ed10SFrederic Weisbecker path->system = malloc(MAX_EVENT_LENGTH); 1961ef2ed10SFrederic Weisbecker if (!path->system) { 1971ef2ed10SFrederic Weisbecker free(path); 1981ef2ed10SFrederic Weisbecker return NULL; 1991ef2ed10SFrederic Weisbecker } 2001ef2ed10SFrederic Weisbecker path->name = malloc(MAX_EVENT_LENGTH); 2011ef2ed10SFrederic Weisbecker if (!path->name) { 2021ef2ed10SFrederic Weisbecker free(path->system); 2031ef2ed10SFrederic Weisbecker free(path); 2041ef2ed10SFrederic Weisbecker return NULL; 2051ef2ed10SFrederic Weisbecker } 2061ef2ed10SFrederic Weisbecker strncpy(path->system, sys_dirent.d_name, 2071ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2081ef2ed10SFrederic Weisbecker strncpy(path->name, evt_dirent.d_name, 2091ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2101ef2ed10SFrederic Weisbecker return path; 211f6bdafefSJason Baron } 212f6bdafefSJason Baron } 213f6bdafefSJason Baron closedir(evt_dir); 214f6bdafefSJason Baron } 215f6bdafefSJason Baron 216f6bdafefSJason Baron closedir(sys_dir); 2171ef2ed10SFrederic Weisbecker return NULL; 2181ef2ed10SFrederic Weisbecker } 2191ef2ed10SFrederic Weisbecker 2201424dc96SDavid Ahern const char *event_type(int type) 2211424dc96SDavid Ahern { 2221424dc96SDavid Ahern switch (type) { 2231424dc96SDavid Ahern case PERF_TYPE_HARDWARE: 2241424dc96SDavid Ahern return "hardware"; 2251424dc96SDavid Ahern 2261424dc96SDavid Ahern case PERF_TYPE_SOFTWARE: 2271424dc96SDavid Ahern return "software"; 2281424dc96SDavid Ahern 2291424dc96SDavid Ahern case PERF_TYPE_TRACEPOINT: 2301424dc96SDavid Ahern return "tracepoint"; 2311424dc96SDavid Ahern 2321424dc96SDavid Ahern case PERF_TYPE_HW_CACHE: 2331424dc96SDavid Ahern return "hardware-cache"; 2341424dc96SDavid Ahern 2351424dc96SDavid Ahern default: 2361424dc96SDavid Ahern break; 2371424dc96SDavid Ahern } 2381424dc96SDavid Ahern 2391424dc96SDavid Ahern return "unknown"; 2401424dc96SDavid Ahern } 2411424dc96SDavid Ahern 2427ae92e74SYan, Zheng 2437ae92e74SYan, Zheng 2447ae92e74SYan, Zheng static int __add_event(struct list_head **_list, int *idx, 2457ae92e74SYan, Zheng struct perf_event_attr *attr, 2467ae92e74SYan, Zheng char *name, struct cpu_map *cpus) 24789812fc8SJiri Olsa { 24889812fc8SJiri Olsa struct perf_evsel *evsel; 249b847cbdcSJiri Olsa struct list_head *list = *_list; 250b847cbdcSJiri Olsa 251b847cbdcSJiri Olsa if (!list) { 252b847cbdcSJiri Olsa list = malloc(sizeof(*list)); 253b847cbdcSJiri Olsa if (!list) 254b847cbdcSJiri Olsa return -ENOMEM; 255b847cbdcSJiri Olsa INIT_LIST_HEAD(list); 256b847cbdcSJiri Olsa } 25789812fc8SJiri Olsa 25889812fc8SJiri Olsa event_attr_init(attr); 25989812fc8SJiri Olsa 26089812fc8SJiri Olsa evsel = perf_evsel__new(attr, (*idx)++); 261b847cbdcSJiri Olsa if (!evsel) { 262b847cbdcSJiri Olsa free(list); 26389812fc8SJiri Olsa return -ENOMEM; 264b847cbdcSJiri Olsa } 26589812fc8SJiri Olsa 2667ae92e74SYan, Zheng evsel->cpus = cpus; 2679db1763cSArnaldo Carvalho de Melo if (name) 26889812fc8SJiri Olsa evsel->name = strdup(name); 269b847cbdcSJiri Olsa list_add_tail(&evsel->node, list); 270b847cbdcSJiri Olsa *_list = list; 27189812fc8SJiri Olsa return 0; 27289812fc8SJiri Olsa } 27389812fc8SJiri Olsa 2747ae92e74SYan, Zheng static int add_event(struct list_head **_list, int *idx, 2757ae92e74SYan, Zheng struct perf_event_attr *attr, char *name) 2767ae92e74SYan, Zheng { 2777ae92e74SYan, Zheng return __add_event(_list, idx, attr, name, NULL); 2787ae92e74SYan, Zheng } 2797ae92e74SYan, Zheng 2800b668bc9SArnaldo Carvalho de Melo static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) 28186470930SIngo Molnar { 28286470930SIngo Molnar int i, j; 28361c45981SPaul Mackerras int n, longest = -1; 28486470930SIngo Molnar 28586470930SIngo Molnar for (i = 0; i < size; i++) { 2860b668bc9SArnaldo Carvalho de Melo for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) { 28761c45981SPaul Mackerras n = strlen(names[i][j]); 28889812fc8SJiri Olsa if (n > longest && !strncasecmp(str, names[i][j], n)) 28961c45981SPaul Mackerras longest = n; 29061c45981SPaul Mackerras } 29189812fc8SJiri Olsa if (longest > 0) 29286470930SIngo Molnar return i; 29386470930SIngo Molnar } 29486470930SIngo Molnar 2958953645fSIngo Molnar return -1; 29686470930SIngo Molnar } 29786470930SIngo Molnar 298b847cbdcSJiri Olsa int parse_events_add_cache(struct list_head **list, int *idx, 29989812fc8SJiri Olsa char *type, char *op_result1, char *op_result2) 30086470930SIngo Molnar { 30189812fc8SJiri Olsa struct perf_event_attr attr; 30289812fc8SJiri Olsa char name[MAX_NAME_LEN]; 30361c45981SPaul Mackerras int cache_type = -1, cache_op = -1, cache_result = -1; 30489812fc8SJiri Olsa char *op_result[2] = { op_result1, op_result2 }; 30589812fc8SJiri Olsa int i, n; 30686470930SIngo Molnar 30786470930SIngo Molnar /* 30886470930SIngo Molnar * No fallback - if we cannot get a clear cache type 30986470930SIngo Molnar * then bail out: 31086470930SIngo Molnar */ 3110b668bc9SArnaldo Carvalho de Melo cache_type = parse_aliases(type, perf_evsel__hw_cache, 31289812fc8SJiri Olsa PERF_COUNT_HW_CACHE_MAX); 31386470930SIngo Molnar if (cache_type == -1) 31489812fc8SJiri Olsa return -EINVAL; 31586470930SIngo Molnar 31689812fc8SJiri Olsa n = snprintf(name, MAX_NAME_LEN, "%s", type); 31789812fc8SJiri Olsa 31889812fc8SJiri Olsa for (i = 0; (i < 2) && (op_result[i]); i++) { 31989812fc8SJiri Olsa char *str = op_result[i]; 32089812fc8SJiri Olsa 321275ef387SJiri Olsa n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str); 32261c45981SPaul Mackerras 32361c45981SPaul Mackerras if (cache_op == -1) { 3240b668bc9SArnaldo Carvalho de Melo cache_op = parse_aliases(str, perf_evsel__hw_cache_op, 32561c45981SPaul Mackerras PERF_COUNT_HW_CACHE_OP_MAX); 32661c45981SPaul Mackerras if (cache_op >= 0) { 3270b668bc9SArnaldo Carvalho de Melo if (!perf_evsel__is_cache_op_valid(cache_type, cache_op)) 32889812fc8SJiri Olsa return -EINVAL; 32961c45981SPaul Mackerras continue; 33061c45981SPaul Mackerras } 33161c45981SPaul Mackerras } 33261c45981SPaul Mackerras 33361c45981SPaul Mackerras if (cache_result == -1) { 3340b668bc9SArnaldo Carvalho de Melo cache_result = parse_aliases(str, perf_evsel__hw_cache_result, 33561c45981SPaul Mackerras PERF_COUNT_HW_CACHE_RESULT_MAX); 33661c45981SPaul Mackerras if (cache_result >= 0) 33761c45981SPaul Mackerras continue; 33861c45981SPaul Mackerras } 33961c45981SPaul Mackerras } 34061c45981SPaul Mackerras 34186470930SIngo Molnar /* 34286470930SIngo Molnar * Fall back to reads: 34386470930SIngo Molnar */ 3448953645fSIngo Molnar if (cache_op == -1) 3458953645fSIngo Molnar cache_op = PERF_COUNT_HW_CACHE_OP_READ; 34686470930SIngo Molnar 34786470930SIngo Molnar /* 34886470930SIngo Molnar * Fall back to accesses: 34986470930SIngo Molnar */ 35086470930SIngo Molnar if (cache_result == -1) 35186470930SIngo Molnar cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 35286470930SIngo Molnar 35389812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 35489812fc8SJiri Olsa attr.config = cache_type | (cache_op << 8) | (cache_result << 16); 35589812fc8SJiri Olsa attr.type = PERF_TYPE_HW_CACHE; 35689812fc8SJiri Olsa return add_event(list, idx, &attr, name); 35786470930SIngo Molnar } 35886470930SIngo Molnar 35982fe1c29SArnaldo Carvalho de Melo static int add_tracepoint(struct list_head **listp, int *idx, 36089812fc8SJiri Olsa char *sys_name, char *evt_name) 361bcd3279fSFrederic Weisbecker { 36282fe1c29SArnaldo Carvalho de Melo struct perf_evsel *evsel; 36382fe1c29SArnaldo Carvalho de Melo struct list_head *list = *listp; 364bcd3279fSFrederic Weisbecker 36582fe1c29SArnaldo Carvalho de Melo if (!list) { 36682fe1c29SArnaldo Carvalho de Melo list = malloc(sizeof(*list)); 36782fe1c29SArnaldo Carvalho de Melo if (!list) 36882fe1c29SArnaldo Carvalho de Melo return -ENOMEM; 36982fe1c29SArnaldo Carvalho de Melo INIT_LIST_HEAD(list); 370bcd3279fSFrederic Weisbecker } 371bcd3279fSFrederic Weisbecker 37282fe1c29SArnaldo Carvalho de Melo evsel = perf_evsel__newtp(sys_name, evt_name, (*idx)++); 37382fe1c29SArnaldo Carvalho de Melo if (!evsel) { 37482fe1c29SArnaldo Carvalho de Melo free(list); 37582fe1c29SArnaldo Carvalho de Melo return -ENOMEM; 37682fe1c29SArnaldo Carvalho de Melo } 377bcd3279fSFrederic Weisbecker 37882fe1c29SArnaldo Carvalho de Melo list_add_tail(&evsel->node, list); 37982fe1c29SArnaldo Carvalho de Melo *listp = list; 38082fe1c29SArnaldo Carvalho de Melo return 0; 381bcd3279fSFrederic Weisbecker } 382bcd3279fSFrederic Weisbecker 383f35488f9SJiri Olsa static int add_tracepoint_multi_event(struct list_head **list, int *idx, 38489812fc8SJiri Olsa char *sys_name, char *evt_name) 385bcd3279fSFrederic Weisbecker { 386bcd3279fSFrederic Weisbecker char evt_path[MAXPATHLEN]; 387bcd3279fSFrederic Weisbecker struct dirent *evt_ent; 388bcd3279fSFrederic Weisbecker DIR *evt_dir; 38989812fc8SJiri Olsa int ret = 0; 390bcd3279fSFrederic Weisbecker 391ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); 392bcd3279fSFrederic Weisbecker evt_dir = opendir(evt_path); 393bcd3279fSFrederic Weisbecker if (!evt_dir) { 394bcd3279fSFrederic Weisbecker perror("Can't open event dir"); 39589812fc8SJiri Olsa return -1; 396bcd3279fSFrederic Weisbecker } 397bcd3279fSFrederic Weisbecker 39889812fc8SJiri Olsa while (!ret && (evt_ent = readdir(evt_dir))) { 399bcd3279fSFrederic Weisbecker if (!strcmp(evt_ent->d_name, ".") 400bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "..") 401bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "enable") 402bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "filter")) 403bcd3279fSFrederic Weisbecker continue; 404bcd3279fSFrederic Weisbecker 40589812fc8SJiri Olsa if (!strglobmatch(evt_ent->d_name, evt_name)) 406fb1d2edfSMasami Hiramatsu continue; 407fb1d2edfSMasami Hiramatsu 40889812fc8SJiri Olsa ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name); 409bcd3279fSFrederic Weisbecker } 410bcd3279fSFrederic Weisbecker 4110bd3f084SJiri Olsa closedir(evt_dir); 41289812fc8SJiri Olsa return ret; 413bcd3279fSFrederic Weisbecker } 414bcd3279fSFrederic Weisbecker 415f35488f9SJiri Olsa static int add_tracepoint_event(struct list_head **list, int *idx, 416f35488f9SJiri Olsa char *sys_name, char *evt_name) 417f35488f9SJiri Olsa { 418f35488f9SJiri Olsa return strpbrk(evt_name, "*?") ? 419f35488f9SJiri Olsa add_tracepoint_multi_event(list, idx, sys_name, evt_name) : 420f35488f9SJiri Olsa add_tracepoint(list, idx, sys_name, evt_name); 421f35488f9SJiri Olsa } 422f35488f9SJiri Olsa 423f35488f9SJiri Olsa static int add_tracepoint_multi_sys(struct list_head **list, int *idx, 424f35488f9SJiri Olsa char *sys_name, char *evt_name) 425f35488f9SJiri Olsa { 426f35488f9SJiri Olsa struct dirent *events_ent; 427f35488f9SJiri Olsa DIR *events_dir; 428f35488f9SJiri Olsa int ret = 0; 429f35488f9SJiri Olsa 430f35488f9SJiri Olsa events_dir = opendir(tracing_events_path); 431f35488f9SJiri Olsa if (!events_dir) { 432f35488f9SJiri Olsa perror("Can't open event dir"); 433f35488f9SJiri Olsa return -1; 434f35488f9SJiri Olsa } 435f35488f9SJiri Olsa 436f35488f9SJiri Olsa while (!ret && (events_ent = readdir(events_dir))) { 437f35488f9SJiri Olsa if (!strcmp(events_ent->d_name, ".") 438f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "..") 439f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "enable") 440f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "header_event") 441f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "header_page")) 442f35488f9SJiri Olsa continue; 443f35488f9SJiri Olsa 444f35488f9SJiri Olsa if (!strglobmatch(events_ent->d_name, sys_name)) 445f35488f9SJiri Olsa continue; 446f35488f9SJiri Olsa 447f35488f9SJiri Olsa ret = add_tracepoint_event(list, idx, events_ent->d_name, 448f35488f9SJiri Olsa evt_name); 449f35488f9SJiri Olsa } 450f35488f9SJiri Olsa 451f35488f9SJiri Olsa closedir(events_dir); 452f35488f9SJiri Olsa return ret; 453f35488f9SJiri Olsa } 454f35488f9SJiri Olsa 455b847cbdcSJiri Olsa int parse_events_add_tracepoint(struct list_head **list, int *idx, 45689812fc8SJiri Olsa char *sys, char *event) 457f6bdafefSJason Baron { 45889812fc8SJiri Olsa int ret; 459f6bdafefSJason Baron 46089812fc8SJiri Olsa ret = debugfs_valid_mountpoint(tracing_events_path); 46189812fc8SJiri Olsa if (ret) 46289812fc8SJiri Olsa return ret; 463f6bdafefSJason Baron 464f35488f9SJiri Olsa if (strpbrk(sys, "*?")) 465f35488f9SJiri Olsa return add_tracepoint_multi_sys(list, idx, sys, event); 466f35488f9SJiri Olsa else 467f35488f9SJiri Olsa return add_tracepoint_event(list, idx, sys, event); 4683a9f131fSFrederic Weisbecker } 4693a9f131fSFrederic Weisbecker 47089812fc8SJiri Olsa static int 47189812fc8SJiri Olsa parse_breakpoint_type(const char *type, struct perf_event_attr *attr) 4721b290d67SFrederic Weisbecker { 4731b290d67SFrederic Weisbecker int i; 4741b290d67SFrederic Weisbecker 4751b290d67SFrederic Weisbecker for (i = 0; i < 3; i++) { 47689812fc8SJiri Olsa if (!type || !type[i]) 4771b290d67SFrederic Weisbecker break; 4781b290d67SFrederic Weisbecker 4797582732fSJiri Olsa #define CHECK_SET_TYPE(bit) \ 4807582732fSJiri Olsa do { \ 4817582732fSJiri Olsa if (attr->bp_type & bit) \ 4827582732fSJiri Olsa return -EINVAL; \ 4837582732fSJiri Olsa else \ 4847582732fSJiri Olsa attr->bp_type |= bit; \ 4857582732fSJiri Olsa } while (0) 4867582732fSJiri Olsa 4871b290d67SFrederic Weisbecker switch (type[i]) { 4881b290d67SFrederic Weisbecker case 'r': 4897582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_R); 4901b290d67SFrederic Weisbecker break; 4911b290d67SFrederic Weisbecker case 'w': 4927582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_W); 4931b290d67SFrederic Weisbecker break; 4941b290d67SFrederic Weisbecker case 'x': 4957582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_X); 4961b290d67SFrederic Weisbecker break; 4971b290d67SFrederic Weisbecker default: 49889812fc8SJiri Olsa return -EINVAL; 4991b290d67SFrederic Weisbecker } 5001b290d67SFrederic Weisbecker } 50189812fc8SJiri Olsa 5027582732fSJiri Olsa #undef CHECK_SET_TYPE 5037582732fSJiri Olsa 5041b290d67SFrederic Weisbecker if (!attr->bp_type) /* Default */ 5051b290d67SFrederic Weisbecker attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 5061b290d67SFrederic Weisbecker 50789812fc8SJiri Olsa return 0; 5081b290d67SFrederic Weisbecker } 5091b290d67SFrederic Weisbecker 510b847cbdcSJiri Olsa int parse_events_add_breakpoint(struct list_head **list, int *idx, 51189812fc8SJiri Olsa void *ptr, char *type) 5121b290d67SFrederic Weisbecker { 51389812fc8SJiri Olsa struct perf_event_attr attr; 5141b290d67SFrederic Weisbecker 51589812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 5169fafd98fSJiri Olsa attr.bp_addr = (unsigned long) ptr; 5171b290d67SFrederic Weisbecker 51889812fc8SJiri Olsa if (parse_breakpoint_type(type, &attr)) 51989812fc8SJiri Olsa return -EINVAL; 5201b290d67SFrederic Weisbecker 521aa59a485SFrederic Weisbecker /* 522aa59a485SFrederic Weisbecker * We should find a nice way to override the access length 523aa59a485SFrederic Weisbecker * Provide some defaults for now 524aa59a485SFrederic Weisbecker */ 52589812fc8SJiri Olsa if (attr.bp_type == HW_BREAKPOINT_X) 52689812fc8SJiri Olsa attr.bp_len = sizeof(long); 527aa59a485SFrederic Weisbecker else 52889812fc8SJiri Olsa attr.bp_len = HW_BREAKPOINT_LEN_4; 529aa59a485SFrederic Weisbecker 53089812fc8SJiri Olsa attr.type = PERF_TYPE_BREAKPOINT; 5314a841d65SJovi Zhang attr.sample_period = 1; 5321b290d67SFrederic Weisbecker 533287e74aaSJiri Olsa return add_event(list, idx, &attr, NULL); 5341b290d67SFrederic Weisbecker } 5351b290d67SFrederic Weisbecker 5368f707d84SJiri Olsa static int config_term(struct perf_event_attr *attr, 5376cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term) 5388f707d84SJiri Olsa { 53916fa7e82SJiri Olsa #define CHECK_TYPE_VAL(type) \ 54016fa7e82SJiri Olsa do { \ 54116fa7e82SJiri Olsa if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val) \ 54216fa7e82SJiri Olsa return -EINVAL; \ 54316fa7e82SJiri Olsa } while (0) 54416fa7e82SJiri Olsa 54516fa7e82SJiri Olsa switch (term->type_term) { 5468f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG: 54716fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5488f707d84SJiri Olsa attr->config = term->val.num; 5498f707d84SJiri Olsa break; 5508f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG1: 55116fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5528f707d84SJiri Olsa attr->config1 = term->val.num; 5538f707d84SJiri Olsa break; 5548f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG2: 55516fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5568f707d84SJiri Olsa attr->config2 = term->val.num; 5578f707d84SJiri Olsa break; 5588f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 55916fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5608f707d84SJiri Olsa attr->sample_period = term->val.num; 5618f707d84SJiri Olsa break; 5628f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: 5638f707d84SJiri Olsa /* 5648f707d84SJiri Olsa * TODO uncomment when the field is available 5658f707d84SJiri Olsa * attr->branch_sample_type = term->val.num; 5668f707d84SJiri Olsa */ 5678f707d84SJiri Olsa break; 5686b5fc39bSJiri Olsa case PARSE_EVENTS__TERM_TYPE_NAME: 5696b5fc39bSJiri Olsa CHECK_TYPE_VAL(STR); 5706b5fc39bSJiri Olsa break; 5718f707d84SJiri Olsa default: 5728f707d84SJiri Olsa return -EINVAL; 5738f707d84SJiri Olsa } 57416fa7e82SJiri Olsa 5758f707d84SJiri Olsa return 0; 57616fa7e82SJiri Olsa #undef CHECK_TYPE_VAL 5778f707d84SJiri Olsa } 5788f707d84SJiri Olsa 5798f707d84SJiri Olsa static int config_attr(struct perf_event_attr *attr, 5808f707d84SJiri Olsa struct list_head *head, int fail) 5818f707d84SJiri Olsa { 5826cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 5838f707d84SJiri Olsa 5848f707d84SJiri Olsa list_for_each_entry(term, head, list) 5858f707d84SJiri Olsa if (config_term(attr, term) && fail) 5868f707d84SJiri Olsa return -EINVAL; 5878f707d84SJiri Olsa 5888f707d84SJiri Olsa return 0; 5898f707d84SJiri Olsa } 5908f707d84SJiri Olsa 591b847cbdcSJiri Olsa int parse_events_add_numeric(struct list_head **list, int *idx, 592b527bab5SRobert Richter u32 type, u64 config, 5938f707d84SJiri Olsa struct list_head *head_config) 59474d5b588SJaswinder Singh Rajput { 59589812fc8SJiri Olsa struct perf_event_attr attr; 59674d5b588SJaswinder Singh Rajput 59789812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 59889812fc8SJiri Olsa attr.type = type; 59989812fc8SJiri Olsa attr.config = config; 6008f707d84SJiri Olsa 6018f707d84SJiri Olsa if (head_config && 6028f707d84SJiri Olsa config_attr(&attr, head_config, 1)) 6038f707d84SJiri Olsa return -EINVAL; 6048f707d84SJiri Olsa 6059db1763cSArnaldo Carvalho de Melo return add_event(list, idx, &attr, NULL); 606b908debdSIngo Molnar } 607b908debdSIngo Molnar 6086cee6cd3SArnaldo Carvalho de Melo static int parse_events__is_name_term(struct parse_events_term *term) 6096b5fc39bSJiri Olsa { 6106b5fc39bSJiri Olsa return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; 6116b5fc39bSJiri Olsa } 6126b5fc39bSJiri Olsa 6139db1763cSArnaldo Carvalho de Melo static char *pmu_event_name(struct list_head *head_terms) 6146b5fc39bSJiri Olsa { 6156cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 6166b5fc39bSJiri Olsa 6176b5fc39bSJiri Olsa list_for_each_entry(term, head_terms, list) 6186b5fc39bSJiri Olsa if (parse_events__is_name_term(term)) 6196b5fc39bSJiri Olsa return term->val.str; 6206b5fc39bSJiri Olsa 6219db1763cSArnaldo Carvalho de Melo return NULL; 6226b5fc39bSJiri Olsa } 6236b5fc39bSJiri Olsa 624b847cbdcSJiri Olsa int parse_events_add_pmu(struct list_head **list, int *idx, 6255f537a26SJiri Olsa char *name, struct list_head *head_config) 6265f537a26SJiri Olsa { 6275f537a26SJiri Olsa struct perf_event_attr attr; 6285f537a26SJiri Olsa struct perf_pmu *pmu; 6295f537a26SJiri Olsa 6305f537a26SJiri Olsa pmu = perf_pmu__find(name); 6315f537a26SJiri Olsa if (!pmu) 6325f537a26SJiri Olsa return -EINVAL; 6335f537a26SJiri Olsa 6345f537a26SJiri Olsa memset(&attr, 0, sizeof(attr)); 6355f537a26SJiri Olsa 636a6146d50SZheng Yan if (perf_pmu__check_alias(pmu, head_config)) 637a6146d50SZheng Yan return -EINVAL; 638a6146d50SZheng Yan 6395f537a26SJiri Olsa /* 6405f537a26SJiri Olsa * Configure hardcoded terms first, no need to check 6415f537a26SJiri Olsa * return value when called with fail == 0 ;) 6425f537a26SJiri Olsa */ 6435f537a26SJiri Olsa config_attr(&attr, head_config, 0); 6445f537a26SJiri Olsa 6455f537a26SJiri Olsa if (perf_pmu__config(pmu, &attr, head_config)) 6465f537a26SJiri Olsa return -EINVAL; 6475f537a26SJiri Olsa 6487ae92e74SYan, Zheng return __add_event(list, idx, &attr, pmu_event_name(head_config), 6497ae92e74SYan, Zheng pmu->cpus); 6505f537a26SJiri Olsa } 6515f537a26SJiri Olsa 6526a4bb04cSJiri Olsa int parse_events__modifier_group(struct list_head *list, 6536a4bb04cSJiri Olsa char *event_mod) 65489efb029SJiri Olsa { 6556a4bb04cSJiri Olsa return parse_events__modifier_event(list, event_mod, true); 6566a4bb04cSJiri Olsa } 6576a4bb04cSJiri Olsa 65863dab225SArnaldo Carvalho de Melo void parse_events__set_leader(char *name, struct list_head *list) 6596a4bb04cSJiri Olsa { 6606a4bb04cSJiri Olsa struct perf_evsel *leader; 6616a4bb04cSJiri Olsa 66263dab225SArnaldo Carvalho de Melo __perf_evlist__set_leader(list); 66363dab225SArnaldo Carvalho de Melo leader = list_entry(list->next, struct perf_evsel, node); 6646a4bb04cSJiri Olsa leader->group_name = name ? strdup(name) : NULL; 66589efb029SJiri Olsa } 66689efb029SJiri Olsa 6675d7be90eSJiri Olsa void parse_events_update_lists(struct list_head *list_event, 6685d7be90eSJiri Olsa struct list_head *list_all) 6695d7be90eSJiri Olsa { 6705d7be90eSJiri Olsa /* 6715d7be90eSJiri Olsa * Called for single event definition. Update the 67289efb029SJiri Olsa * 'all event' list, and reinit the 'single event' 6735d7be90eSJiri Olsa * list, for next event definition. 6745d7be90eSJiri Olsa */ 6755d7be90eSJiri Olsa list_splice_tail(list_event, list_all); 676b847cbdcSJiri Olsa free(list_event); 6775d7be90eSJiri Olsa } 6785d7be90eSJiri Olsa 679f5b1135bSJiri Olsa struct event_modifier { 680f5b1135bSJiri Olsa int eu; 681f5b1135bSJiri Olsa int ek; 682f5b1135bSJiri Olsa int eh; 683f5b1135bSJiri Olsa int eH; 684f5b1135bSJiri Olsa int eG; 685f5b1135bSJiri Olsa int precise; 686f5b1135bSJiri Olsa int exclude_GH; 687f5b1135bSJiri Olsa }; 68861c45981SPaul Mackerras 689f5b1135bSJiri Olsa static int get_event_modifier(struct event_modifier *mod, char *str, 690f5b1135bSJiri Olsa struct perf_evsel *evsel) 691f5b1135bSJiri Olsa { 692f5b1135bSJiri Olsa int eu = evsel ? evsel->attr.exclude_user : 0; 693f5b1135bSJiri Olsa int ek = evsel ? evsel->attr.exclude_kernel : 0; 694f5b1135bSJiri Olsa int eh = evsel ? evsel->attr.exclude_hv : 0; 695f5b1135bSJiri Olsa int eH = evsel ? evsel->attr.exclude_host : 0; 696f5b1135bSJiri Olsa int eG = evsel ? evsel->attr.exclude_guest : 0; 697f5b1135bSJiri Olsa int precise = evsel ? evsel->attr.precise_ip : 0; 698f5b1135bSJiri Olsa 699f5b1135bSJiri Olsa int exclude = eu | ek | eh; 700f5b1135bSJiri Olsa int exclude_GH = evsel ? evsel->exclude_GH : 0; 701f5b1135bSJiri Olsa 702f5b1135bSJiri Olsa /* 703f5b1135bSJiri Olsa * We are here for group and 'GH' was not set as event 704f5b1135bSJiri Olsa * modifier and whatever event/group modifier override 705f5b1135bSJiri Olsa * default 'GH' setup. 706f5b1135bSJiri Olsa */ 707f5b1135bSJiri Olsa if (evsel && !exclude_GH) 708f5b1135bSJiri Olsa eH = eG = 0; 709f5b1135bSJiri Olsa 710f5b1135bSJiri Olsa memset(mod, 0, sizeof(*mod)); 711ceb53fbfSIngo Molnar 71261c45981SPaul Mackerras while (*str) { 713ab608344SPeter Zijlstra if (*str == 'u') { 714ab608344SPeter Zijlstra if (!exclude) 715ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 71661c45981SPaul Mackerras eu = 0; 717ab608344SPeter Zijlstra } else if (*str == 'k') { 718ab608344SPeter Zijlstra if (!exclude) 719ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 72061c45981SPaul Mackerras ek = 0; 721ab608344SPeter Zijlstra } else if (*str == 'h') { 722ab608344SPeter Zijlstra if (!exclude) 723ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 72461c45981SPaul Mackerras eh = 0; 72599320cc8SJoerg Roedel } else if (*str == 'G') { 72699320cc8SJoerg Roedel if (!exclude_GH) 72799320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 72899320cc8SJoerg Roedel eG = 0; 72999320cc8SJoerg Roedel } else if (*str == 'H') { 73099320cc8SJoerg Roedel if (!exclude_GH) 73199320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 73299320cc8SJoerg Roedel eH = 0; 733ab608344SPeter Zijlstra } else if (*str == 'p') { 734ab608344SPeter Zijlstra precise++; 7351342798cSDavid Ahern /* use of precise requires exclude_guest */ 7361342798cSDavid Ahern if (!exclude_GH) 7371342798cSDavid Ahern eG = 1; 738ab608344SPeter Zijlstra } else 73961c45981SPaul Mackerras break; 740ab608344SPeter Zijlstra 74161c45981SPaul Mackerras ++str; 74261c45981SPaul Mackerras } 74374d5b588SJaswinder Singh Rajput 74486470930SIngo Molnar /* 74589812fc8SJiri Olsa * precise ip: 74689812fc8SJiri Olsa * 74789812fc8SJiri Olsa * 0 - SAMPLE_IP can have arbitrary skid 74889812fc8SJiri Olsa * 1 - SAMPLE_IP must have constant skid 74989812fc8SJiri Olsa * 2 - SAMPLE_IP requested to have 0 skid 75089812fc8SJiri Olsa * 3 - SAMPLE_IP must have 0 skid 75189812fc8SJiri Olsa * 75289812fc8SJiri Olsa * See also PERF_RECORD_MISC_EXACT_IP 75386470930SIngo Molnar */ 75489812fc8SJiri Olsa if (precise > 3) 75589812fc8SJiri Olsa return -EINVAL; 75686470930SIngo Molnar 757f5b1135bSJiri Olsa mod->eu = eu; 758f5b1135bSJiri Olsa mod->ek = ek; 759f5b1135bSJiri Olsa mod->eh = eh; 760f5b1135bSJiri Olsa mod->eH = eH; 761f5b1135bSJiri Olsa mod->eG = eG; 762f5b1135bSJiri Olsa mod->precise = precise; 763f5b1135bSJiri Olsa mod->exclude_GH = exclude_GH; 764f5b1135bSJiri Olsa return 0; 765f5b1135bSJiri Olsa } 766f5b1135bSJiri Olsa 767534123f4SJiri Olsa /* 768534123f4SJiri Olsa * Basic modifier sanity check to validate it contains only one 769534123f4SJiri Olsa * instance of any modifier (apart from 'p') present. 770534123f4SJiri Olsa */ 771534123f4SJiri Olsa static int check_modifier(char *str) 772534123f4SJiri Olsa { 773534123f4SJiri Olsa char *p = str; 774534123f4SJiri Olsa 775534123f4SJiri Olsa /* The sizeof includes 0 byte as well. */ 776534123f4SJiri Olsa if (strlen(str) > (sizeof("ukhGHppp") - 1)) 777534123f4SJiri Olsa return -1; 778534123f4SJiri Olsa 779534123f4SJiri Olsa while (*p) { 780534123f4SJiri Olsa if (*p != 'p' && strchr(p + 1, *p)) 781534123f4SJiri Olsa return -1; 782534123f4SJiri Olsa p++; 783534123f4SJiri Olsa } 784534123f4SJiri Olsa 785534123f4SJiri Olsa return 0; 786534123f4SJiri Olsa } 787534123f4SJiri Olsa 788f5b1135bSJiri Olsa int parse_events__modifier_event(struct list_head *list, char *str, bool add) 789f5b1135bSJiri Olsa { 790f5b1135bSJiri Olsa struct perf_evsel *evsel; 791f5b1135bSJiri Olsa struct event_modifier mod; 792f5b1135bSJiri Olsa 793f5b1135bSJiri Olsa if (str == NULL) 794f5b1135bSJiri Olsa return 0; 795f5b1135bSJiri Olsa 796534123f4SJiri Olsa if (check_modifier(str)) 797534123f4SJiri Olsa return -EINVAL; 798534123f4SJiri Olsa 799f5b1135bSJiri Olsa if (!add && get_event_modifier(&mod, str, NULL)) 800f5b1135bSJiri Olsa return -EINVAL; 801f5b1135bSJiri Olsa 80289812fc8SJiri Olsa list_for_each_entry(evsel, list, node) { 803f5b1135bSJiri Olsa 804f5b1135bSJiri Olsa if (add && get_event_modifier(&mod, str, evsel)) 805f5b1135bSJiri Olsa return -EINVAL; 806f5b1135bSJiri Olsa 807f5b1135bSJiri Olsa evsel->attr.exclude_user = mod.eu; 808f5b1135bSJiri Olsa evsel->attr.exclude_kernel = mod.ek; 809f5b1135bSJiri Olsa evsel->attr.exclude_hv = mod.eh; 810f5b1135bSJiri Olsa evsel->attr.precise_ip = mod.precise; 811f5b1135bSJiri Olsa evsel->attr.exclude_host = mod.eH; 812f5b1135bSJiri Olsa evsel->attr.exclude_guest = mod.eG; 813f5b1135bSJiri Olsa evsel->exclude_GH = mod.exclude_GH; 814ceb53fbfSIngo Molnar } 81586470930SIngo Molnar 81689812fc8SJiri Olsa return 0; 81786470930SIngo Molnar } 81886470930SIngo Molnar 819ac2ba9f3SRobert Richter int parse_events_name(struct list_head *list, char *name) 820ac2ba9f3SRobert Richter { 821ac2ba9f3SRobert Richter struct perf_evsel *evsel; 822ac2ba9f3SRobert Richter 823ac2ba9f3SRobert Richter list_for_each_entry(evsel, list, node) { 824ac2ba9f3SRobert Richter if (!evsel->name) 825ac2ba9f3SRobert Richter evsel->name = strdup(name); 826ac2ba9f3SRobert Richter } 827ac2ba9f3SRobert Richter 828ac2ba9f3SRobert Richter return 0; 829ac2ba9f3SRobert Richter } 830ac2ba9f3SRobert Richter 83190e2b22dSJiri Olsa static int parse_events__scanner(const char *str, void *data, int start_token) 832ac20de6fSZheng Yan { 833ac20de6fSZheng Yan YY_BUFFER_STATE buffer; 834ac20de6fSZheng Yan void *scanner; 835ac20de6fSZheng Yan int ret; 836ac20de6fSZheng Yan 83790e2b22dSJiri Olsa ret = parse_events_lex_init_extra(start_token, &scanner); 838ac20de6fSZheng Yan if (ret) 839ac20de6fSZheng Yan return ret; 840ac20de6fSZheng Yan 841ac20de6fSZheng Yan buffer = parse_events__scan_string(str, scanner); 842ac20de6fSZheng Yan 843ac20de6fSZheng Yan #ifdef PARSER_DEBUG 844ac20de6fSZheng Yan parse_events_debug = 1; 845ac20de6fSZheng Yan #endif 846ac20de6fSZheng Yan ret = parse_events_parse(data, scanner); 847ac20de6fSZheng Yan 848ac20de6fSZheng Yan parse_events__flush_buffer(buffer, scanner); 849ac20de6fSZheng Yan parse_events__delete_buffer(buffer, scanner); 850ac20de6fSZheng Yan parse_events_lex_destroy(scanner); 851ac20de6fSZheng Yan return ret; 852ac20de6fSZheng Yan } 853ac20de6fSZheng Yan 85490e2b22dSJiri Olsa /* 85590e2b22dSJiri Olsa * parse event config string, return a list of event terms. 85690e2b22dSJiri Olsa */ 85790e2b22dSJiri Olsa int parse_events_terms(struct list_head *terms, const char *str) 85890e2b22dSJiri Olsa { 85923b6339bSArnaldo Carvalho de Melo struct parse_events_terms data = { 86090e2b22dSJiri Olsa .terms = NULL, 86190e2b22dSJiri Olsa }; 86290e2b22dSJiri Olsa int ret; 86390e2b22dSJiri Olsa 86490e2b22dSJiri Olsa ret = parse_events__scanner(str, &data, PE_START_TERMS); 86590e2b22dSJiri Olsa if (!ret) { 86690e2b22dSJiri Olsa list_splice(data.terms, terms); 86790e2b22dSJiri Olsa free(data.terms); 86890e2b22dSJiri Olsa return 0; 86990e2b22dSJiri Olsa } 87090e2b22dSJiri Olsa 87190e2b22dSJiri Olsa parse_events__free_terms(data.terms); 87290e2b22dSJiri Olsa return ret; 87390e2b22dSJiri Olsa } 87490e2b22dSJiri Olsa 875d8f7bbc9SJiri Olsa int parse_events(struct perf_evlist *evlist, const char *str) 87686470930SIngo Molnar { 87723b6339bSArnaldo Carvalho de Melo struct parse_events_evlist data = { 87846010ab2SJiri Olsa .list = LIST_HEAD_INIT(data.list), 87946010ab2SJiri Olsa .idx = evlist->nr_entries, 88046010ab2SJiri Olsa }; 88146010ab2SJiri Olsa int ret; 88286470930SIngo Molnar 88390e2b22dSJiri Olsa ret = parse_events__scanner(str, &data, PE_START_EVENTS); 88489812fc8SJiri Olsa if (!ret) { 88546010ab2SJiri Olsa int entries = data.idx - evlist->nr_entries; 88646010ab2SJiri Olsa perf_evlist__splice_list_tail(evlist, &data.list, entries); 887*97f63e4aSNamhyung Kim evlist->nr_groups += data.nr_groups; 88886470930SIngo Molnar return 0; 88986470930SIngo Molnar } 89086470930SIngo Molnar 8915d7be90eSJiri Olsa /* 8925d7be90eSJiri Olsa * There are 2 users - builtin-record and builtin-test objects. 8935d7be90eSJiri Olsa * Both call perf_evlist__delete in case of error, so we dont 8945d7be90eSJiri Olsa * need to bother. 8955d7be90eSJiri Olsa */ 89689812fc8SJiri Olsa return ret; 89789812fc8SJiri Olsa } 89889812fc8SJiri Olsa 899f120f9d5SJiri Olsa int parse_events_option(const struct option *opt, const char *str, 9001d037ca1SIrina Tirdea int unset __maybe_unused) 901f120f9d5SJiri Olsa { 902f120f9d5SJiri Olsa struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 903d8f7bbc9SJiri Olsa int ret = parse_events(evlist, str); 9049175ce1fSAndi Kleen 9059175ce1fSAndi Kleen if (ret) { 9069175ce1fSAndi Kleen fprintf(stderr, "invalid or unsupported event: '%s'\n", str); 9079175ce1fSAndi Kleen fprintf(stderr, "Run 'perf list' for a list of valid events\n"); 9089175ce1fSAndi Kleen } 9099175ce1fSAndi Kleen return ret; 910f120f9d5SJiri Olsa } 911f120f9d5SJiri Olsa 912361c99a6SArnaldo Carvalho de Melo int parse_filter(const struct option *opt, const char *str, 9131d037ca1SIrina Tirdea int unset __maybe_unused) 914c171b552SLi Zefan { 915361c99a6SArnaldo Carvalho de Melo struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 91669aad6f1SArnaldo Carvalho de Melo struct perf_evsel *last = NULL; 917c171b552SLi Zefan 918361c99a6SArnaldo Carvalho de Melo if (evlist->nr_entries > 0) 9190c21f736SArnaldo Carvalho de Melo last = perf_evlist__last(evlist); 92069aad6f1SArnaldo Carvalho de Melo 92169aad6f1SArnaldo Carvalho de Melo if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { 922c171b552SLi Zefan fprintf(stderr, 923c171b552SLi Zefan "-F option should follow a -e tracepoint option\n"); 924c171b552SLi Zefan return -1; 925c171b552SLi Zefan } 926c171b552SLi Zefan 92769aad6f1SArnaldo Carvalho de Melo last->filter = strdup(str); 92869aad6f1SArnaldo Carvalho de Melo if (last->filter == NULL) { 929c171b552SLi Zefan fprintf(stderr, "not enough memory to hold filter string\n"); 930c171b552SLi Zefan return -1; 931c171b552SLi Zefan } 932c171b552SLi Zefan 933c171b552SLi Zefan return 0; 934c171b552SLi Zefan } 935c171b552SLi Zefan 93686470930SIngo Molnar static const char * const event_type_descriptors[] = { 93786470930SIngo Molnar "Hardware event", 93886470930SIngo Molnar "Software event", 93986470930SIngo Molnar "Tracepoint event", 94086470930SIngo Molnar "Hardware cache event", 94141bdcb23SLiming Wang "Raw hardware event descriptor", 94241bdcb23SLiming Wang "Hardware breakpoint", 94386470930SIngo Molnar }; 94486470930SIngo Molnar 94586470930SIngo Molnar /* 946f6bdafefSJason Baron * Print the events from <debugfs_mount_point>/tracing/events 947f6bdafefSJason Baron */ 948f6bdafefSJason Baron 949a3277d2dSFrederic Weisbecker void print_tracepoint_events(const char *subsys_glob, const char *event_glob, 950a3277d2dSFrederic Weisbecker bool name_only) 951f6bdafefSJason Baron { 952f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 953f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 954f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 955725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 956f6bdafefSJason Baron 957ebf294bfSArnaldo Carvalho de Melo if (debugfs_valid_mountpoint(tracing_events_path)) 958f6bdafefSJason Baron return; 959f6bdafefSJason Baron 960ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 961f6bdafefSJason Baron if (!sys_dir) 962725b1368SEric Dumazet return; 963f6bdafefSJason Baron 9646b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 965668b8788SArnaldo Carvalho de Melo if (subsys_glob != NULL && 966668b8788SArnaldo Carvalho de Melo !strglobmatch(sys_dirent.d_name, subsys_glob)) 967668b8788SArnaldo Carvalho de Melo continue; 968725b1368SEric Dumazet 969ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 970725b1368SEric Dumazet sys_dirent.d_name); 971725b1368SEric Dumazet evt_dir = opendir(dir_path); 972725b1368SEric Dumazet if (!evt_dir) 9736b58e7f1SUlrich Drepper continue; 974725b1368SEric Dumazet 9756b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 976668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 977668b8788SArnaldo Carvalho de Melo !strglobmatch(evt_dirent.d_name, event_glob)) 978668b8788SArnaldo Carvalho de Melo continue; 979668b8788SArnaldo Carvalho de Melo 980a3277d2dSFrederic Weisbecker if (name_only) { 981a3277d2dSFrederic Weisbecker printf("%s:%s ", sys_dirent.d_name, evt_dirent.d_name); 982a3277d2dSFrederic Weisbecker continue; 983a3277d2dSFrederic Weisbecker } 984a3277d2dSFrederic Weisbecker 985f6bdafefSJason Baron snprintf(evt_path, MAXPATHLEN, "%s:%s", 986f6bdafefSJason Baron sys_dirent.d_name, evt_dirent.d_name); 987947b4ad1SIngo Molnar printf(" %-50s [%s]\n", evt_path, 98841bdcb23SLiming Wang event_type_descriptors[PERF_TYPE_TRACEPOINT]); 989f6bdafefSJason Baron } 990f6bdafefSJason Baron closedir(evt_dir); 991f6bdafefSJason Baron } 992f6bdafefSJason Baron closedir(sys_dir); 993f6bdafefSJason Baron } 994f6bdafefSJason Baron 995f6bdafefSJason Baron /* 99620c457b8SThomas Renninger * Check whether event is in <debugfs_mount_point>/tracing/events 99720c457b8SThomas Renninger */ 99820c457b8SThomas Renninger 99920c457b8SThomas Renninger int is_valid_tracepoint(const char *event_string) 100020c457b8SThomas Renninger { 100120c457b8SThomas Renninger DIR *sys_dir, *evt_dir; 100220c457b8SThomas Renninger struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 100320c457b8SThomas Renninger char evt_path[MAXPATHLEN]; 100420c457b8SThomas Renninger char dir_path[MAXPATHLEN]; 100520c457b8SThomas Renninger 1006ebf294bfSArnaldo Carvalho de Melo if (debugfs_valid_mountpoint(tracing_events_path)) 100720c457b8SThomas Renninger return 0; 100820c457b8SThomas Renninger 1009ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 101020c457b8SThomas Renninger if (!sys_dir) 101120c457b8SThomas Renninger return 0; 101220c457b8SThomas Renninger 101320c457b8SThomas Renninger for_each_subsystem(sys_dir, sys_dirent, sys_next) { 101420c457b8SThomas Renninger 1015ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 101620c457b8SThomas Renninger sys_dirent.d_name); 101720c457b8SThomas Renninger evt_dir = opendir(dir_path); 101820c457b8SThomas Renninger if (!evt_dir) 101920c457b8SThomas Renninger continue; 102020c457b8SThomas Renninger 102120c457b8SThomas Renninger for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 102220c457b8SThomas Renninger snprintf(evt_path, MAXPATHLEN, "%s:%s", 102320c457b8SThomas Renninger sys_dirent.d_name, evt_dirent.d_name); 102420c457b8SThomas Renninger if (!strcmp(evt_path, event_string)) { 102520c457b8SThomas Renninger closedir(evt_dir); 102620c457b8SThomas Renninger closedir(sys_dir); 102720c457b8SThomas Renninger return 1; 102820c457b8SThomas Renninger } 102920c457b8SThomas Renninger } 103020c457b8SThomas Renninger closedir(evt_dir); 103120c457b8SThomas Renninger } 103220c457b8SThomas Renninger closedir(sys_dir); 103320c457b8SThomas Renninger return 0; 103420c457b8SThomas Renninger } 103520c457b8SThomas Renninger 10361dc12760SJiri Olsa static void __print_events_type(u8 type, struct event_symbol *syms, 10371dc12760SJiri Olsa unsigned max) 1038668b8788SArnaldo Carvalho de Melo { 1039668b8788SArnaldo Carvalho de Melo char name[64]; 10401dc12760SJiri Olsa unsigned i; 1041668b8788SArnaldo Carvalho de Melo 10421dc12760SJiri Olsa for (i = 0; i < max ; i++, syms++) { 1043668b8788SArnaldo Carvalho de Melo if (strlen(syms->alias)) 1044668b8788SArnaldo Carvalho de Melo snprintf(name, sizeof(name), "%s OR %s", 1045668b8788SArnaldo Carvalho de Melo syms->symbol, syms->alias); 1046668b8788SArnaldo Carvalho de Melo else 1047668b8788SArnaldo Carvalho de Melo snprintf(name, sizeof(name), "%s", syms->symbol); 1048668b8788SArnaldo Carvalho de Melo 1049947b4ad1SIngo Molnar printf(" %-50s [%s]\n", name, 1050668b8788SArnaldo Carvalho de Melo event_type_descriptors[type]); 1051668b8788SArnaldo Carvalho de Melo } 1052668b8788SArnaldo Carvalho de Melo } 1053668b8788SArnaldo Carvalho de Melo 10541dc12760SJiri Olsa void print_events_type(u8 type) 10551dc12760SJiri Olsa { 10561dc12760SJiri Olsa if (type == PERF_TYPE_SOFTWARE) 10571dc12760SJiri Olsa __print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX); 10581dc12760SJiri Olsa else 10591dc12760SJiri Olsa __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX); 10601dc12760SJiri Olsa } 10611dc12760SJiri Olsa 1062a3277d2dSFrederic Weisbecker int print_hwcache_events(const char *event_glob, bool name_only) 1063668b8788SArnaldo Carvalho de Melo { 1064668b8788SArnaldo Carvalho de Melo unsigned int type, op, i, printed = 0; 10650b668bc9SArnaldo Carvalho de Melo char name[64]; 1066668b8788SArnaldo Carvalho de Melo 1067668b8788SArnaldo Carvalho de Melo for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 1068668b8788SArnaldo Carvalho de Melo for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 1069668b8788SArnaldo Carvalho de Melo /* skip invalid cache type */ 10700b668bc9SArnaldo Carvalho de Melo if (!perf_evsel__is_cache_op_valid(type, op)) 1071668b8788SArnaldo Carvalho de Melo continue; 1072668b8788SArnaldo Carvalho de Melo 1073668b8788SArnaldo Carvalho de Melo for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 10740b668bc9SArnaldo Carvalho de Melo __perf_evsel__hw_cache_type_op_res_name(type, op, i, 10750b668bc9SArnaldo Carvalho de Melo name, sizeof(name)); 1076947b4ad1SIngo Molnar if (event_glob != NULL && !strglobmatch(name, event_glob)) 1077668b8788SArnaldo Carvalho de Melo continue; 1078668b8788SArnaldo Carvalho de Melo 1079a3277d2dSFrederic Weisbecker if (name_only) 1080a3277d2dSFrederic Weisbecker printf("%s ", name); 1081a3277d2dSFrederic Weisbecker else 1082947b4ad1SIngo Molnar printf(" %-50s [%s]\n", name, 1083668b8788SArnaldo Carvalho de Melo event_type_descriptors[PERF_TYPE_HW_CACHE]); 1084668b8788SArnaldo Carvalho de Melo ++printed; 1085668b8788SArnaldo Carvalho de Melo } 1086668b8788SArnaldo Carvalho de Melo } 1087668b8788SArnaldo Carvalho de Melo } 1088668b8788SArnaldo Carvalho de Melo 1089668b8788SArnaldo Carvalho de Melo return printed; 1090668b8788SArnaldo Carvalho de Melo } 1091668b8788SArnaldo Carvalho de Melo 10921dc12760SJiri Olsa static void print_symbol_events(const char *event_glob, unsigned type, 1093a3277d2dSFrederic Weisbecker struct event_symbol *syms, unsigned max, 1094a3277d2dSFrederic Weisbecker bool name_only) 109586470930SIngo Molnar { 10961dc12760SJiri Olsa unsigned i, printed = 0; 1097947b4ad1SIngo Molnar char name[MAX_NAME_LEN]; 109886470930SIngo Molnar 10991dc12760SJiri Olsa for (i = 0; i < max; i++, syms++) { 1100668b8788SArnaldo Carvalho de Melo 1101668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 1102668b8788SArnaldo Carvalho de Melo !(strglobmatch(syms->symbol, event_glob) || 1103668b8788SArnaldo Carvalho de Melo (syms->alias && strglobmatch(syms->alias, event_glob)))) 1104668b8788SArnaldo Carvalho de Melo continue; 110586470930SIngo Molnar 1106a3277d2dSFrederic Weisbecker if (name_only) { 1107a3277d2dSFrederic Weisbecker printf("%s ", syms->symbol); 1108a3277d2dSFrederic Weisbecker continue; 1109a3277d2dSFrederic Weisbecker } 1110a3277d2dSFrederic Weisbecker 111174d5b588SJaswinder Singh Rajput if (strlen(syms->alias)) 1112947b4ad1SIngo Molnar snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 111374d5b588SJaswinder Singh Rajput else 1114947b4ad1SIngo Molnar strncpy(name, syms->symbol, MAX_NAME_LEN); 111586470930SIngo Molnar 11161dc12760SJiri Olsa printf(" %-50s [%s]\n", name, event_type_descriptors[type]); 11171dc12760SJiri Olsa 11181dc12760SJiri Olsa printed++; 111986470930SIngo Molnar } 112086470930SIngo Molnar 11211dc12760SJiri Olsa if (printed) 1122689d3018SMarti Raudsepp printf("\n"); 1123668b8788SArnaldo Carvalho de Melo } 11241dc12760SJiri Olsa 11251dc12760SJiri Olsa /* 11261dc12760SJiri Olsa * Print the help text for the event symbols: 11271dc12760SJiri Olsa */ 1128a3277d2dSFrederic Weisbecker void print_events(const char *event_glob, bool name_only) 11291dc12760SJiri Olsa { 1130a3277d2dSFrederic Weisbecker if (!name_only) { 11311dc12760SJiri Olsa printf("\n"); 11321dc12760SJiri Olsa printf("List of pre-defined events (to be used in -e):\n"); 1133a3277d2dSFrederic Weisbecker } 11341dc12760SJiri Olsa 11351dc12760SJiri Olsa print_symbol_events(event_glob, PERF_TYPE_HARDWARE, 1136a3277d2dSFrederic Weisbecker event_symbols_hw, PERF_COUNT_HW_MAX, name_only); 11371dc12760SJiri Olsa 11381dc12760SJiri Olsa print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, 1139a3277d2dSFrederic Weisbecker event_symbols_sw, PERF_COUNT_SW_MAX, name_only); 11401dc12760SJiri Olsa 1141a3277d2dSFrederic Weisbecker print_hwcache_events(event_glob, name_only); 114273c24cb8SJaswinder Singh Rajput 1143668b8788SArnaldo Carvalho de Melo if (event_glob != NULL) 1144668b8788SArnaldo Carvalho de Melo return; 114573c24cb8SJaswinder Singh Rajput 1146a3277d2dSFrederic Weisbecker if (!name_only) { 1147689d3018SMarti Raudsepp printf("\n"); 1148947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 11495f537a26SJiri Olsa "rNNN", 11501cf4a063SArnaldo Carvalho de Melo event_type_descriptors[PERF_TYPE_RAW]); 11515f537a26SJiri Olsa printf(" %-50s [%s]\n", 11525f537a26SJiri Olsa "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 11535f537a26SJiri Olsa event_type_descriptors[PERF_TYPE_RAW]); 1154af3df2cfSBorislav Petkov printf(" (see 'man perf-list' on how to encode it)\n"); 1155689d3018SMarti Raudsepp printf("\n"); 115686470930SIngo Molnar 1157947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 115841bdcb23SLiming Wang "mem:<addr>[:access]", 115941bdcb23SLiming Wang event_type_descriptors[PERF_TYPE_BREAKPOINT]); 11601b290d67SFrederic Weisbecker printf("\n"); 1161a3277d2dSFrederic Weisbecker } 11621b290d67SFrederic Weisbecker 1163a3277d2dSFrederic Weisbecker print_tracepoint_events(NULL, NULL, name_only); 116486470930SIngo Molnar } 11658f707d84SJiri Olsa 11666cee6cd3SArnaldo Carvalho de Melo int parse_events__is_hardcoded_term(struct parse_events_term *term) 11678f707d84SJiri Olsa { 116816fa7e82SJiri Olsa return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; 11698f707d84SJiri Olsa } 11708f707d84SJiri Olsa 11716cee6cd3SArnaldo Carvalho de Melo static int new_term(struct parse_events_term **_term, int type_val, 117216fa7e82SJiri Olsa int type_term, char *config, 1173b527bab5SRobert Richter char *str, u64 num) 11748f707d84SJiri Olsa { 11756cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 11768f707d84SJiri Olsa 11778f707d84SJiri Olsa term = zalloc(sizeof(*term)); 11788f707d84SJiri Olsa if (!term) 11798f707d84SJiri Olsa return -ENOMEM; 11808f707d84SJiri Olsa 11818f707d84SJiri Olsa INIT_LIST_HEAD(&term->list); 118216fa7e82SJiri Olsa term->type_val = type_val; 118316fa7e82SJiri Olsa term->type_term = type_term; 11848f707d84SJiri Olsa term->config = config; 11858f707d84SJiri Olsa 118616fa7e82SJiri Olsa switch (type_val) { 11878f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_NUM: 11888f707d84SJiri Olsa term->val.num = num; 11898f707d84SJiri Olsa break; 11908f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_STR: 11918f707d84SJiri Olsa term->val.str = str; 11928f707d84SJiri Olsa break; 11938f707d84SJiri Olsa default: 11948f707d84SJiri Olsa return -EINVAL; 11958f707d84SJiri Olsa } 11968f707d84SJiri Olsa 11978f707d84SJiri Olsa *_term = term; 11988f707d84SJiri Olsa return 0; 11998f707d84SJiri Olsa } 12008f707d84SJiri Olsa 12016cee6cd3SArnaldo Carvalho de Melo int parse_events_term__num(struct parse_events_term **term, 1202b527bab5SRobert Richter int type_term, char *config, u64 num) 120316fa7e82SJiri Olsa { 120416fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, 120516fa7e82SJiri Olsa config, NULL, num); 120616fa7e82SJiri Olsa } 120716fa7e82SJiri Olsa 12086cee6cd3SArnaldo Carvalho de Melo int parse_events_term__str(struct parse_events_term **term, 120916fa7e82SJiri Olsa int type_term, char *config, char *str) 121016fa7e82SJiri Olsa { 121116fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, 121216fa7e82SJiri Olsa config, str, 0); 121316fa7e82SJiri Olsa } 121416fa7e82SJiri Olsa 12156cee6cd3SArnaldo Carvalho de Melo int parse_events_term__sym_hw(struct parse_events_term **term, 12161d33d6dcSJiri Olsa char *config, unsigned idx) 12171d33d6dcSJiri Olsa { 12181d33d6dcSJiri Olsa struct event_symbol *sym; 12191d33d6dcSJiri Olsa 12201d33d6dcSJiri Olsa BUG_ON(idx >= PERF_COUNT_HW_MAX); 12211d33d6dcSJiri Olsa sym = &event_symbols_hw[idx]; 12221d33d6dcSJiri Olsa 12231d33d6dcSJiri Olsa if (config) 12241d33d6dcSJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 12251d33d6dcSJiri Olsa PARSE_EVENTS__TERM_TYPE_USER, config, 12261d33d6dcSJiri Olsa (char *) sym->symbol, 0); 12271d33d6dcSJiri Olsa else 12281d33d6dcSJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 12291d33d6dcSJiri Olsa PARSE_EVENTS__TERM_TYPE_USER, 12301d33d6dcSJiri Olsa (char *) "event", (char *) sym->symbol, 0); 12311d33d6dcSJiri Olsa } 12321d33d6dcSJiri Olsa 12336cee6cd3SArnaldo Carvalho de Melo int parse_events_term__clone(struct parse_events_term **new, 12346cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term) 1235a6146d50SZheng Yan { 1236a6146d50SZheng Yan return new_term(new, term->type_val, term->type_term, term->config, 1237a6146d50SZheng Yan term->val.str, term->val.num); 1238a6146d50SZheng Yan } 1239a6146d50SZheng Yan 12408f707d84SJiri Olsa void parse_events__free_terms(struct list_head *terms) 12418f707d84SJiri Olsa { 12426cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term, *h; 12438f707d84SJiri Olsa 12448f707d84SJiri Olsa list_for_each_entry_safe(term, h, terms, list) 12458f707d84SJiri Olsa free(term); 12468f707d84SJiri Olsa 12478f707d84SJiri Olsa free(terms); 12488f707d84SJiri Olsa } 1249