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" 942f60c2dSKan Liang #include "string.h" 105aab621bSArnaldo Carvalho de Melo #include "symbol.h" 115beeded1SJason Baron #include "cache.h" 128755a8f2SArjan van de Ven #include "header.h" 136e81c74cSMasami Hiramatsu #include "debug.h" 14553873e1SBorislav Petkov #include <api/fs/debugfs.h> 15ac20de6fSZheng Yan #include "parse-events-bison.h" 1690e2b22dSJiri Olsa #define YY_EXTRA_TYPE int 1789812fc8SJiri Olsa #include "parse-events-flex.h" 185f537a26SJiri Olsa #include "pmu.h" 19b41f1cecSNamhyung Kim #include "thread_map.h" 2089812fc8SJiri Olsa 2189812fc8SJiri Olsa #define MAX_NAME_LEN 100 2286470930SIngo Molnar 2386470930SIngo Molnar struct event_symbol { 2483a0944fSIngo Molnar const char *symbol; 2583a0944fSIngo Molnar const char *alias; 2686470930SIngo Molnar }; 2786470930SIngo Molnar 2882ba1f2fSJiri Olsa #ifdef PARSER_DEBUG 2982ba1f2fSJiri Olsa extern int parse_events_debug; 3082ba1f2fSJiri Olsa #endif 31ac20de6fSZheng Yan int parse_events_parse(void *data, void *scanner); 32bcd3279fSFrederic Weisbecker 33dcb4e102SKan Liang static struct perf_pmu_event_symbol *perf_pmu_events_list; 34dcb4e102SKan Liang /* 35dcb4e102SKan Liang * The variable indicates the number of supported pmu event symbols. 36dcb4e102SKan Liang * 0 means not initialized and ready to init 37dcb4e102SKan Liang * -1 means failed to init, don't try anymore 38dcb4e102SKan Liang * >0 is the number of supported pmu event symbols 39dcb4e102SKan Liang */ 40dcb4e102SKan Liang static int perf_pmu_events_list_num; 41dcb4e102SKan Liang 421dc12760SJiri Olsa static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = { 431dc12760SJiri Olsa [PERF_COUNT_HW_CPU_CYCLES] = { 441dc12760SJiri Olsa .symbol = "cpu-cycles", 451dc12760SJiri Olsa .alias = "cycles", 461dc12760SJiri Olsa }, 471dc12760SJiri Olsa [PERF_COUNT_HW_INSTRUCTIONS] = { 481dc12760SJiri Olsa .symbol = "instructions", 491dc12760SJiri Olsa .alias = "", 501dc12760SJiri Olsa }, 511dc12760SJiri Olsa [PERF_COUNT_HW_CACHE_REFERENCES] = { 521dc12760SJiri Olsa .symbol = "cache-references", 531dc12760SJiri Olsa .alias = "", 541dc12760SJiri Olsa }, 551dc12760SJiri Olsa [PERF_COUNT_HW_CACHE_MISSES] = { 561dc12760SJiri Olsa .symbol = "cache-misses", 571dc12760SJiri Olsa .alias = "", 581dc12760SJiri Olsa }, 591dc12760SJiri Olsa [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 601dc12760SJiri Olsa .symbol = "branch-instructions", 611dc12760SJiri Olsa .alias = "branches", 621dc12760SJiri Olsa }, 631dc12760SJiri Olsa [PERF_COUNT_HW_BRANCH_MISSES] = { 641dc12760SJiri Olsa .symbol = "branch-misses", 651dc12760SJiri Olsa .alias = "", 661dc12760SJiri Olsa }, 671dc12760SJiri Olsa [PERF_COUNT_HW_BUS_CYCLES] = { 681dc12760SJiri Olsa .symbol = "bus-cycles", 691dc12760SJiri Olsa .alias = "", 701dc12760SJiri Olsa }, 711dc12760SJiri Olsa [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = { 721dc12760SJiri Olsa .symbol = "stalled-cycles-frontend", 731dc12760SJiri Olsa .alias = "idle-cycles-frontend", 741dc12760SJiri Olsa }, 751dc12760SJiri Olsa [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = { 761dc12760SJiri Olsa .symbol = "stalled-cycles-backend", 771dc12760SJiri Olsa .alias = "idle-cycles-backend", 781dc12760SJiri Olsa }, 791dc12760SJiri Olsa [PERF_COUNT_HW_REF_CPU_CYCLES] = { 801dc12760SJiri Olsa .symbol = "ref-cycles", 811dc12760SJiri Olsa .alias = "", 821dc12760SJiri Olsa }, 831dc12760SJiri Olsa }; 8486470930SIngo Molnar 851dc12760SJiri Olsa static struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { 861dc12760SJiri Olsa [PERF_COUNT_SW_CPU_CLOCK] = { 871dc12760SJiri Olsa .symbol = "cpu-clock", 881dc12760SJiri Olsa .alias = "", 891dc12760SJiri Olsa }, 901dc12760SJiri Olsa [PERF_COUNT_SW_TASK_CLOCK] = { 911dc12760SJiri Olsa .symbol = "task-clock", 921dc12760SJiri Olsa .alias = "", 931dc12760SJiri Olsa }, 941dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS] = { 951dc12760SJiri Olsa .symbol = "page-faults", 961dc12760SJiri Olsa .alias = "faults", 971dc12760SJiri Olsa }, 981dc12760SJiri Olsa [PERF_COUNT_SW_CONTEXT_SWITCHES] = { 991dc12760SJiri Olsa .symbol = "context-switches", 1001dc12760SJiri Olsa .alias = "cs", 1011dc12760SJiri Olsa }, 1021dc12760SJiri Olsa [PERF_COUNT_SW_CPU_MIGRATIONS] = { 1031dc12760SJiri Olsa .symbol = "cpu-migrations", 1041dc12760SJiri Olsa .alias = "migrations", 1051dc12760SJiri Olsa }, 1061dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS_MIN] = { 1071dc12760SJiri Olsa .symbol = "minor-faults", 1081dc12760SJiri Olsa .alias = "", 1091dc12760SJiri Olsa }, 1101dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS_MAJ] = { 1111dc12760SJiri Olsa .symbol = "major-faults", 1121dc12760SJiri Olsa .alias = "", 1131dc12760SJiri Olsa }, 1141dc12760SJiri Olsa [PERF_COUNT_SW_ALIGNMENT_FAULTS] = { 1151dc12760SJiri Olsa .symbol = "alignment-faults", 1161dc12760SJiri Olsa .alias = "", 1171dc12760SJiri Olsa }, 1181dc12760SJiri Olsa [PERF_COUNT_SW_EMULATION_FAULTS] = { 1191dc12760SJiri Olsa .symbol = "emulation-faults", 1201dc12760SJiri Olsa .alias = "", 1211dc12760SJiri Olsa }, 122d22d1a2aSAdrian Hunter [PERF_COUNT_SW_DUMMY] = { 123d22d1a2aSAdrian Hunter .symbol = "dummy", 124d22d1a2aSAdrian Hunter .alias = "", 125d22d1a2aSAdrian Hunter }, 12686470930SIngo Molnar }; 12786470930SIngo Molnar 128cdd6c482SIngo Molnar #define __PERF_EVENT_FIELD(config, name) \ 129cdd6c482SIngo Molnar ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 13086470930SIngo Molnar 131cdd6c482SIngo Molnar #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 132cdd6c482SIngo Molnar #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 133cdd6c482SIngo Molnar #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 134cdd6c482SIngo Molnar #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 13586470930SIngo Molnar 1366b58e7f1SUlrich Drepper #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 137f6bdafefSJason Baron while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 1386b58e7f1SUlrich Drepper if (sys_dirent.d_type == DT_DIR && \ 139f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".")) && \ 140f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".."))) 141f6bdafefSJason Baron 142ae07b63fSPeter Zijlstra static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 143ae07b63fSPeter Zijlstra { 144ae07b63fSPeter Zijlstra char evt_path[MAXPATHLEN]; 145ae07b63fSPeter Zijlstra int fd; 146ae07b63fSPeter Zijlstra 147ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path, 148ae07b63fSPeter Zijlstra sys_dir->d_name, evt_dir->d_name); 149ae07b63fSPeter Zijlstra fd = open(evt_path, O_RDONLY); 150ae07b63fSPeter Zijlstra if (fd < 0) 151ae07b63fSPeter Zijlstra return -EINVAL; 152ae07b63fSPeter Zijlstra close(fd); 153ae07b63fSPeter Zijlstra 154ae07b63fSPeter Zijlstra return 0; 155ae07b63fSPeter Zijlstra } 156ae07b63fSPeter Zijlstra 1576b58e7f1SUlrich Drepper #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ 158f6bdafefSJason Baron while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 1596b58e7f1SUlrich Drepper if (evt_dirent.d_type == DT_DIR && \ 160f6bdafefSJason Baron (strcmp(evt_dirent.d_name, ".")) && \ 161ae07b63fSPeter Zijlstra (strcmp(evt_dirent.d_name, "..")) && \ 162ae07b63fSPeter Zijlstra (!tp_event_has_id(&sys_dirent, &evt_dirent))) 163f6bdafefSJason Baron 164270bbbe8SLi Zefan #define MAX_EVENT_LENGTH 512 165f6bdafefSJason Baron 166f6bdafefSJason Baron 1671ef2ed10SFrederic Weisbecker struct tracepoint_path *tracepoint_id_to_path(u64 config) 168f6bdafefSJason Baron { 1691ef2ed10SFrederic Weisbecker struct tracepoint_path *path = NULL; 170f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 171f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1728aa8a7c8SStephane Eranian char id_buf[24]; 173725b1368SEric Dumazet int fd; 174f6bdafefSJason Baron u64 id; 175f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 176725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 177f6bdafefSJason Baron 178ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 179f6bdafefSJason Baron if (!sys_dir) 180725b1368SEric Dumazet return NULL; 181f6bdafefSJason Baron 1826b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 183725b1368SEric Dumazet 184ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 185725b1368SEric Dumazet sys_dirent.d_name); 186725b1368SEric Dumazet evt_dir = opendir(dir_path); 187725b1368SEric Dumazet if (!evt_dir) 1886b58e7f1SUlrich Drepper continue; 189725b1368SEric Dumazet 1906b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 191725b1368SEric Dumazet 192725b1368SEric Dumazet snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 193f6bdafefSJason Baron evt_dirent.d_name); 194725b1368SEric Dumazet fd = open(evt_path, O_RDONLY); 195f6bdafefSJason Baron if (fd < 0) 196f6bdafefSJason Baron continue; 197f6bdafefSJason Baron if (read(fd, id_buf, sizeof(id_buf)) < 0) { 198f6bdafefSJason Baron close(fd); 199f6bdafefSJason Baron continue; 200f6bdafefSJason Baron } 201f6bdafefSJason Baron close(fd); 202f6bdafefSJason Baron id = atoll(id_buf); 203f6bdafefSJason Baron if (id == config) { 204f6bdafefSJason Baron closedir(evt_dir); 205f6bdafefSJason Baron closedir(sys_dir); 20659b4caebSJulia Lawall path = zalloc(sizeof(*path)); 2071ef2ed10SFrederic Weisbecker path->system = malloc(MAX_EVENT_LENGTH); 2081ef2ed10SFrederic Weisbecker if (!path->system) { 2091ef2ed10SFrederic Weisbecker free(path); 2101ef2ed10SFrederic Weisbecker return NULL; 2111ef2ed10SFrederic Weisbecker } 2121ef2ed10SFrederic Weisbecker path->name = malloc(MAX_EVENT_LENGTH); 2131ef2ed10SFrederic Weisbecker if (!path->name) { 21474cf249dSArnaldo Carvalho de Melo zfree(&path->system); 2151ef2ed10SFrederic Weisbecker free(path); 2161ef2ed10SFrederic Weisbecker return NULL; 2171ef2ed10SFrederic Weisbecker } 2181ef2ed10SFrederic Weisbecker strncpy(path->system, sys_dirent.d_name, 2191ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2201ef2ed10SFrederic Weisbecker strncpy(path->name, evt_dirent.d_name, 2211ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2221ef2ed10SFrederic Weisbecker return path; 223f6bdafefSJason Baron } 224f6bdafefSJason Baron } 225f6bdafefSJason Baron closedir(evt_dir); 226f6bdafefSJason Baron } 227f6bdafefSJason Baron 228f6bdafefSJason Baron closedir(sys_dir); 2291ef2ed10SFrederic Weisbecker return NULL; 2301ef2ed10SFrederic Weisbecker } 2311ef2ed10SFrederic Weisbecker 232e7c93f09SNamhyung Kim struct tracepoint_path *tracepoint_name_to_path(const char *name) 233e7c93f09SNamhyung Kim { 234e7c93f09SNamhyung Kim struct tracepoint_path *path = zalloc(sizeof(*path)); 235e7c93f09SNamhyung Kim char *str = strchr(name, ':'); 236e7c93f09SNamhyung Kim 237e7c93f09SNamhyung Kim if (path == NULL || str == NULL) { 238e7c93f09SNamhyung Kim free(path); 239e7c93f09SNamhyung Kim return NULL; 240e7c93f09SNamhyung Kim } 241e7c93f09SNamhyung Kim 242e7c93f09SNamhyung Kim path->system = strndup(name, str - name); 243e7c93f09SNamhyung Kim path->name = strdup(str+1); 244e7c93f09SNamhyung Kim 245e7c93f09SNamhyung Kim if (path->system == NULL || path->name == NULL) { 24674cf249dSArnaldo Carvalho de Melo zfree(&path->system); 24774cf249dSArnaldo Carvalho de Melo zfree(&path->name); 248e7c93f09SNamhyung Kim free(path); 249e7c93f09SNamhyung Kim path = NULL; 250e7c93f09SNamhyung Kim } 251e7c93f09SNamhyung Kim 252e7c93f09SNamhyung Kim return path; 253e7c93f09SNamhyung Kim } 254e7c93f09SNamhyung Kim 2551424dc96SDavid Ahern const char *event_type(int type) 2561424dc96SDavid Ahern { 2571424dc96SDavid Ahern switch (type) { 2581424dc96SDavid Ahern case PERF_TYPE_HARDWARE: 2591424dc96SDavid Ahern return "hardware"; 2601424dc96SDavid Ahern 2611424dc96SDavid Ahern case PERF_TYPE_SOFTWARE: 2621424dc96SDavid Ahern return "software"; 2631424dc96SDavid Ahern 2641424dc96SDavid Ahern case PERF_TYPE_TRACEPOINT: 2651424dc96SDavid Ahern return "tracepoint"; 2661424dc96SDavid Ahern 2671424dc96SDavid Ahern case PERF_TYPE_HW_CACHE: 2681424dc96SDavid Ahern return "hardware-cache"; 2691424dc96SDavid Ahern 2701424dc96SDavid Ahern default: 2711424dc96SDavid Ahern break; 2721424dc96SDavid Ahern } 2731424dc96SDavid Ahern 2741424dc96SDavid Ahern return "unknown"; 2751424dc96SDavid Ahern } 2761424dc96SDavid Ahern 2777ae92e74SYan, Zheng 2787ae92e74SYan, Zheng 279410136f5SStephane Eranian static struct perf_evsel * 280410136f5SStephane Eranian __add_event(struct list_head *list, int *idx, 2817ae92e74SYan, Zheng struct perf_event_attr *attr, 2827ae92e74SYan, Zheng char *name, struct cpu_map *cpus) 28389812fc8SJiri Olsa { 28489812fc8SJiri Olsa struct perf_evsel *evsel; 28589812fc8SJiri Olsa 28689812fc8SJiri Olsa event_attr_init(attr); 28789812fc8SJiri Olsa 288ef503831SArnaldo Carvalho de Melo evsel = perf_evsel__new_idx(attr, (*idx)++); 289c5cd8ac0SDavid Ahern if (!evsel) 290410136f5SStephane Eranian return NULL; 29189812fc8SJiri Olsa 2927ae92e74SYan, Zheng evsel->cpus = cpus; 2939db1763cSArnaldo Carvalho de Melo if (name) 29489812fc8SJiri Olsa evsel->name = strdup(name); 295b847cbdcSJiri Olsa list_add_tail(&evsel->node, list); 296410136f5SStephane Eranian return evsel; 29789812fc8SJiri Olsa } 29889812fc8SJiri Olsa 299c5cd8ac0SDavid Ahern static int add_event(struct list_head *list, int *idx, 3007ae92e74SYan, Zheng struct perf_event_attr *attr, char *name) 3017ae92e74SYan, Zheng { 302410136f5SStephane Eranian return __add_event(list, idx, attr, name, NULL) ? 0 : -ENOMEM; 3037ae92e74SYan, Zheng } 3047ae92e74SYan, Zheng 3050b668bc9SArnaldo Carvalho de Melo static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) 30686470930SIngo Molnar { 30786470930SIngo Molnar int i, j; 30861c45981SPaul Mackerras int n, longest = -1; 30986470930SIngo Molnar 31086470930SIngo Molnar for (i = 0; i < size; i++) { 3110b668bc9SArnaldo Carvalho de Melo for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) { 31261c45981SPaul Mackerras n = strlen(names[i][j]); 31389812fc8SJiri Olsa if (n > longest && !strncasecmp(str, names[i][j], n)) 31461c45981SPaul Mackerras longest = n; 31561c45981SPaul Mackerras } 31689812fc8SJiri Olsa if (longest > 0) 31786470930SIngo Molnar return i; 31886470930SIngo Molnar } 31986470930SIngo Molnar 3208953645fSIngo Molnar return -1; 32186470930SIngo Molnar } 32286470930SIngo Molnar 323c5cd8ac0SDavid Ahern int parse_events_add_cache(struct list_head *list, int *idx, 32489812fc8SJiri Olsa char *type, char *op_result1, char *op_result2) 32586470930SIngo Molnar { 32689812fc8SJiri Olsa struct perf_event_attr attr; 32789812fc8SJiri Olsa char name[MAX_NAME_LEN]; 32861c45981SPaul Mackerras int cache_type = -1, cache_op = -1, cache_result = -1; 32989812fc8SJiri Olsa char *op_result[2] = { op_result1, op_result2 }; 33089812fc8SJiri Olsa int i, n; 33186470930SIngo Molnar 33286470930SIngo Molnar /* 33386470930SIngo Molnar * No fallback - if we cannot get a clear cache type 33486470930SIngo Molnar * then bail out: 33586470930SIngo Molnar */ 3360b668bc9SArnaldo Carvalho de Melo cache_type = parse_aliases(type, perf_evsel__hw_cache, 33789812fc8SJiri Olsa PERF_COUNT_HW_CACHE_MAX); 33886470930SIngo Molnar if (cache_type == -1) 33989812fc8SJiri Olsa return -EINVAL; 34086470930SIngo Molnar 34189812fc8SJiri Olsa n = snprintf(name, MAX_NAME_LEN, "%s", type); 34289812fc8SJiri Olsa 34389812fc8SJiri Olsa for (i = 0; (i < 2) && (op_result[i]); i++) { 34489812fc8SJiri Olsa char *str = op_result[i]; 34589812fc8SJiri Olsa 346275ef387SJiri Olsa n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str); 34761c45981SPaul Mackerras 34861c45981SPaul Mackerras if (cache_op == -1) { 3490b668bc9SArnaldo Carvalho de Melo cache_op = parse_aliases(str, perf_evsel__hw_cache_op, 35061c45981SPaul Mackerras PERF_COUNT_HW_CACHE_OP_MAX); 35161c45981SPaul Mackerras if (cache_op >= 0) { 3520b668bc9SArnaldo Carvalho de Melo if (!perf_evsel__is_cache_op_valid(cache_type, cache_op)) 35389812fc8SJiri Olsa return -EINVAL; 35461c45981SPaul Mackerras continue; 35561c45981SPaul Mackerras } 35661c45981SPaul Mackerras } 35761c45981SPaul Mackerras 35861c45981SPaul Mackerras if (cache_result == -1) { 3590b668bc9SArnaldo Carvalho de Melo cache_result = parse_aliases(str, perf_evsel__hw_cache_result, 36061c45981SPaul Mackerras PERF_COUNT_HW_CACHE_RESULT_MAX); 36161c45981SPaul Mackerras if (cache_result >= 0) 36261c45981SPaul Mackerras continue; 36361c45981SPaul Mackerras } 36461c45981SPaul Mackerras } 36561c45981SPaul Mackerras 36686470930SIngo Molnar /* 36786470930SIngo Molnar * Fall back to reads: 36886470930SIngo Molnar */ 3698953645fSIngo Molnar if (cache_op == -1) 3708953645fSIngo Molnar cache_op = PERF_COUNT_HW_CACHE_OP_READ; 37186470930SIngo Molnar 37286470930SIngo Molnar /* 37386470930SIngo Molnar * Fall back to accesses: 37486470930SIngo Molnar */ 37586470930SIngo Molnar if (cache_result == -1) 37686470930SIngo Molnar cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 37786470930SIngo Molnar 37889812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 37989812fc8SJiri Olsa attr.config = cache_type | (cache_op << 8) | (cache_result << 16); 38089812fc8SJiri Olsa attr.type = PERF_TYPE_HW_CACHE; 38189812fc8SJiri Olsa return add_event(list, idx, &attr, name); 38286470930SIngo Molnar } 38386470930SIngo Molnar 384c5cd8ac0SDavid Ahern static int add_tracepoint(struct list_head *list, int *idx, 38589812fc8SJiri Olsa char *sys_name, char *evt_name) 386bcd3279fSFrederic Weisbecker { 38782fe1c29SArnaldo Carvalho de Melo struct perf_evsel *evsel; 388bcd3279fSFrederic Weisbecker 389ef503831SArnaldo Carvalho de Melo evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++); 390c5cd8ac0SDavid Ahern if (!evsel) 39182fe1c29SArnaldo Carvalho de Melo return -ENOMEM; 392bcd3279fSFrederic Weisbecker 39382fe1c29SArnaldo Carvalho de Melo list_add_tail(&evsel->node, list); 394c5cd8ac0SDavid Ahern 39582fe1c29SArnaldo Carvalho de Melo return 0; 396bcd3279fSFrederic Weisbecker } 397bcd3279fSFrederic Weisbecker 398c5cd8ac0SDavid Ahern static int add_tracepoint_multi_event(struct list_head *list, int *idx, 39989812fc8SJiri Olsa char *sys_name, char *evt_name) 400bcd3279fSFrederic Weisbecker { 401bcd3279fSFrederic Weisbecker char evt_path[MAXPATHLEN]; 402bcd3279fSFrederic Weisbecker struct dirent *evt_ent; 403bcd3279fSFrederic Weisbecker DIR *evt_dir; 40489812fc8SJiri Olsa int ret = 0; 405bcd3279fSFrederic Weisbecker 406ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); 407bcd3279fSFrederic Weisbecker evt_dir = opendir(evt_path); 408bcd3279fSFrederic Weisbecker if (!evt_dir) { 409bcd3279fSFrederic Weisbecker perror("Can't open event dir"); 41089812fc8SJiri Olsa return -1; 411bcd3279fSFrederic Weisbecker } 412bcd3279fSFrederic Weisbecker 41389812fc8SJiri Olsa while (!ret && (evt_ent = readdir(evt_dir))) { 414bcd3279fSFrederic Weisbecker if (!strcmp(evt_ent->d_name, ".") 415bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "..") 416bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "enable") 417bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "filter")) 418bcd3279fSFrederic Weisbecker continue; 419bcd3279fSFrederic Weisbecker 42089812fc8SJiri Olsa if (!strglobmatch(evt_ent->d_name, evt_name)) 421fb1d2edfSMasami Hiramatsu continue; 422fb1d2edfSMasami Hiramatsu 42389812fc8SJiri Olsa ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name); 424bcd3279fSFrederic Weisbecker } 425bcd3279fSFrederic Weisbecker 4260bd3f084SJiri Olsa closedir(evt_dir); 42789812fc8SJiri Olsa return ret; 428bcd3279fSFrederic Weisbecker } 429bcd3279fSFrederic Weisbecker 430c5cd8ac0SDavid Ahern static int add_tracepoint_event(struct list_head *list, int *idx, 431f35488f9SJiri Olsa char *sys_name, char *evt_name) 432f35488f9SJiri Olsa { 433f35488f9SJiri Olsa return strpbrk(evt_name, "*?") ? 434f35488f9SJiri Olsa add_tracepoint_multi_event(list, idx, sys_name, evt_name) : 435f35488f9SJiri Olsa add_tracepoint(list, idx, sys_name, evt_name); 436f35488f9SJiri Olsa } 437f35488f9SJiri Olsa 438c5cd8ac0SDavid Ahern static int add_tracepoint_multi_sys(struct list_head *list, int *idx, 439f35488f9SJiri Olsa char *sys_name, char *evt_name) 440f35488f9SJiri Olsa { 441f35488f9SJiri Olsa struct dirent *events_ent; 442f35488f9SJiri Olsa DIR *events_dir; 443f35488f9SJiri Olsa int ret = 0; 444f35488f9SJiri Olsa 445f35488f9SJiri Olsa events_dir = opendir(tracing_events_path); 446f35488f9SJiri Olsa if (!events_dir) { 447f35488f9SJiri Olsa perror("Can't open event dir"); 448f35488f9SJiri Olsa return -1; 449f35488f9SJiri Olsa } 450f35488f9SJiri Olsa 451f35488f9SJiri Olsa while (!ret && (events_ent = readdir(events_dir))) { 452f35488f9SJiri Olsa if (!strcmp(events_ent->d_name, ".") 453f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "..") 454f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "enable") 455f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "header_event") 456f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "header_page")) 457f35488f9SJiri Olsa continue; 458f35488f9SJiri Olsa 459f35488f9SJiri Olsa if (!strglobmatch(events_ent->d_name, sys_name)) 460f35488f9SJiri Olsa continue; 461f35488f9SJiri Olsa 462f35488f9SJiri Olsa ret = add_tracepoint_event(list, idx, events_ent->d_name, 463f35488f9SJiri Olsa evt_name); 464f35488f9SJiri Olsa } 465f35488f9SJiri Olsa 466f35488f9SJiri Olsa closedir(events_dir); 467f35488f9SJiri Olsa return ret; 468f35488f9SJiri Olsa } 469f35488f9SJiri Olsa 470c5cd8ac0SDavid Ahern int parse_events_add_tracepoint(struct list_head *list, int *idx, 47189812fc8SJiri Olsa char *sys, char *event) 472f6bdafefSJason Baron { 473f35488f9SJiri Olsa if (strpbrk(sys, "*?")) 474f35488f9SJiri Olsa return add_tracepoint_multi_sys(list, idx, sys, event); 475f35488f9SJiri Olsa else 476f35488f9SJiri Olsa return add_tracepoint_event(list, idx, sys, event); 4773a9f131fSFrederic Weisbecker } 4783a9f131fSFrederic Weisbecker 47989812fc8SJiri Olsa static int 48089812fc8SJiri Olsa parse_breakpoint_type(const char *type, struct perf_event_attr *attr) 4811b290d67SFrederic Weisbecker { 4821b290d67SFrederic Weisbecker int i; 4831b290d67SFrederic Weisbecker 4841b290d67SFrederic Weisbecker for (i = 0; i < 3; i++) { 48589812fc8SJiri Olsa if (!type || !type[i]) 4861b290d67SFrederic Weisbecker break; 4871b290d67SFrederic Weisbecker 4887582732fSJiri Olsa #define CHECK_SET_TYPE(bit) \ 4897582732fSJiri Olsa do { \ 4907582732fSJiri Olsa if (attr->bp_type & bit) \ 4917582732fSJiri Olsa return -EINVAL; \ 4927582732fSJiri Olsa else \ 4937582732fSJiri Olsa attr->bp_type |= bit; \ 4947582732fSJiri Olsa } while (0) 4957582732fSJiri Olsa 4961b290d67SFrederic Weisbecker switch (type[i]) { 4971b290d67SFrederic Weisbecker case 'r': 4987582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_R); 4991b290d67SFrederic Weisbecker break; 5001b290d67SFrederic Weisbecker case 'w': 5017582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_W); 5021b290d67SFrederic Weisbecker break; 5031b290d67SFrederic Weisbecker case 'x': 5047582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_X); 5051b290d67SFrederic Weisbecker break; 5061b290d67SFrederic Weisbecker default: 50789812fc8SJiri Olsa return -EINVAL; 5081b290d67SFrederic Weisbecker } 5091b290d67SFrederic Weisbecker } 51089812fc8SJiri Olsa 5117582732fSJiri Olsa #undef CHECK_SET_TYPE 5127582732fSJiri Olsa 5131b290d67SFrederic Weisbecker if (!attr->bp_type) /* Default */ 5141b290d67SFrederic Weisbecker attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 5151b290d67SFrederic Weisbecker 51689812fc8SJiri Olsa return 0; 5171b290d67SFrederic Weisbecker } 5181b290d67SFrederic Weisbecker 519c5cd8ac0SDavid Ahern int parse_events_add_breakpoint(struct list_head *list, int *idx, 5203741eb9fSJacob Shin void *ptr, char *type, u64 len) 5211b290d67SFrederic Weisbecker { 52289812fc8SJiri Olsa struct perf_event_attr attr; 5231b290d67SFrederic Weisbecker 52489812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 5259fafd98fSJiri Olsa attr.bp_addr = (unsigned long) ptr; 5261b290d67SFrederic Weisbecker 52789812fc8SJiri Olsa if (parse_breakpoint_type(type, &attr)) 52889812fc8SJiri Olsa return -EINVAL; 5291b290d67SFrederic Weisbecker 5303741eb9fSJacob Shin /* Provide some defaults if len is not specified */ 5313741eb9fSJacob Shin if (!len) { 53289812fc8SJiri Olsa if (attr.bp_type == HW_BREAKPOINT_X) 5333741eb9fSJacob Shin len = sizeof(long); 534aa59a485SFrederic Weisbecker else 5353741eb9fSJacob Shin len = HW_BREAKPOINT_LEN_4; 5363741eb9fSJacob Shin } 5373741eb9fSJacob Shin 5383741eb9fSJacob Shin attr.bp_len = len; 539aa59a485SFrederic Weisbecker 54089812fc8SJiri Olsa attr.type = PERF_TYPE_BREAKPOINT; 5414a841d65SJovi Zhang attr.sample_period = 1; 5421b290d67SFrederic Weisbecker 543287e74aaSJiri Olsa return add_event(list, idx, &attr, NULL); 5441b290d67SFrederic Weisbecker } 5451b290d67SFrederic Weisbecker 5468f707d84SJiri Olsa static int config_term(struct perf_event_attr *attr, 5476cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term) 5488f707d84SJiri Olsa { 54916fa7e82SJiri Olsa #define CHECK_TYPE_VAL(type) \ 55016fa7e82SJiri Olsa do { \ 55116fa7e82SJiri Olsa if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val) \ 55216fa7e82SJiri Olsa return -EINVAL; \ 55316fa7e82SJiri Olsa } while (0) 55416fa7e82SJiri Olsa 55516fa7e82SJiri Olsa switch (term->type_term) { 5568f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG: 55716fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5588f707d84SJiri Olsa attr->config = term->val.num; 5598f707d84SJiri Olsa break; 5608f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG1: 56116fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5628f707d84SJiri Olsa attr->config1 = term->val.num; 5638f707d84SJiri Olsa break; 5648f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG2: 56516fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5668f707d84SJiri Olsa attr->config2 = term->val.num; 5678f707d84SJiri Olsa break; 5688f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 56916fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5708f707d84SJiri Olsa attr->sample_period = term->val.num; 5718f707d84SJiri Olsa break; 5728f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: 5738f707d84SJiri Olsa /* 5748f707d84SJiri Olsa * TODO uncomment when the field is available 5758f707d84SJiri Olsa * attr->branch_sample_type = term->val.num; 5768f707d84SJiri Olsa */ 5778f707d84SJiri Olsa break; 5786b5fc39bSJiri Olsa case PARSE_EVENTS__TERM_TYPE_NAME: 5796b5fc39bSJiri Olsa CHECK_TYPE_VAL(STR); 5806b5fc39bSJiri Olsa break; 5818f707d84SJiri Olsa default: 5828f707d84SJiri Olsa return -EINVAL; 5838f707d84SJiri Olsa } 58416fa7e82SJiri Olsa 5858f707d84SJiri Olsa return 0; 58616fa7e82SJiri Olsa #undef CHECK_TYPE_VAL 5878f707d84SJiri Olsa } 5888f707d84SJiri Olsa 5898f707d84SJiri Olsa static int config_attr(struct perf_event_attr *attr, 5908f707d84SJiri Olsa struct list_head *head, int fail) 5918f707d84SJiri Olsa { 5926cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 5938f707d84SJiri Olsa 5948f707d84SJiri Olsa list_for_each_entry(term, head, list) 5958f707d84SJiri Olsa if (config_term(attr, term) && fail) 5968f707d84SJiri Olsa return -EINVAL; 5978f707d84SJiri Olsa 5988f707d84SJiri Olsa return 0; 5998f707d84SJiri Olsa } 6008f707d84SJiri Olsa 601c5cd8ac0SDavid Ahern int parse_events_add_numeric(struct list_head *list, int *idx, 602b527bab5SRobert Richter u32 type, u64 config, 6038f707d84SJiri Olsa struct list_head *head_config) 60474d5b588SJaswinder Singh Rajput { 60589812fc8SJiri Olsa struct perf_event_attr attr; 60674d5b588SJaswinder Singh Rajput 60789812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 60889812fc8SJiri Olsa attr.type = type; 60989812fc8SJiri Olsa attr.config = config; 6108f707d84SJiri Olsa 6118f707d84SJiri Olsa if (head_config && 6128f707d84SJiri Olsa config_attr(&attr, head_config, 1)) 6138f707d84SJiri Olsa return -EINVAL; 6148f707d84SJiri Olsa 6159db1763cSArnaldo Carvalho de Melo return add_event(list, idx, &attr, NULL); 616b908debdSIngo Molnar } 617b908debdSIngo Molnar 6186cee6cd3SArnaldo Carvalho de Melo static int parse_events__is_name_term(struct parse_events_term *term) 6196b5fc39bSJiri Olsa { 6206b5fc39bSJiri Olsa return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; 6216b5fc39bSJiri Olsa } 6226b5fc39bSJiri Olsa 6239db1763cSArnaldo Carvalho de Melo static char *pmu_event_name(struct list_head *head_terms) 6246b5fc39bSJiri Olsa { 6256cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 6266b5fc39bSJiri Olsa 6276b5fc39bSJiri Olsa list_for_each_entry(term, head_terms, list) 6286b5fc39bSJiri Olsa if (parse_events__is_name_term(term)) 6296b5fc39bSJiri Olsa return term->val.str; 6306b5fc39bSJiri Olsa 6319db1763cSArnaldo Carvalho de Melo return NULL; 6326b5fc39bSJiri Olsa } 6336b5fc39bSJiri Olsa 634c5cd8ac0SDavid Ahern int parse_events_add_pmu(struct list_head *list, int *idx, 6355f537a26SJiri Olsa char *name, struct list_head *head_config) 6365f537a26SJiri Olsa { 6375f537a26SJiri Olsa struct perf_event_attr attr; 63846441bdcSMatt Fleming struct perf_pmu_info info; 6395f537a26SJiri Olsa struct perf_pmu *pmu; 640410136f5SStephane Eranian struct perf_evsel *evsel; 6415f537a26SJiri Olsa 6425f537a26SJiri Olsa pmu = perf_pmu__find(name); 6435f537a26SJiri Olsa if (!pmu) 6445f537a26SJiri Olsa return -EINVAL; 6455f537a26SJiri Olsa 646dc0a6202SAdrian Hunter if (pmu->default_config) { 647dc0a6202SAdrian Hunter memcpy(&attr, pmu->default_config, 648dc0a6202SAdrian Hunter sizeof(struct perf_event_attr)); 649dc0a6202SAdrian Hunter } else { 6505f537a26SJiri Olsa memset(&attr, 0, sizeof(attr)); 651dc0a6202SAdrian Hunter } 6525f537a26SJiri Olsa 653ad962273SAdrian Hunter if (!head_config) { 654ad962273SAdrian Hunter attr.type = pmu->type; 655ad962273SAdrian Hunter evsel = __add_event(list, idx, &attr, NULL, pmu->cpus); 656ad962273SAdrian Hunter return evsel ? 0 : -ENOMEM; 657ad962273SAdrian Hunter } 658ad962273SAdrian Hunter 65946441bdcSMatt Fleming if (perf_pmu__check_alias(pmu, head_config, &info)) 660a6146d50SZheng Yan return -EINVAL; 661a6146d50SZheng Yan 6625f537a26SJiri Olsa /* 6635f537a26SJiri Olsa * Configure hardcoded terms first, no need to check 6645f537a26SJiri Olsa * return value when called with fail == 0 ;) 6655f537a26SJiri Olsa */ 6665f537a26SJiri Olsa config_attr(&attr, head_config, 0); 6675f537a26SJiri Olsa 6685f537a26SJiri Olsa if (perf_pmu__config(pmu, &attr, head_config)) 6695f537a26SJiri Olsa return -EINVAL; 6705f537a26SJiri Olsa 671410136f5SStephane Eranian evsel = __add_event(list, idx, &attr, pmu_event_name(head_config), 6727ae92e74SYan, Zheng pmu->cpus); 673410136f5SStephane Eranian if (evsel) { 67446441bdcSMatt Fleming evsel->unit = info.unit; 67546441bdcSMatt Fleming evsel->scale = info.scale; 676044330c1SMatt Fleming evsel->per_pkg = info.per_pkg; 6771d9e446bSJiri Olsa evsel->snapshot = info.snapshot; 678410136f5SStephane Eranian } 679410136f5SStephane Eranian 680410136f5SStephane Eranian return evsel ? 0 : -ENOMEM; 6815f537a26SJiri Olsa } 6825f537a26SJiri Olsa 6836a4bb04cSJiri Olsa int parse_events__modifier_group(struct list_head *list, 6846a4bb04cSJiri Olsa char *event_mod) 68589efb029SJiri Olsa { 6866a4bb04cSJiri Olsa return parse_events__modifier_event(list, event_mod, true); 6876a4bb04cSJiri Olsa } 6886a4bb04cSJiri Olsa 68963dab225SArnaldo Carvalho de Melo void parse_events__set_leader(char *name, struct list_head *list) 6906a4bb04cSJiri Olsa { 6916a4bb04cSJiri Olsa struct perf_evsel *leader; 6926a4bb04cSJiri Olsa 69363dab225SArnaldo Carvalho de Melo __perf_evlist__set_leader(list); 69463dab225SArnaldo Carvalho de Melo leader = list_entry(list->next, struct perf_evsel, node); 6956a4bb04cSJiri Olsa leader->group_name = name ? strdup(name) : NULL; 69689efb029SJiri Olsa } 69789efb029SJiri Olsa 698c5cd8ac0SDavid Ahern /* list_event is assumed to point to malloc'ed memory */ 6995d7be90eSJiri Olsa void parse_events_update_lists(struct list_head *list_event, 7005d7be90eSJiri Olsa struct list_head *list_all) 7015d7be90eSJiri Olsa { 7025d7be90eSJiri Olsa /* 7035d7be90eSJiri Olsa * Called for single event definition. Update the 70489efb029SJiri Olsa * 'all event' list, and reinit the 'single event' 7055d7be90eSJiri Olsa * list, for next event definition. 7065d7be90eSJiri Olsa */ 7075d7be90eSJiri Olsa list_splice_tail(list_event, list_all); 708b847cbdcSJiri Olsa free(list_event); 7095d7be90eSJiri Olsa } 7105d7be90eSJiri Olsa 711f5b1135bSJiri Olsa struct event_modifier { 712f5b1135bSJiri Olsa int eu; 713f5b1135bSJiri Olsa int ek; 714f5b1135bSJiri Olsa int eh; 715f5b1135bSJiri Olsa int eH; 716f5b1135bSJiri Olsa int eG; 717f5b1135bSJiri Olsa int precise; 718f5b1135bSJiri Olsa int exclude_GH; 7193c176311SJiri Olsa int sample_read; 720e9a7c414SMichael Ellerman int pinned; 721f5b1135bSJiri Olsa }; 72261c45981SPaul Mackerras 723f5b1135bSJiri Olsa static int get_event_modifier(struct event_modifier *mod, char *str, 724f5b1135bSJiri Olsa struct perf_evsel *evsel) 725f5b1135bSJiri Olsa { 726f5b1135bSJiri Olsa int eu = evsel ? evsel->attr.exclude_user : 0; 727f5b1135bSJiri Olsa int ek = evsel ? evsel->attr.exclude_kernel : 0; 728f5b1135bSJiri Olsa int eh = evsel ? evsel->attr.exclude_hv : 0; 729f5b1135bSJiri Olsa int eH = evsel ? evsel->attr.exclude_host : 0; 730f5b1135bSJiri Olsa int eG = evsel ? evsel->attr.exclude_guest : 0; 731f5b1135bSJiri Olsa int precise = evsel ? evsel->attr.precise_ip : 0; 7323c176311SJiri Olsa int sample_read = 0; 733e9a7c414SMichael Ellerman int pinned = evsel ? evsel->attr.pinned : 0; 734f5b1135bSJiri Olsa 735f5b1135bSJiri Olsa int exclude = eu | ek | eh; 736f5b1135bSJiri Olsa int exclude_GH = evsel ? evsel->exclude_GH : 0; 737f5b1135bSJiri Olsa 738f5b1135bSJiri Olsa memset(mod, 0, sizeof(*mod)); 739ceb53fbfSIngo Molnar 74061c45981SPaul Mackerras while (*str) { 741ab608344SPeter Zijlstra if (*str == 'u') { 742ab608344SPeter Zijlstra if (!exclude) 743ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 74461c45981SPaul Mackerras eu = 0; 745ab608344SPeter Zijlstra } else if (*str == 'k') { 746ab608344SPeter Zijlstra if (!exclude) 747ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 74861c45981SPaul Mackerras ek = 0; 749ab608344SPeter Zijlstra } else if (*str == 'h') { 750ab608344SPeter Zijlstra if (!exclude) 751ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 75261c45981SPaul Mackerras eh = 0; 75399320cc8SJoerg Roedel } else if (*str == 'G') { 75499320cc8SJoerg Roedel if (!exclude_GH) 75599320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 75699320cc8SJoerg Roedel eG = 0; 75799320cc8SJoerg Roedel } else if (*str == 'H') { 75899320cc8SJoerg Roedel if (!exclude_GH) 75999320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 76099320cc8SJoerg Roedel eH = 0; 761ab608344SPeter Zijlstra } else if (*str == 'p') { 762ab608344SPeter Zijlstra precise++; 7631342798cSDavid Ahern /* use of precise requires exclude_guest */ 7641342798cSDavid Ahern if (!exclude_GH) 7651342798cSDavid Ahern eG = 1; 7663c176311SJiri Olsa } else if (*str == 'S') { 7673c176311SJiri Olsa sample_read = 1; 768e9a7c414SMichael Ellerman } else if (*str == 'D') { 769e9a7c414SMichael Ellerman pinned = 1; 770ab608344SPeter Zijlstra } else 77161c45981SPaul Mackerras break; 772ab608344SPeter Zijlstra 77361c45981SPaul Mackerras ++str; 77461c45981SPaul Mackerras } 77574d5b588SJaswinder Singh Rajput 77686470930SIngo Molnar /* 77789812fc8SJiri Olsa * precise ip: 77889812fc8SJiri Olsa * 77989812fc8SJiri Olsa * 0 - SAMPLE_IP can have arbitrary skid 78089812fc8SJiri Olsa * 1 - SAMPLE_IP must have constant skid 78189812fc8SJiri Olsa * 2 - SAMPLE_IP requested to have 0 skid 78289812fc8SJiri Olsa * 3 - SAMPLE_IP must have 0 skid 78389812fc8SJiri Olsa * 78489812fc8SJiri Olsa * See also PERF_RECORD_MISC_EXACT_IP 78586470930SIngo Molnar */ 78689812fc8SJiri Olsa if (precise > 3) 78789812fc8SJiri Olsa return -EINVAL; 78886470930SIngo Molnar 789f5b1135bSJiri Olsa mod->eu = eu; 790f5b1135bSJiri Olsa mod->ek = ek; 791f5b1135bSJiri Olsa mod->eh = eh; 792f5b1135bSJiri Olsa mod->eH = eH; 793f5b1135bSJiri Olsa mod->eG = eG; 794f5b1135bSJiri Olsa mod->precise = precise; 795f5b1135bSJiri Olsa mod->exclude_GH = exclude_GH; 7963c176311SJiri Olsa mod->sample_read = sample_read; 797e9a7c414SMichael Ellerman mod->pinned = pinned; 798e9a7c414SMichael Ellerman 799f5b1135bSJiri Olsa return 0; 800f5b1135bSJiri Olsa } 801f5b1135bSJiri Olsa 802534123f4SJiri Olsa /* 803534123f4SJiri Olsa * Basic modifier sanity check to validate it contains only one 804534123f4SJiri Olsa * instance of any modifier (apart from 'p') present. 805534123f4SJiri Olsa */ 806534123f4SJiri Olsa static int check_modifier(char *str) 807534123f4SJiri Olsa { 808534123f4SJiri Olsa char *p = str; 809534123f4SJiri Olsa 810534123f4SJiri Olsa /* The sizeof includes 0 byte as well. */ 811e9a7c414SMichael Ellerman if (strlen(str) > (sizeof("ukhGHpppSD") - 1)) 812534123f4SJiri Olsa return -1; 813534123f4SJiri Olsa 814534123f4SJiri Olsa while (*p) { 815534123f4SJiri Olsa if (*p != 'p' && strchr(p + 1, *p)) 816534123f4SJiri Olsa return -1; 817534123f4SJiri Olsa p++; 818534123f4SJiri Olsa } 819534123f4SJiri Olsa 820534123f4SJiri Olsa return 0; 821534123f4SJiri Olsa } 822534123f4SJiri Olsa 823f5b1135bSJiri Olsa int parse_events__modifier_event(struct list_head *list, char *str, bool add) 824f5b1135bSJiri Olsa { 825f5b1135bSJiri Olsa struct perf_evsel *evsel; 826f5b1135bSJiri Olsa struct event_modifier mod; 827f5b1135bSJiri Olsa 828f5b1135bSJiri Olsa if (str == NULL) 829f5b1135bSJiri Olsa return 0; 830f5b1135bSJiri Olsa 831534123f4SJiri Olsa if (check_modifier(str)) 832534123f4SJiri Olsa return -EINVAL; 833534123f4SJiri Olsa 834f5b1135bSJiri Olsa if (!add && get_event_modifier(&mod, str, NULL)) 835f5b1135bSJiri Olsa return -EINVAL; 836f5b1135bSJiri Olsa 8370050f7aaSArnaldo Carvalho de Melo __evlist__for_each(list, evsel) { 838f5b1135bSJiri Olsa if (add && get_event_modifier(&mod, str, evsel)) 839f5b1135bSJiri Olsa return -EINVAL; 840f5b1135bSJiri Olsa 841f5b1135bSJiri Olsa evsel->attr.exclude_user = mod.eu; 842f5b1135bSJiri Olsa evsel->attr.exclude_kernel = mod.ek; 843f5b1135bSJiri Olsa evsel->attr.exclude_hv = mod.eh; 844f5b1135bSJiri Olsa evsel->attr.precise_ip = mod.precise; 845f5b1135bSJiri Olsa evsel->attr.exclude_host = mod.eH; 846f5b1135bSJiri Olsa evsel->attr.exclude_guest = mod.eG; 847f5b1135bSJiri Olsa evsel->exclude_GH = mod.exclude_GH; 8483c176311SJiri Olsa evsel->sample_read = mod.sample_read; 849e9a7c414SMichael Ellerman 850e9a7c414SMichael Ellerman if (perf_evsel__is_group_leader(evsel)) 851e9a7c414SMichael Ellerman evsel->attr.pinned = mod.pinned; 852ceb53fbfSIngo Molnar } 85386470930SIngo Molnar 85489812fc8SJiri Olsa return 0; 85586470930SIngo Molnar } 85686470930SIngo Molnar 857ac2ba9f3SRobert Richter int parse_events_name(struct list_head *list, char *name) 858ac2ba9f3SRobert Richter { 859ac2ba9f3SRobert Richter struct perf_evsel *evsel; 860ac2ba9f3SRobert Richter 8610050f7aaSArnaldo Carvalho de Melo __evlist__for_each(list, evsel) { 862ac2ba9f3SRobert Richter if (!evsel->name) 863ac2ba9f3SRobert Richter evsel->name = strdup(name); 864ac2ba9f3SRobert Richter } 865ac2ba9f3SRobert Richter 866ac2ba9f3SRobert Richter return 0; 867ac2ba9f3SRobert Richter } 868ac2ba9f3SRobert Richter 869dcb4e102SKan Liang static int 870dcb4e102SKan Liang comp_pmu(const void *p1, const void *p2) 871dcb4e102SKan Liang { 872dcb4e102SKan Liang struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1; 873dcb4e102SKan Liang struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2; 874dcb4e102SKan Liang 875dcb4e102SKan Liang return strcmp(pmu1->symbol, pmu2->symbol); 876dcb4e102SKan Liang } 877dcb4e102SKan Liang 878dcb4e102SKan Liang static void perf_pmu__parse_cleanup(void) 879dcb4e102SKan Liang { 880dcb4e102SKan Liang if (perf_pmu_events_list_num > 0) { 881dcb4e102SKan Liang struct perf_pmu_event_symbol *p; 882dcb4e102SKan Liang int i; 883dcb4e102SKan Liang 884dcb4e102SKan Liang for (i = 0; i < perf_pmu_events_list_num; i++) { 885dcb4e102SKan Liang p = perf_pmu_events_list + i; 886dcb4e102SKan Liang free(p->symbol); 887dcb4e102SKan Liang } 888dcb4e102SKan Liang free(perf_pmu_events_list); 889dcb4e102SKan Liang perf_pmu_events_list = NULL; 890dcb4e102SKan Liang perf_pmu_events_list_num = 0; 891dcb4e102SKan Liang } 892dcb4e102SKan Liang } 893dcb4e102SKan Liang 894dcb4e102SKan Liang #define SET_SYMBOL(str, stype) \ 895dcb4e102SKan Liang do { \ 896dcb4e102SKan Liang p->symbol = str; \ 897dcb4e102SKan Liang if (!p->symbol) \ 898dcb4e102SKan Liang goto err; \ 899dcb4e102SKan Liang p->type = stype; \ 900dcb4e102SKan Liang } while (0) 901dcb4e102SKan Liang 902dcb4e102SKan Liang /* 903dcb4e102SKan Liang * Read the pmu events list from sysfs 904dcb4e102SKan Liang * Save it into perf_pmu_events_list 905dcb4e102SKan Liang */ 906dcb4e102SKan Liang static void perf_pmu__parse_init(void) 907dcb4e102SKan Liang { 908dcb4e102SKan Liang 909dcb4e102SKan Liang struct perf_pmu *pmu = NULL; 910dcb4e102SKan Liang struct perf_pmu_alias *alias; 911dcb4e102SKan Liang int len = 0; 912dcb4e102SKan Liang 913dcb4e102SKan Liang pmu = perf_pmu__find("cpu"); 914dcb4e102SKan Liang if ((pmu == NULL) || list_empty(&pmu->aliases)) { 915dcb4e102SKan Liang perf_pmu_events_list_num = -1; 916dcb4e102SKan Liang return; 917dcb4e102SKan Liang } 918dcb4e102SKan Liang list_for_each_entry(alias, &pmu->aliases, list) { 919dcb4e102SKan Liang if (strchr(alias->name, '-')) 920dcb4e102SKan Liang len++; 921dcb4e102SKan Liang len++; 922dcb4e102SKan Liang } 923dcb4e102SKan Liang perf_pmu_events_list = malloc(sizeof(struct perf_pmu_event_symbol) * len); 924dcb4e102SKan Liang if (!perf_pmu_events_list) 925dcb4e102SKan Liang return; 926dcb4e102SKan Liang perf_pmu_events_list_num = len; 927dcb4e102SKan Liang 928dcb4e102SKan Liang len = 0; 929dcb4e102SKan Liang list_for_each_entry(alias, &pmu->aliases, list) { 930dcb4e102SKan Liang struct perf_pmu_event_symbol *p = perf_pmu_events_list + len; 931dcb4e102SKan Liang char *tmp = strchr(alias->name, '-'); 932dcb4e102SKan Liang 933dcb4e102SKan Liang if (tmp != NULL) { 934dcb4e102SKan Liang SET_SYMBOL(strndup(alias->name, tmp - alias->name), 935dcb4e102SKan Liang PMU_EVENT_SYMBOL_PREFIX); 936dcb4e102SKan Liang p++; 937dcb4e102SKan Liang SET_SYMBOL(strdup(++tmp), PMU_EVENT_SYMBOL_SUFFIX); 938dcb4e102SKan Liang len += 2; 939dcb4e102SKan Liang } else { 940dcb4e102SKan Liang SET_SYMBOL(strdup(alias->name), PMU_EVENT_SYMBOL); 941dcb4e102SKan Liang len++; 942dcb4e102SKan Liang } 943dcb4e102SKan Liang } 944dcb4e102SKan Liang qsort(perf_pmu_events_list, len, 945dcb4e102SKan Liang sizeof(struct perf_pmu_event_symbol), comp_pmu); 946dcb4e102SKan Liang 947dcb4e102SKan Liang return; 948dcb4e102SKan Liang err: 949dcb4e102SKan Liang perf_pmu__parse_cleanup(); 950dcb4e102SKan Liang } 951dcb4e102SKan Liang 952dcb4e102SKan Liang enum perf_pmu_event_symbol_type 953dcb4e102SKan Liang perf_pmu__parse_check(const char *name) 954dcb4e102SKan Liang { 955dcb4e102SKan Liang struct perf_pmu_event_symbol p, *r; 956dcb4e102SKan Liang 957dcb4e102SKan Liang /* scan kernel pmu events from sysfs if needed */ 958dcb4e102SKan Liang if (perf_pmu_events_list_num == 0) 959dcb4e102SKan Liang perf_pmu__parse_init(); 960dcb4e102SKan Liang /* 961dcb4e102SKan Liang * name "cpu" could be prefix of cpu-cycles or cpu// events. 962dcb4e102SKan Liang * cpu-cycles has been handled by hardcode. 963dcb4e102SKan Liang * So it must be cpu// events, not kernel pmu event. 964dcb4e102SKan Liang */ 965dcb4e102SKan Liang if ((perf_pmu_events_list_num <= 0) || !strcmp(name, "cpu")) 966dcb4e102SKan Liang return PMU_EVENT_SYMBOL_ERR; 967dcb4e102SKan Liang 968dcb4e102SKan Liang p.symbol = strdup(name); 969dcb4e102SKan Liang r = bsearch(&p, perf_pmu_events_list, 970dcb4e102SKan Liang (size_t) perf_pmu_events_list_num, 971dcb4e102SKan Liang sizeof(struct perf_pmu_event_symbol), comp_pmu); 972dcb4e102SKan Liang free(p.symbol); 973dcb4e102SKan Liang return r ? r->type : PMU_EVENT_SYMBOL_ERR; 974dcb4e102SKan Liang } 975dcb4e102SKan Liang 97690e2b22dSJiri Olsa static int parse_events__scanner(const char *str, void *data, int start_token) 977ac20de6fSZheng Yan { 978ac20de6fSZheng Yan YY_BUFFER_STATE buffer; 979ac20de6fSZheng Yan void *scanner; 980ac20de6fSZheng Yan int ret; 981ac20de6fSZheng Yan 98290e2b22dSJiri Olsa ret = parse_events_lex_init_extra(start_token, &scanner); 983ac20de6fSZheng Yan if (ret) 984ac20de6fSZheng Yan return ret; 985ac20de6fSZheng Yan 986ac20de6fSZheng Yan buffer = parse_events__scan_string(str, scanner); 987ac20de6fSZheng Yan 988ac20de6fSZheng Yan #ifdef PARSER_DEBUG 989ac20de6fSZheng Yan parse_events_debug = 1; 990ac20de6fSZheng Yan #endif 991ac20de6fSZheng Yan ret = parse_events_parse(data, scanner); 992ac20de6fSZheng Yan 993ac20de6fSZheng Yan parse_events__flush_buffer(buffer, scanner); 994ac20de6fSZheng Yan parse_events__delete_buffer(buffer, scanner); 995ac20de6fSZheng Yan parse_events_lex_destroy(scanner); 996ac20de6fSZheng Yan return ret; 997ac20de6fSZheng Yan } 998ac20de6fSZheng Yan 99990e2b22dSJiri Olsa /* 100090e2b22dSJiri Olsa * parse event config string, return a list of event terms. 100190e2b22dSJiri Olsa */ 100290e2b22dSJiri Olsa int parse_events_terms(struct list_head *terms, const char *str) 100390e2b22dSJiri Olsa { 100423b6339bSArnaldo Carvalho de Melo struct parse_events_terms data = { 100590e2b22dSJiri Olsa .terms = NULL, 100690e2b22dSJiri Olsa }; 100790e2b22dSJiri Olsa int ret; 100890e2b22dSJiri Olsa 100990e2b22dSJiri Olsa ret = parse_events__scanner(str, &data, PE_START_TERMS); 101090e2b22dSJiri Olsa if (!ret) { 101190e2b22dSJiri Olsa list_splice(data.terms, terms); 101274cf249dSArnaldo Carvalho de Melo zfree(&data.terms); 101390e2b22dSJiri Olsa return 0; 101490e2b22dSJiri Olsa } 101590e2b22dSJiri Olsa 1016b2c34fdeSAdrian Hunter if (data.terms) 101790e2b22dSJiri Olsa parse_events__free_terms(data.terms); 101890e2b22dSJiri Olsa return ret; 101990e2b22dSJiri Olsa } 102090e2b22dSJiri Olsa 1021d8f7bbc9SJiri Olsa int parse_events(struct perf_evlist *evlist, const char *str) 102286470930SIngo Molnar { 102323b6339bSArnaldo Carvalho de Melo struct parse_events_evlist data = { 102446010ab2SJiri Olsa .list = LIST_HEAD_INIT(data.list), 102546010ab2SJiri Olsa .idx = evlist->nr_entries, 102646010ab2SJiri Olsa }; 102746010ab2SJiri Olsa int ret; 102886470930SIngo Molnar 102990e2b22dSJiri Olsa ret = parse_events__scanner(str, &data, PE_START_EVENTS); 1030dcb4e102SKan Liang perf_pmu__parse_cleanup(); 103189812fc8SJiri Olsa if (!ret) { 103246010ab2SJiri Olsa int entries = data.idx - evlist->nr_entries; 103346010ab2SJiri Olsa perf_evlist__splice_list_tail(evlist, &data.list, entries); 103497f63e4aSNamhyung Kim evlist->nr_groups += data.nr_groups; 103586470930SIngo Molnar return 0; 103686470930SIngo Molnar } 103786470930SIngo Molnar 10385d7be90eSJiri Olsa /* 10395d7be90eSJiri Olsa * There are 2 users - builtin-record and builtin-test objects. 10405d7be90eSJiri Olsa * Both call perf_evlist__delete in case of error, so we dont 10415d7be90eSJiri Olsa * need to bother. 10425d7be90eSJiri Olsa */ 104389812fc8SJiri Olsa return ret; 104489812fc8SJiri Olsa } 104589812fc8SJiri Olsa 1046f120f9d5SJiri Olsa int parse_events_option(const struct option *opt, const char *str, 10471d037ca1SIrina Tirdea int unset __maybe_unused) 1048f120f9d5SJiri Olsa { 1049f120f9d5SJiri Olsa struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 1050d8f7bbc9SJiri Olsa int ret = parse_events(evlist, str); 10519175ce1fSAndi Kleen 10529175ce1fSAndi Kleen if (ret) { 10539175ce1fSAndi Kleen fprintf(stderr, "invalid or unsupported event: '%s'\n", str); 10549175ce1fSAndi Kleen fprintf(stderr, "Run 'perf list' for a list of valid events\n"); 10559175ce1fSAndi Kleen } 10569175ce1fSAndi Kleen return ret; 1057f120f9d5SJiri Olsa } 1058f120f9d5SJiri Olsa 1059361c99a6SArnaldo Carvalho de Melo int parse_filter(const struct option *opt, const char *str, 10601d037ca1SIrina Tirdea int unset __maybe_unused) 1061c171b552SLi Zefan { 1062361c99a6SArnaldo Carvalho de Melo struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 106369aad6f1SArnaldo Carvalho de Melo struct perf_evsel *last = NULL; 1064c171b552SLi Zefan 1065361c99a6SArnaldo Carvalho de Melo if (evlist->nr_entries > 0) 10660c21f736SArnaldo Carvalho de Melo last = perf_evlist__last(evlist); 106769aad6f1SArnaldo Carvalho de Melo 106869aad6f1SArnaldo Carvalho de Melo if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { 1069c171b552SLi Zefan fprintf(stderr, 1070281f92f2SArnaldo Carvalho de Melo "--filter option should follow a -e tracepoint option\n"); 1071c171b552SLi Zefan return -1; 1072c171b552SLi Zefan } 1073c171b552SLi Zefan 107469aad6f1SArnaldo Carvalho de Melo last->filter = strdup(str); 107569aad6f1SArnaldo Carvalho de Melo if (last->filter == NULL) { 1076c171b552SLi Zefan fprintf(stderr, "not enough memory to hold filter string\n"); 1077c171b552SLi Zefan return -1; 1078c171b552SLi Zefan } 1079c171b552SLi Zefan 1080c171b552SLi Zefan return 0; 1081c171b552SLi Zefan } 1082c171b552SLi Zefan 108386470930SIngo Molnar static const char * const event_type_descriptors[] = { 108486470930SIngo Molnar "Hardware event", 108586470930SIngo Molnar "Software event", 108686470930SIngo Molnar "Tracepoint event", 108786470930SIngo Molnar "Hardware cache event", 108841bdcb23SLiming Wang "Raw hardware event descriptor", 108941bdcb23SLiming Wang "Hardware breakpoint", 109086470930SIngo Molnar }; 109186470930SIngo Molnar 1092*ab0e4800SYunlong Song static int cmp_string(const void *a, const void *b) 1093*ab0e4800SYunlong Song { 1094*ab0e4800SYunlong Song const char * const *as = a; 1095*ab0e4800SYunlong Song const char * const *bs = b; 1096*ab0e4800SYunlong Song 1097*ab0e4800SYunlong Song return strcmp(*as, *bs); 1098*ab0e4800SYunlong Song } 1099*ab0e4800SYunlong Song 110086470930SIngo Molnar /* 1101f6bdafefSJason Baron * Print the events from <debugfs_mount_point>/tracing/events 1102f6bdafefSJason Baron */ 1103f6bdafefSJason Baron 1104a3277d2dSFrederic Weisbecker void print_tracepoint_events(const char *subsys_glob, const char *event_glob, 1105a3277d2dSFrederic Weisbecker bool name_only) 1106f6bdafefSJason Baron { 1107f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 1108f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1109f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 1110725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 1111*ab0e4800SYunlong Song char **evt_list = NULL; 1112*ab0e4800SYunlong Song unsigned int evt_i = 0, evt_num = 0; 1113*ab0e4800SYunlong Song bool evt_num_known = false; 1114f6bdafefSJason Baron 1115*ab0e4800SYunlong Song restart: 1116ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 1117f6bdafefSJason Baron if (!sys_dir) 1118725b1368SEric Dumazet return; 1119f6bdafefSJason Baron 1120*ab0e4800SYunlong Song if (evt_num_known) { 1121*ab0e4800SYunlong Song evt_list = zalloc(sizeof(char *) * evt_num); 1122*ab0e4800SYunlong Song if (!evt_list) 1123*ab0e4800SYunlong Song goto out_close_sys_dir; 1124*ab0e4800SYunlong Song } 1125*ab0e4800SYunlong Song 11266b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 1127668b8788SArnaldo Carvalho de Melo if (subsys_glob != NULL && 1128668b8788SArnaldo Carvalho de Melo !strglobmatch(sys_dirent.d_name, subsys_glob)) 1129668b8788SArnaldo Carvalho de Melo continue; 1130725b1368SEric Dumazet 1131ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 1132725b1368SEric Dumazet sys_dirent.d_name); 1133725b1368SEric Dumazet evt_dir = opendir(dir_path); 1134725b1368SEric Dumazet if (!evt_dir) 11356b58e7f1SUlrich Drepper continue; 1136725b1368SEric Dumazet 11376b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 1138668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 1139668b8788SArnaldo Carvalho de Melo !strglobmatch(evt_dirent.d_name, event_glob)) 1140668b8788SArnaldo Carvalho de Melo continue; 1141668b8788SArnaldo Carvalho de Melo 1142*ab0e4800SYunlong Song if (!evt_num_known) { 1143*ab0e4800SYunlong Song evt_num++; 1144a3277d2dSFrederic Weisbecker continue; 1145a3277d2dSFrederic Weisbecker } 1146a3277d2dSFrederic Weisbecker 1147f6bdafefSJason Baron snprintf(evt_path, MAXPATHLEN, "%s:%s", 1148f6bdafefSJason Baron sys_dirent.d_name, evt_dirent.d_name); 1149*ab0e4800SYunlong Song 1150*ab0e4800SYunlong Song evt_list[evt_i] = strdup(evt_path); 1151*ab0e4800SYunlong Song if (evt_list[evt_i] == NULL) 1152*ab0e4800SYunlong Song goto out_close_evt_dir; 1153*ab0e4800SYunlong Song evt_i++; 1154f6bdafefSJason Baron } 1155f6bdafefSJason Baron closedir(evt_dir); 1156f6bdafefSJason Baron } 1157f6bdafefSJason Baron closedir(sys_dir); 1158*ab0e4800SYunlong Song 1159*ab0e4800SYunlong Song if (!evt_num_known) { 1160*ab0e4800SYunlong Song evt_num_known = true; 1161*ab0e4800SYunlong Song goto restart; 1162*ab0e4800SYunlong Song } 1163*ab0e4800SYunlong Song qsort(evt_list, evt_num, sizeof(char *), cmp_string); 1164*ab0e4800SYunlong Song evt_i = 0; 1165*ab0e4800SYunlong Song while (evt_i < evt_num) { 1166*ab0e4800SYunlong Song if (name_only) { 1167*ab0e4800SYunlong Song printf("%s ", evt_list[evt_i++]); 1168*ab0e4800SYunlong Song continue; 1169*ab0e4800SYunlong Song } 1170*ab0e4800SYunlong Song printf(" %-50s [%s]\n", evt_list[evt_i++], 1171*ab0e4800SYunlong Song event_type_descriptors[PERF_TYPE_TRACEPOINT]); 1172*ab0e4800SYunlong Song } 1173*ab0e4800SYunlong Song if (evt_num) 1174*ab0e4800SYunlong Song printf("\n"); 1175*ab0e4800SYunlong Song 1176*ab0e4800SYunlong Song out_free: 1177*ab0e4800SYunlong Song evt_num = evt_i; 1178*ab0e4800SYunlong Song for (evt_i = 0; evt_i < evt_num; evt_i++) 1179*ab0e4800SYunlong Song zfree(&evt_list[evt_i]); 1180*ab0e4800SYunlong Song zfree(&evt_list); 1181*ab0e4800SYunlong Song return; 1182*ab0e4800SYunlong Song 1183*ab0e4800SYunlong Song out_close_evt_dir: 1184*ab0e4800SYunlong Song closedir(evt_dir); 1185*ab0e4800SYunlong Song out_close_sys_dir: 1186*ab0e4800SYunlong Song closedir(sys_dir); 1187*ab0e4800SYunlong Song 1188*ab0e4800SYunlong Song printf("FATAL: not enough memory to print %s\n", 1189*ab0e4800SYunlong Song event_type_descriptors[PERF_TYPE_TRACEPOINT]); 1190*ab0e4800SYunlong Song if (evt_list) 1191*ab0e4800SYunlong Song goto out_free; 1192f6bdafefSJason Baron } 1193f6bdafefSJason Baron 1194f6bdafefSJason Baron /* 119520c457b8SThomas Renninger * Check whether event is in <debugfs_mount_point>/tracing/events 119620c457b8SThomas Renninger */ 119720c457b8SThomas Renninger 119820c457b8SThomas Renninger int is_valid_tracepoint(const char *event_string) 119920c457b8SThomas Renninger { 120020c457b8SThomas Renninger DIR *sys_dir, *evt_dir; 120120c457b8SThomas Renninger struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 120220c457b8SThomas Renninger char evt_path[MAXPATHLEN]; 120320c457b8SThomas Renninger char dir_path[MAXPATHLEN]; 120420c457b8SThomas Renninger 1205ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 120620c457b8SThomas Renninger if (!sys_dir) 120720c457b8SThomas Renninger return 0; 120820c457b8SThomas Renninger 120920c457b8SThomas Renninger for_each_subsystem(sys_dir, sys_dirent, sys_next) { 121020c457b8SThomas Renninger 1211ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 121220c457b8SThomas Renninger sys_dirent.d_name); 121320c457b8SThomas Renninger evt_dir = opendir(dir_path); 121420c457b8SThomas Renninger if (!evt_dir) 121520c457b8SThomas Renninger continue; 121620c457b8SThomas Renninger 121720c457b8SThomas Renninger for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 121820c457b8SThomas Renninger snprintf(evt_path, MAXPATHLEN, "%s:%s", 121920c457b8SThomas Renninger sys_dirent.d_name, evt_dirent.d_name); 122020c457b8SThomas Renninger if (!strcmp(evt_path, event_string)) { 122120c457b8SThomas Renninger closedir(evt_dir); 122220c457b8SThomas Renninger closedir(sys_dir); 122320c457b8SThomas Renninger return 1; 122420c457b8SThomas Renninger } 122520c457b8SThomas Renninger } 122620c457b8SThomas Renninger closedir(evt_dir); 122720c457b8SThomas Renninger } 122820c457b8SThomas Renninger closedir(sys_dir); 122920c457b8SThomas Renninger return 0; 123020c457b8SThomas Renninger } 123120c457b8SThomas Renninger 1232b41f1cecSNamhyung Kim static bool is_event_supported(u8 type, unsigned config) 1233b41f1cecSNamhyung Kim { 1234b41f1cecSNamhyung Kim bool ret = true; 123588fee52eSVince Weaver int open_return; 1236b41f1cecSNamhyung Kim struct perf_evsel *evsel; 1237b41f1cecSNamhyung Kim struct perf_event_attr attr = { 1238b41f1cecSNamhyung Kim .type = type, 1239b41f1cecSNamhyung Kim .config = config, 1240b41f1cecSNamhyung Kim .disabled = 1, 1241b41f1cecSNamhyung Kim }; 1242b41f1cecSNamhyung Kim struct { 1243b41f1cecSNamhyung Kim struct thread_map map; 1244b41f1cecSNamhyung Kim int threads[1]; 1245b41f1cecSNamhyung Kim } tmap = { 1246b41f1cecSNamhyung Kim .map.nr = 1, 1247b41f1cecSNamhyung Kim .threads = { 0 }, 1248b41f1cecSNamhyung Kim }; 1249b41f1cecSNamhyung Kim 1250ef503831SArnaldo Carvalho de Melo evsel = perf_evsel__new(&attr); 1251b41f1cecSNamhyung Kim if (evsel) { 125288fee52eSVince Weaver open_return = perf_evsel__open(evsel, NULL, &tmap.map); 125388fee52eSVince Weaver ret = open_return >= 0; 125488fee52eSVince Weaver 125588fee52eSVince Weaver if (open_return == -EACCES) { 125688fee52eSVince Weaver /* 125788fee52eSVince Weaver * This happens if the paranoid value 125888fee52eSVince Weaver * /proc/sys/kernel/perf_event_paranoid is set to 2 125988fee52eSVince Weaver * Re-run with exclude_kernel set; we don't do that 126088fee52eSVince Weaver * by default as some ARM machines do not support it. 126188fee52eSVince Weaver * 126288fee52eSVince Weaver */ 126388fee52eSVince Weaver evsel->attr.exclude_kernel = 1; 1264b41f1cecSNamhyung Kim ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; 126588fee52eSVince Weaver } 1266b41f1cecSNamhyung Kim perf_evsel__delete(evsel); 1267b41f1cecSNamhyung Kim } 1268b41f1cecSNamhyung Kim 1269b41f1cecSNamhyung Kim return ret; 1270b41f1cecSNamhyung Kim } 1271b41f1cecSNamhyung Kim 12721dc12760SJiri Olsa static void __print_events_type(u8 type, struct event_symbol *syms, 12731dc12760SJiri Olsa unsigned max) 1274668b8788SArnaldo Carvalho de Melo { 1275668b8788SArnaldo Carvalho de Melo char name[64]; 1276*ab0e4800SYunlong Song unsigned int i, evt_i = 0, evt_num = 0; 1277*ab0e4800SYunlong Song char **evt_list = NULL; 1278*ab0e4800SYunlong Song bool evt_num_known = false; 1279*ab0e4800SYunlong Song 1280*ab0e4800SYunlong Song restart: 1281*ab0e4800SYunlong Song if (evt_num_known) { 1282*ab0e4800SYunlong Song evt_list = zalloc(sizeof(char *) * evt_num); 1283*ab0e4800SYunlong Song if (!evt_list) 1284*ab0e4800SYunlong Song goto out_enomem; 1285*ab0e4800SYunlong Song syms -= max; 1286*ab0e4800SYunlong Song } 1287668b8788SArnaldo Carvalho de Melo 12881dc12760SJiri Olsa for (i = 0; i < max ; i++, syms++) { 1289b41f1cecSNamhyung Kim if (!is_event_supported(type, i)) 1290b41f1cecSNamhyung Kim continue; 1291b41f1cecSNamhyung Kim 1292*ab0e4800SYunlong Song if (!evt_num_known) { 1293*ab0e4800SYunlong Song evt_num++; 1294*ab0e4800SYunlong Song continue; 1295*ab0e4800SYunlong Song } 1296*ab0e4800SYunlong Song 1297668b8788SArnaldo Carvalho de Melo if (strlen(syms->alias)) 1298668b8788SArnaldo Carvalho de Melo snprintf(name, sizeof(name), "%s OR %s", 1299668b8788SArnaldo Carvalho de Melo syms->symbol, syms->alias); 1300668b8788SArnaldo Carvalho de Melo else 1301668b8788SArnaldo Carvalho de Melo snprintf(name, sizeof(name), "%s", syms->symbol); 1302668b8788SArnaldo Carvalho de Melo 1303*ab0e4800SYunlong Song evt_list[evt_i] = strdup(name); 1304*ab0e4800SYunlong Song if (evt_list[evt_i] == NULL) 1305*ab0e4800SYunlong Song goto out_enomem; 1306*ab0e4800SYunlong Song evt_i++; 1307668b8788SArnaldo Carvalho de Melo } 1308*ab0e4800SYunlong Song 1309*ab0e4800SYunlong Song if (!evt_num_known) { 1310*ab0e4800SYunlong Song evt_num_known = true; 1311*ab0e4800SYunlong Song goto restart; 1312*ab0e4800SYunlong Song } 1313*ab0e4800SYunlong Song qsort(evt_list, evt_num, sizeof(char *), cmp_string); 1314*ab0e4800SYunlong Song evt_i = 0; 1315*ab0e4800SYunlong Song while (evt_i < evt_num) 1316*ab0e4800SYunlong Song printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); 1317*ab0e4800SYunlong Song if (evt_num) 1318*ab0e4800SYunlong Song printf("\n"); 1319*ab0e4800SYunlong Song 1320*ab0e4800SYunlong Song out_free: 1321*ab0e4800SYunlong Song evt_num = evt_i; 1322*ab0e4800SYunlong Song for (evt_i = 0; evt_i < evt_num; evt_i++) 1323*ab0e4800SYunlong Song zfree(&evt_list[evt_i]); 1324*ab0e4800SYunlong Song zfree(&evt_list); 1325*ab0e4800SYunlong Song return; 1326*ab0e4800SYunlong Song 1327*ab0e4800SYunlong Song out_enomem: 1328*ab0e4800SYunlong Song printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); 1329*ab0e4800SYunlong Song if (evt_list) 1330*ab0e4800SYunlong Song goto out_free; 1331668b8788SArnaldo Carvalho de Melo } 1332668b8788SArnaldo Carvalho de Melo 13331dc12760SJiri Olsa void print_events_type(u8 type) 13341dc12760SJiri Olsa { 13351dc12760SJiri Olsa if (type == PERF_TYPE_SOFTWARE) 13361dc12760SJiri Olsa __print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX); 13371dc12760SJiri Olsa else 13381dc12760SJiri Olsa __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX); 13391dc12760SJiri Olsa } 13401dc12760SJiri Olsa 1341a3277d2dSFrederic Weisbecker int print_hwcache_events(const char *event_glob, bool name_only) 1342668b8788SArnaldo Carvalho de Melo { 1343*ab0e4800SYunlong Song unsigned int type, op, i, evt_i = 0, evt_num = 0; 13440b668bc9SArnaldo Carvalho de Melo char name[64]; 1345*ab0e4800SYunlong Song char **evt_list = NULL; 1346*ab0e4800SYunlong Song bool evt_num_known = false; 1347*ab0e4800SYunlong Song 1348*ab0e4800SYunlong Song restart: 1349*ab0e4800SYunlong Song if (evt_num_known) { 1350*ab0e4800SYunlong Song evt_list = zalloc(sizeof(char *) * evt_num); 1351*ab0e4800SYunlong Song if (!evt_list) 1352*ab0e4800SYunlong Song goto out_enomem; 1353*ab0e4800SYunlong Song } 1354668b8788SArnaldo Carvalho de Melo 1355668b8788SArnaldo Carvalho de Melo for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 1356668b8788SArnaldo Carvalho de Melo for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 1357668b8788SArnaldo Carvalho de Melo /* skip invalid cache type */ 13580b668bc9SArnaldo Carvalho de Melo if (!perf_evsel__is_cache_op_valid(type, op)) 1359668b8788SArnaldo Carvalho de Melo continue; 1360668b8788SArnaldo Carvalho de Melo 1361668b8788SArnaldo Carvalho de Melo for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 13620b668bc9SArnaldo Carvalho de Melo __perf_evsel__hw_cache_type_op_res_name(type, op, i, 13630b668bc9SArnaldo Carvalho de Melo name, sizeof(name)); 1364947b4ad1SIngo Molnar if (event_glob != NULL && !strglobmatch(name, event_glob)) 1365668b8788SArnaldo Carvalho de Melo continue; 1366668b8788SArnaldo Carvalho de Melo 1367b41f1cecSNamhyung Kim if (!is_event_supported(PERF_TYPE_HW_CACHE, 1368b41f1cecSNamhyung Kim type | (op << 8) | (i << 16))) 1369b41f1cecSNamhyung Kim continue; 1370b41f1cecSNamhyung Kim 1371*ab0e4800SYunlong Song if (!evt_num_known) { 1372*ab0e4800SYunlong Song evt_num++; 1373*ab0e4800SYunlong Song continue; 1374*ab0e4800SYunlong Song } 1375*ab0e4800SYunlong Song 1376*ab0e4800SYunlong Song evt_list[evt_i] = strdup(name); 1377*ab0e4800SYunlong Song if (evt_list[evt_i] == NULL) 1378*ab0e4800SYunlong Song goto out_enomem; 1379*ab0e4800SYunlong Song evt_i++; 1380668b8788SArnaldo Carvalho de Melo } 1381668b8788SArnaldo Carvalho de Melo } 1382668b8788SArnaldo Carvalho de Melo } 1383668b8788SArnaldo Carvalho de Melo 1384*ab0e4800SYunlong Song if (!evt_num_known) { 1385*ab0e4800SYunlong Song evt_num_known = true; 1386*ab0e4800SYunlong Song goto restart; 1387*ab0e4800SYunlong Song } 1388*ab0e4800SYunlong Song qsort(evt_list, evt_num, sizeof(char *), cmp_string); 1389*ab0e4800SYunlong Song evt_i = 0; 1390*ab0e4800SYunlong Song while (evt_i < evt_num) { 1391*ab0e4800SYunlong Song if (name_only) { 1392*ab0e4800SYunlong Song printf("%s ", evt_list[evt_i++]); 1393*ab0e4800SYunlong Song continue; 1394*ab0e4800SYunlong Song } 1395*ab0e4800SYunlong Song printf(" %-50s [%s]\n", evt_list[evt_i++], 1396*ab0e4800SYunlong Song event_type_descriptors[PERF_TYPE_HW_CACHE]); 1397*ab0e4800SYunlong Song } 1398*ab0e4800SYunlong Song if (evt_num) 1399dc098b35SAndi Kleen printf("\n"); 1400*ab0e4800SYunlong Song 1401*ab0e4800SYunlong Song out_free: 1402*ab0e4800SYunlong Song evt_num = evt_i; 1403*ab0e4800SYunlong Song for (evt_i = 0; evt_i < evt_num; evt_i++) 1404*ab0e4800SYunlong Song zfree(&evt_list[evt_i]); 1405*ab0e4800SYunlong Song zfree(&evt_list); 1406*ab0e4800SYunlong Song return evt_num; 1407*ab0e4800SYunlong Song 1408*ab0e4800SYunlong Song out_enomem: 1409*ab0e4800SYunlong Song printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]); 1410*ab0e4800SYunlong Song if (evt_list) 1411*ab0e4800SYunlong Song goto out_free; 1412*ab0e4800SYunlong Song return evt_num; 1413668b8788SArnaldo Carvalho de Melo } 1414668b8788SArnaldo Carvalho de Melo 14151dc12760SJiri Olsa static void print_symbol_events(const char *event_glob, unsigned type, 1416a3277d2dSFrederic Weisbecker struct event_symbol *syms, unsigned max, 1417a3277d2dSFrederic Weisbecker bool name_only) 141886470930SIngo Molnar { 1419*ab0e4800SYunlong Song unsigned int i, evt_i = 0, evt_num = 0; 1420947b4ad1SIngo Molnar char name[MAX_NAME_LEN]; 1421*ab0e4800SYunlong Song char **evt_list = NULL; 1422*ab0e4800SYunlong Song bool evt_num_known = false; 1423*ab0e4800SYunlong Song 1424*ab0e4800SYunlong Song restart: 1425*ab0e4800SYunlong Song if (evt_num_known) { 1426*ab0e4800SYunlong Song evt_list = zalloc(sizeof(char *) * evt_num); 1427*ab0e4800SYunlong Song if (!evt_list) 1428*ab0e4800SYunlong Song goto out_enomem; 1429*ab0e4800SYunlong Song syms -= max; 1430*ab0e4800SYunlong Song } 143186470930SIngo Molnar 14321dc12760SJiri Olsa for (i = 0; i < max; i++, syms++) { 1433668b8788SArnaldo Carvalho de Melo 1434668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 1435668b8788SArnaldo Carvalho de Melo !(strglobmatch(syms->symbol, event_glob) || 1436668b8788SArnaldo Carvalho de Melo (syms->alias && strglobmatch(syms->alias, event_glob)))) 1437668b8788SArnaldo Carvalho de Melo continue; 143886470930SIngo Molnar 1439b41f1cecSNamhyung Kim if (!is_event_supported(type, i)) 1440b41f1cecSNamhyung Kim continue; 1441b41f1cecSNamhyung Kim 1442*ab0e4800SYunlong Song if (!evt_num_known) { 1443*ab0e4800SYunlong Song evt_num++; 1444a3277d2dSFrederic Weisbecker continue; 1445a3277d2dSFrederic Weisbecker } 1446a3277d2dSFrederic Weisbecker 1447*ab0e4800SYunlong Song if (!name_only && strlen(syms->alias)) 1448947b4ad1SIngo Molnar snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 144974d5b588SJaswinder Singh Rajput else 1450947b4ad1SIngo Molnar strncpy(name, syms->symbol, MAX_NAME_LEN); 145186470930SIngo Molnar 1452*ab0e4800SYunlong Song evt_list[evt_i] = strdup(name); 1453*ab0e4800SYunlong Song if (evt_list[evt_i] == NULL) 1454*ab0e4800SYunlong Song goto out_enomem; 1455*ab0e4800SYunlong Song evt_i++; 145686470930SIngo Molnar } 145786470930SIngo Molnar 1458*ab0e4800SYunlong Song if (!evt_num_known) { 1459*ab0e4800SYunlong Song evt_num_known = true; 1460*ab0e4800SYunlong Song goto restart; 1461*ab0e4800SYunlong Song } 1462*ab0e4800SYunlong Song qsort(evt_list, evt_num, sizeof(char *), cmp_string); 1463*ab0e4800SYunlong Song evt_i = 0; 1464*ab0e4800SYunlong Song while (evt_i < evt_num) { 1465*ab0e4800SYunlong Song if (name_only) { 1466*ab0e4800SYunlong Song printf("%s ", evt_list[evt_i++]); 1467*ab0e4800SYunlong Song continue; 1468*ab0e4800SYunlong Song } 1469*ab0e4800SYunlong Song printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); 1470*ab0e4800SYunlong Song } 1471*ab0e4800SYunlong Song if (evt_num) 1472689d3018SMarti Raudsepp printf("\n"); 1473*ab0e4800SYunlong Song 1474*ab0e4800SYunlong Song out_free: 1475*ab0e4800SYunlong Song evt_num = evt_i; 1476*ab0e4800SYunlong Song for (evt_i = 0; evt_i < evt_num; evt_i++) 1477*ab0e4800SYunlong Song zfree(&evt_list[evt_i]); 1478*ab0e4800SYunlong Song zfree(&evt_list); 1479*ab0e4800SYunlong Song return; 1480*ab0e4800SYunlong Song 1481*ab0e4800SYunlong Song out_enomem: 1482*ab0e4800SYunlong Song printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); 1483*ab0e4800SYunlong Song if (evt_list) 1484*ab0e4800SYunlong Song goto out_free; 1485668b8788SArnaldo Carvalho de Melo } 14861dc12760SJiri Olsa 14871dc12760SJiri Olsa /* 14881dc12760SJiri Olsa * Print the help text for the event symbols: 14891dc12760SJiri Olsa */ 1490a3277d2dSFrederic Weisbecker void print_events(const char *event_glob, bool name_only) 14911dc12760SJiri Olsa { 14921dc12760SJiri Olsa print_symbol_events(event_glob, PERF_TYPE_HARDWARE, 1493a3277d2dSFrederic Weisbecker event_symbols_hw, PERF_COUNT_HW_MAX, name_only); 14941dc12760SJiri Olsa 14951dc12760SJiri Olsa print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, 1496a3277d2dSFrederic Weisbecker event_symbols_sw, PERF_COUNT_SW_MAX, name_only); 14971dc12760SJiri Olsa 1498a3277d2dSFrederic Weisbecker print_hwcache_events(event_glob, name_only); 149973c24cb8SJaswinder Singh Rajput 1500dc098b35SAndi Kleen print_pmu_events(event_glob, name_only); 1501dc098b35SAndi Kleen 1502668b8788SArnaldo Carvalho de Melo if (event_glob != NULL) 1503668b8788SArnaldo Carvalho de Melo return; 150473c24cb8SJaswinder Singh Rajput 1505a3277d2dSFrederic Weisbecker if (!name_only) { 1506947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 15075f537a26SJiri Olsa "rNNN", 15081cf4a063SArnaldo Carvalho de Melo event_type_descriptors[PERF_TYPE_RAW]); 15095f537a26SJiri Olsa printf(" %-50s [%s]\n", 15105f537a26SJiri Olsa "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 15115f537a26SJiri Olsa event_type_descriptors[PERF_TYPE_RAW]); 1512af3df2cfSBorislav Petkov printf(" (see 'man perf-list' on how to encode it)\n"); 1513689d3018SMarti Raudsepp printf("\n"); 151486470930SIngo Molnar 1515947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 15163741eb9fSJacob Shin "mem:<addr>[/len][:access]", 151741bdcb23SLiming Wang event_type_descriptors[PERF_TYPE_BREAKPOINT]); 15181b290d67SFrederic Weisbecker printf("\n"); 1519a3277d2dSFrederic Weisbecker } 15201b290d67SFrederic Weisbecker 1521a3277d2dSFrederic Weisbecker print_tracepoint_events(NULL, NULL, name_only); 152286470930SIngo Molnar } 15238f707d84SJiri Olsa 15246cee6cd3SArnaldo Carvalho de Melo int parse_events__is_hardcoded_term(struct parse_events_term *term) 15258f707d84SJiri Olsa { 152616fa7e82SJiri Olsa return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; 15278f707d84SJiri Olsa } 15288f707d84SJiri Olsa 15296cee6cd3SArnaldo Carvalho de Melo static int new_term(struct parse_events_term **_term, int type_val, 153016fa7e82SJiri Olsa int type_term, char *config, 1531b527bab5SRobert Richter char *str, u64 num) 15328f707d84SJiri Olsa { 15336cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 15348f707d84SJiri Olsa 15358f707d84SJiri Olsa term = zalloc(sizeof(*term)); 15368f707d84SJiri Olsa if (!term) 15378f707d84SJiri Olsa return -ENOMEM; 15388f707d84SJiri Olsa 15398f707d84SJiri Olsa INIT_LIST_HEAD(&term->list); 154016fa7e82SJiri Olsa term->type_val = type_val; 154116fa7e82SJiri Olsa term->type_term = type_term; 15428f707d84SJiri Olsa term->config = config; 15438f707d84SJiri Olsa 154416fa7e82SJiri Olsa switch (type_val) { 15458f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_NUM: 15468f707d84SJiri Olsa term->val.num = num; 15478f707d84SJiri Olsa break; 15488f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_STR: 15498f707d84SJiri Olsa term->val.str = str; 15508f707d84SJiri Olsa break; 15518f707d84SJiri Olsa default: 15524be8be6bSAdrian Hunter free(term); 15538f707d84SJiri Olsa return -EINVAL; 15548f707d84SJiri Olsa } 15558f707d84SJiri Olsa 15568f707d84SJiri Olsa *_term = term; 15578f707d84SJiri Olsa return 0; 15588f707d84SJiri Olsa } 15598f707d84SJiri Olsa 15606cee6cd3SArnaldo Carvalho de Melo int parse_events_term__num(struct parse_events_term **term, 1561b527bab5SRobert Richter int type_term, char *config, u64 num) 156216fa7e82SJiri Olsa { 156316fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, 156416fa7e82SJiri Olsa config, NULL, num); 156516fa7e82SJiri Olsa } 156616fa7e82SJiri Olsa 15676cee6cd3SArnaldo Carvalho de Melo int parse_events_term__str(struct parse_events_term **term, 156816fa7e82SJiri Olsa int type_term, char *config, char *str) 156916fa7e82SJiri Olsa { 157016fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, 157116fa7e82SJiri Olsa config, str, 0); 157216fa7e82SJiri Olsa } 157316fa7e82SJiri Olsa 15746cee6cd3SArnaldo Carvalho de Melo int parse_events_term__sym_hw(struct parse_events_term **term, 15751d33d6dcSJiri Olsa char *config, unsigned idx) 15761d33d6dcSJiri Olsa { 15771d33d6dcSJiri Olsa struct event_symbol *sym; 15781d33d6dcSJiri Olsa 15791d33d6dcSJiri Olsa BUG_ON(idx >= PERF_COUNT_HW_MAX); 15801d33d6dcSJiri Olsa sym = &event_symbols_hw[idx]; 15811d33d6dcSJiri Olsa 15821d33d6dcSJiri Olsa if (config) 15831d33d6dcSJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 15841d33d6dcSJiri Olsa PARSE_EVENTS__TERM_TYPE_USER, config, 15851d33d6dcSJiri Olsa (char *) sym->symbol, 0); 15861d33d6dcSJiri Olsa else 15871d33d6dcSJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 15881d33d6dcSJiri Olsa PARSE_EVENTS__TERM_TYPE_USER, 15891d33d6dcSJiri Olsa (char *) "event", (char *) sym->symbol, 0); 15901d33d6dcSJiri Olsa } 15911d33d6dcSJiri Olsa 15926cee6cd3SArnaldo Carvalho de Melo int parse_events_term__clone(struct parse_events_term **new, 15936cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term) 1594a6146d50SZheng Yan { 1595a6146d50SZheng Yan return new_term(new, term->type_val, term->type_term, term->config, 1596a6146d50SZheng Yan term->val.str, term->val.num); 1597a6146d50SZheng Yan } 1598a6146d50SZheng Yan 15998f707d84SJiri Olsa void parse_events__free_terms(struct list_head *terms) 16008f707d84SJiri Olsa { 16016cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term, *h; 16028f707d84SJiri Olsa 16038f707d84SJiri Olsa list_for_each_entry_safe(term, h, terms, list) 16048f707d84SJiri Olsa free(term); 16058f707d84SJiri Olsa } 1606