1d2709c7cSDavid Howells #include <linux/hw_breakpoint.h> 28dd2a131SJiri Olsa #include <linux/err.h> 386470930SIngo Molnar #include "util.h" 46b58e7f1SUlrich Drepper #include "../perf.h" 5361c99a6SArnaldo Carvalho de Melo #include "evlist.h" 669aad6f1SArnaldo Carvalho de Melo #include "evsel.h" 7*4b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h> 886470930SIngo Molnar #include "parse-events.h" 9*4b6ab94eSJosh Poimboeuf #include <subcmd/exec-cmd.h> 1042f60c2dSKan Liang #include "string.h" 115aab621bSArnaldo Carvalho de Melo #include "symbol.h" 125beeded1SJason Baron #include "cache.h" 138755a8f2SArjan van de Ven #include "header.h" 1484c86ca1SWang Nan #include "bpf-loader.h" 156e81c74cSMasami Hiramatsu #include "debug.h" 16592d5a6bSJiri Olsa #include <api/fs/tracing_path.h> 17ac20de6fSZheng Yan #include "parse-events-bison.h" 1890e2b22dSJiri Olsa #define YY_EXTRA_TYPE int 1989812fc8SJiri Olsa #include "parse-events-flex.h" 205f537a26SJiri Olsa #include "pmu.h" 21b41f1cecSNamhyung Kim #include "thread_map.h" 22f30a79b0SJiri Olsa #include "cpumap.h" 23b39b8393SJiri Olsa #include "asm/bug.h" 2489812fc8SJiri Olsa 2589812fc8SJiri Olsa #define MAX_NAME_LEN 100 2686470930SIngo Molnar 2782ba1f2fSJiri Olsa #ifdef PARSER_DEBUG 2882ba1f2fSJiri Olsa extern int parse_events_debug; 2982ba1f2fSJiri Olsa #endif 30ac20de6fSZheng Yan int parse_events_parse(void *data, void *scanner); 31e637d177SHe Kuang static int get_config_terms(struct list_head *head_config, 32e637d177SHe Kuang struct list_head *head_terms __maybe_unused); 33bcd3279fSFrederic Weisbecker 34dcb4e102SKan Liang static struct perf_pmu_event_symbol *perf_pmu_events_list; 35dcb4e102SKan Liang /* 36dcb4e102SKan Liang * The variable indicates the number of supported pmu event symbols. 37dcb4e102SKan Liang * 0 means not initialized and ready to init 38dcb4e102SKan Liang * -1 means failed to init, don't try anymore 39dcb4e102SKan Liang * >0 is the number of supported pmu event symbols 40dcb4e102SKan Liang */ 41dcb4e102SKan Liang static int perf_pmu_events_list_num; 42dcb4e102SKan Liang 43705750f2SYunlong Song struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = { 441dc12760SJiri Olsa [PERF_COUNT_HW_CPU_CYCLES] = { 451dc12760SJiri Olsa .symbol = "cpu-cycles", 461dc12760SJiri Olsa .alias = "cycles", 471dc12760SJiri Olsa }, 481dc12760SJiri Olsa [PERF_COUNT_HW_INSTRUCTIONS] = { 491dc12760SJiri Olsa .symbol = "instructions", 501dc12760SJiri Olsa .alias = "", 511dc12760SJiri Olsa }, 521dc12760SJiri Olsa [PERF_COUNT_HW_CACHE_REFERENCES] = { 531dc12760SJiri Olsa .symbol = "cache-references", 541dc12760SJiri Olsa .alias = "", 551dc12760SJiri Olsa }, 561dc12760SJiri Olsa [PERF_COUNT_HW_CACHE_MISSES] = { 571dc12760SJiri Olsa .symbol = "cache-misses", 581dc12760SJiri Olsa .alias = "", 591dc12760SJiri Olsa }, 601dc12760SJiri Olsa [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 611dc12760SJiri Olsa .symbol = "branch-instructions", 621dc12760SJiri Olsa .alias = "branches", 631dc12760SJiri Olsa }, 641dc12760SJiri Olsa [PERF_COUNT_HW_BRANCH_MISSES] = { 651dc12760SJiri Olsa .symbol = "branch-misses", 661dc12760SJiri Olsa .alias = "", 671dc12760SJiri Olsa }, 681dc12760SJiri Olsa [PERF_COUNT_HW_BUS_CYCLES] = { 691dc12760SJiri Olsa .symbol = "bus-cycles", 701dc12760SJiri Olsa .alias = "", 711dc12760SJiri Olsa }, 721dc12760SJiri Olsa [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = { 731dc12760SJiri Olsa .symbol = "stalled-cycles-frontend", 741dc12760SJiri Olsa .alias = "idle-cycles-frontend", 751dc12760SJiri Olsa }, 761dc12760SJiri Olsa [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = { 771dc12760SJiri Olsa .symbol = "stalled-cycles-backend", 781dc12760SJiri Olsa .alias = "idle-cycles-backend", 791dc12760SJiri Olsa }, 801dc12760SJiri Olsa [PERF_COUNT_HW_REF_CPU_CYCLES] = { 811dc12760SJiri Olsa .symbol = "ref-cycles", 821dc12760SJiri Olsa .alias = "", 831dc12760SJiri Olsa }, 841dc12760SJiri Olsa }; 8586470930SIngo Molnar 86705750f2SYunlong Song struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { 871dc12760SJiri Olsa [PERF_COUNT_SW_CPU_CLOCK] = { 881dc12760SJiri Olsa .symbol = "cpu-clock", 891dc12760SJiri Olsa .alias = "", 901dc12760SJiri Olsa }, 911dc12760SJiri Olsa [PERF_COUNT_SW_TASK_CLOCK] = { 921dc12760SJiri Olsa .symbol = "task-clock", 931dc12760SJiri Olsa .alias = "", 941dc12760SJiri Olsa }, 951dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS] = { 961dc12760SJiri Olsa .symbol = "page-faults", 971dc12760SJiri Olsa .alias = "faults", 981dc12760SJiri Olsa }, 991dc12760SJiri Olsa [PERF_COUNT_SW_CONTEXT_SWITCHES] = { 1001dc12760SJiri Olsa .symbol = "context-switches", 1011dc12760SJiri Olsa .alias = "cs", 1021dc12760SJiri Olsa }, 1031dc12760SJiri Olsa [PERF_COUNT_SW_CPU_MIGRATIONS] = { 1041dc12760SJiri Olsa .symbol = "cpu-migrations", 1051dc12760SJiri Olsa .alias = "migrations", 1061dc12760SJiri Olsa }, 1071dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS_MIN] = { 1081dc12760SJiri Olsa .symbol = "minor-faults", 1091dc12760SJiri Olsa .alias = "", 1101dc12760SJiri Olsa }, 1111dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS_MAJ] = { 1121dc12760SJiri Olsa .symbol = "major-faults", 1131dc12760SJiri Olsa .alias = "", 1141dc12760SJiri Olsa }, 1151dc12760SJiri Olsa [PERF_COUNT_SW_ALIGNMENT_FAULTS] = { 1161dc12760SJiri Olsa .symbol = "alignment-faults", 1171dc12760SJiri Olsa .alias = "", 1181dc12760SJiri Olsa }, 1191dc12760SJiri Olsa [PERF_COUNT_SW_EMULATION_FAULTS] = { 1201dc12760SJiri Olsa .symbol = "emulation-faults", 1211dc12760SJiri Olsa .alias = "", 1221dc12760SJiri Olsa }, 123d22d1a2aSAdrian Hunter [PERF_COUNT_SW_DUMMY] = { 124d22d1a2aSAdrian Hunter .symbol = "dummy", 125d22d1a2aSAdrian Hunter .alias = "", 126d22d1a2aSAdrian Hunter }, 127bae9cc41SArnaldo Carvalho de Melo [PERF_COUNT_SW_BPF_OUTPUT] = { 128bae9cc41SArnaldo Carvalho de Melo .symbol = "bpf-output", 129bae9cc41SArnaldo Carvalho de Melo .alias = "", 130bae9cc41SArnaldo Carvalho de Melo }, 13186470930SIngo Molnar }; 13286470930SIngo Molnar 133cdd6c482SIngo Molnar #define __PERF_EVENT_FIELD(config, name) \ 134cdd6c482SIngo Molnar ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 13586470930SIngo Molnar 136cdd6c482SIngo Molnar #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 137cdd6c482SIngo Molnar #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 138cdd6c482SIngo Molnar #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 139cdd6c482SIngo Molnar #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 14086470930SIngo Molnar 1416b58e7f1SUlrich Drepper #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 142f6bdafefSJason Baron while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 1436b58e7f1SUlrich Drepper if (sys_dirent.d_type == DT_DIR && \ 144f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".")) && \ 145f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".."))) 146f6bdafefSJason Baron 147ae07b63fSPeter Zijlstra static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 148ae07b63fSPeter Zijlstra { 149ae07b63fSPeter Zijlstra char evt_path[MAXPATHLEN]; 150ae07b63fSPeter Zijlstra int fd; 151ae07b63fSPeter Zijlstra 152ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path, 153ae07b63fSPeter Zijlstra sys_dir->d_name, evt_dir->d_name); 154ae07b63fSPeter Zijlstra fd = open(evt_path, O_RDONLY); 155ae07b63fSPeter Zijlstra if (fd < 0) 156ae07b63fSPeter Zijlstra return -EINVAL; 157ae07b63fSPeter Zijlstra close(fd); 158ae07b63fSPeter Zijlstra 159ae07b63fSPeter Zijlstra return 0; 160ae07b63fSPeter Zijlstra } 161ae07b63fSPeter Zijlstra 1626b58e7f1SUlrich Drepper #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ 163f6bdafefSJason Baron while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 1646b58e7f1SUlrich Drepper if (evt_dirent.d_type == DT_DIR && \ 165f6bdafefSJason Baron (strcmp(evt_dirent.d_name, ".")) && \ 166ae07b63fSPeter Zijlstra (strcmp(evt_dirent.d_name, "..")) && \ 167ae07b63fSPeter Zijlstra (!tp_event_has_id(&sys_dirent, &evt_dirent))) 168f6bdafefSJason Baron 169270bbbe8SLi Zefan #define MAX_EVENT_LENGTH 512 170f6bdafefSJason Baron 171f6bdafefSJason Baron 1721ef2ed10SFrederic Weisbecker struct tracepoint_path *tracepoint_id_to_path(u64 config) 173f6bdafefSJason Baron { 1741ef2ed10SFrederic Weisbecker struct tracepoint_path *path = NULL; 175f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 176f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1778aa8a7c8SStephane Eranian char id_buf[24]; 178725b1368SEric Dumazet int fd; 179f6bdafefSJason Baron u64 id; 180f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 181725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 182f6bdafefSJason Baron 183ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 184f6bdafefSJason Baron if (!sys_dir) 185725b1368SEric Dumazet return NULL; 186f6bdafefSJason Baron 1876b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 188725b1368SEric Dumazet 189ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 190725b1368SEric Dumazet sys_dirent.d_name); 191725b1368SEric Dumazet evt_dir = opendir(dir_path); 192725b1368SEric Dumazet if (!evt_dir) 1936b58e7f1SUlrich Drepper continue; 194725b1368SEric Dumazet 1956b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 196725b1368SEric Dumazet 197725b1368SEric Dumazet snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 198f6bdafefSJason Baron evt_dirent.d_name); 199725b1368SEric Dumazet fd = open(evt_path, O_RDONLY); 200f6bdafefSJason Baron if (fd < 0) 201f6bdafefSJason Baron continue; 202f6bdafefSJason Baron if (read(fd, id_buf, sizeof(id_buf)) < 0) { 203f6bdafefSJason Baron close(fd); 204f6bdafefSJason Baron continue; 205f6bdafefSJason Baron } 206f6bdafefSJason Baron close(fd); 207f6bdafefSJason Baron id = atoll(id_buf); 208f6bdafefSJason Baron if (id == config) { 209f6bdafefSJason Baron closedir(evt_dir); 210f6bdafefSJason Baron closedir(sys_dir); 21159b4caebSJulia Lawall path = zalloc(sizeof(*path)); 2121ef2ed10SFrederic Weisbecker path->system = malloc(MAX_EVENT_LENGTH); 2131ef2ed10SFrederic Weisbecker if (!path->system) { 2141ef2ed10SFrederic Weisbecker free(path); 2151ef2ed10SFrederic Weisbecker return NULL; 2161ef2ed10SFrederic Weisbecker } 2171ef2ed10SFrederic Weisbecker path->name = malloc(MAX_EVENT_LENGTH); 2181ef2ed10SFrederic Weisbecker if (!path->name) { 21974cf249dSArnaldo Carvalho de Melo zfree(&path->system); 2201ef2ed10SFrederic Weisbecker free(path); 2211ef2ed10SFrederic Weisbecker return NULL; 2221ef2ed10SFrederic Weisbecker } 2231ef2ed10SFrederic Weisbecker strncpy(path->system, sys_dirent.d_name, 2241ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2251ef2ed10SFrederic Weisbecker strncpy(path->name, evt_dirent.d_name, 2261ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2271ef2ed10SFrederic Weisbecker return path; 228f6bdafefSJason Baron } 229f6bdafefSJason Baron } 230f6bdafefSJason Baron closedir(evt_dir); 231f6bdafefSJason Baron } 232f6bdafefSJason Baron 233f6bdafefSJason Baron closedir(sys_dir); 2341ef2ed10SFrederic Weisbecker return NULL; 2351ef2ed10SFrederic Weisbecker } 2361ef2ed10SFrederic Weisbecker 237e7c93f09SNamhyung Kim struct tracepoint_path *tracepoint_name_to_path(const char *name) 238e7c93f09SNamhyung Kim { 239e7c93f09SNamhyung Kim struct tracepoint_path *path = zalloc(sizeof(*path)); 240e7c93f09SNamhyung Kim char *str = strchr(name, ':'); 241e7c93f09SNamhyung Kim 242e7c93f09SNamhyung Kim if (path == NULL || str == NULL) { 243e7c93f09SNamhyung Kim free(path); 244e7c93f09SNamhyung Kim return NULL; 245e7c93f09SNamhyung Kim } 246e7c93f09SNamhyung Kim 247e7c93f09SNamhyung Kim path->system = strndup(name, str - name); 248e7c93f09SNamhyung Kim path->name = strdup(str+1); 249e7c93f09SNamhyung Kim 250e7c93f09SNamhyung Kim if (path->system == NULL || path->name == NULL) { 25174cf249dSArnaldo Carvalho de Melo zfree(&path->system); 25274cf249dSArnaldo Carvalho de Melo zfree(&path->name); 253e7c93f09SNamhyung Kim free(path); 254e7c93f09SNamhyung Kim path = NULL; 255e7c93f09SNamhyung Kim } 256e7c93f09SNamhyung Kim 257e7c93f09SNamhyung Kim return path; 258e7c93f09SNamhyung Kim } 259e7c93f09SNamhyung Kim 2601424dc96SDavid Ahern const char *event_type(int type) 2611424dc96SDavid Ahern { 2621424dc96SDavid Ahern switch (type) { 2631424dc96SDavid Ahern case PERF_TYPE_HARDWARE: 2641424dc96SDavid Ahern return "hardware"; 2651424dc96SDavid Ahern 2661424dc96SDavid Ahern case PERF_TYPE_SOFTWARE: 2671424dc96SDavid Ahern return "software"; 2681424dc96SDavid Ahern 2691424dc96SDavid Ahern case PERF_TYPE_TRACEPOINT: 2701424dc96SDavid Ahern return "tracepoint"; 2711424dc96SDavid Ahern 2721424dc96SDavid Ahern case PERF_TYPE_HW_CACHE: 2731424dc96SDavid Ahern return "hardware-cache"; 2741424dc96SDavid Ahern 2751424dc96SDavid Ahern default: 2761424dc96SDavid Ahern break; 2771424dc96SDavid Ahern } 2781424dc96SDavid Ahern 2791424dc96SDavid Ahern return "unknown"; 2801424dc96SDavid Ahern } 2811424dc96SDavid Ahern 2827ae92e74SYan, Zheng 2837ae92e74SYan, Zheng 284410136f5SStephane Eranian static struct perf_evsel * 285410136f5SStephane Eranian __add_event(struct list_head *list, int *idx, 2867ae92e74SYan, Zheng struct perf_event_attr *attr, 287930a2e29SJiri Olsa char *name, struct cpu_map *cpus, 288930a2e29SJiri Olsa struct list_head *config_terms) 28989812fc8SJiri Olsa { 29089812fc8SJiri Olsa struct perf_evsel *evsel; 29189812fc8SJiri Olsa 29289812fc8SJiri Olsa event_attr_init(attr); 29389812fc8SJiri Olsa 294ef503831SArnaldo Carvalho de Melo evsel = perf_evsel__new_idx(attr, (*idx)++); 295c5cd8ac0SDavid Ahern if (!evsel) 296410136f5SStephane Eranian return NULL; 29789812fc8SJiri Olsa 298f30a79b0SJiri Olsa evsel->cpus = cpu_map__get(cpus); 299fce4d296SAdrian Hunter evsel->own_cpus = cpu_map__get(cpus); 300f30a79b0SJiri Olsa 3019db1763cSArnaldo Carvalho de Melo if (name) 30289812fc8SJiri Olsa evsel->name = strdup(name); 303930a2e29SJiri Olsa 304930a2e29SJiri Olsa if (config_terms) 305930a2e29SJiri Olsa list_splice(config_terms, &evsel->config_terms); 306930a2e29SJiri Olsa 307b847cbdcSJiri Olsa list_add_tail(&evsel->node, list); 308410136f5SStephane Eranian return evsel; 30989812fc8SJiri Olsa } 31089812fc8SJiri Olsa 311c5cd8ac0SDavid Ahern static int add_event(struct list_head *list, int *idx, 312930a2e29SJiri Olsa struct perf_event_attr *attr, char *name, 313930a2e29SJiri Olsa struct list_head *config_terms) 3147ae92e74SYan, Zheng { 315930a2e29SJiri Olsa return __add_event(list, idx, attr, name, NULL, config_terms) ? 0 : -ENOMEM; 3167ae92e74SYan, Zheng } 3177ae92e74SYan, Zheng 3180b668bc9SArnaldo Carvalho de Melo static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) 31986470930SIngo Molnar { 32086470930SIngo Molnar int i, j; 32161c45981SPaul Mackerras int n, longest = -1; 32286470930SIngo Molnar 32386470930SIngo Molnar for (i = 0; i < size; i++) { 3240b668bc9SArnaldo Carvalho de Melo for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) { 32561c45981SPaul Mackerras n = strlen(names[i][j]); 32689812fc8SJiri Olsa if (n > longest && !strncasecmp(str, names[i][j], n)) 32761c45981SPaul Mackerras longest = n; 32861c45981SPaul Mackerras } 32989812fc8SJiri Olsa if (longest > 0) 33086470930SIngo Molnar return i; 33186470930SIngo Molnar } 33286470930SIngo Molnar 3338953645fSIngo Molnar return -1; 33486470930SIngo Molnar } 33586470930SIngo Molnar 336c5cd8ac0SDavid Ahern int parse_events_add_cache(struct list_head *list, int *idx, 33789812fc8SJiri Olsa char *type, char *op_result1, char *op_result2) 33886470930SIngo Molnar { 33989812fc8SJiri Olsa struct perf_event_attr attr; 34089812fc8SJiri Olsa char name[MAX_NAME_LEN]; 34161c45981SPaul Mackerras int cache_type = -1, cache_op = -1, cache_result = -1; 34289812fc8SJiri Olsa char *op_result[2] = { op_result1, op_result2 }; 34389812fc8SJiri Olsa int i, n; 34486470930SIngo Molnar 34586470930SIngo Molnar /* 34686470930SIngo Molnar * No fallback - if we cannot get a clear cache type 34786470930SIngo Molnar * then bail out: 34886470930SIngo Molnar */ 3490b668bc9SArnaldo Carvalho de Melo cache_type = parse_aliases(type, perf_evsel__hw_cache, 35089812fc8SJiri Olsa PERF_COUNT_HW_CACHE_MAX); 35186470930SIngo Molnar if (cache_type == -1) 35289812fc8SJiri Olsa return -EINVAL; 35386470930SIngo Molnar 35489812fc8SJiri Olsa n = snprintf(name, MAX_NAME_LEN, "%s", type); 35589812fc8SJiri Olsa 35689812fc8SJiri Olsa for (i = 0; (i < 2) && (op_result[i]); i++) { 35789812fc8SJiri Olsa char *str = op_result[i]; 35889812fc8SJiri Olsa 359275ef387SJiri Olsa n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str); 36061c45981SPaul Mackerras 36161c45981SPaul Mackerras if (cache_op == -1) { 3620b668bc9SArnaldo Carvalho de Melo cache_op = parse_aliases(str, perf_evsel__hw_cache_op, 36361c45981SPaul Mackerras PERF_COUNT_HW_CACHE_OP_MAX); 36461c45981SPaul Mackerras if (cache_op >= 0) { 3650b668bc9SArnaldo Carvalho de Melo if (!perf_evsel__is_cache_op_valid(cache_type, cache_op)) 36689812fc8SJiri Olsa return -EINVAL; 36761c45981SPaul Mackerras continue; 36861c45981SPaul Mackerras } 36961c45981SPaul Mackerras } 37061c45981SPaul Mackerras 37161c45981SPaul Mackerras if (cache_result == -1) { 3720b668bc9SArnaldo Carvalho de Melo cache_result = parse_aliases(str, perf_evsel__hw_cache_result, 37361c45981SPaul Mackerras PERF_COUNT_HW_CACHE_RESULT_MAX); 37461c45981SPaul Mackerras if (cache_result >= 0) 37561c45981SPaul Mackerras continue; 37661c45981SPaul Mackerras } 37761c45981SPaul Mackerras } 37861c45981SPaul Mackerras 37986470930SIngo Molnar /* 38086470930SIngo Molnar * Fall back to reads: 38186470930SIngo Molnar */ 3828953645fSIngo Molnar if (cache_op == -1) 3838953645fSIngo Molnar cache_op = PERF_COUNT_HW_CACHE_OP_READ; 38486470930SIngo Molnar 38586470930SIngo Molnar /* 38686470930SIngo Molnar * Fall back to accesses: 38786470930SIngo Molnar */ 38886470930SIngo Molnar if (cache_result == -1) 38986470930SIngo Molnar cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 39086470930SIngo Molnar 39189812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 39289812fc8SJiri Olsa attr.config = cache_type | (cache_op << 8) | (cache_result << 16); 39389812fc8SJiri Olsa attr.type = PERF_TYPE_HW_CACHE; 394930a2e29SJiri Olsa return add_event(list, idx, &attr, name, NULL); 39586470930SIngo Molnar } 39686470930SIngo Molnar 397272ed29aSJiri Olsa static void tracepoint_error(struct parse_events_error *e, int err, 39819658171SJiri Olsa char *sys, char *name) 39919658171SJiri Olsa { 40019658171SJiri Olsa char help[BUFSIZ]; 40119658171SJiri Olsa 40219658171SJiri Olsa /* 40319658171SJiri Olsa * We get error directly from syscall errno ( > 0), 40419658171SJiri Olsa * or from encoded pointer's error ( < 0). 40519658171SJiri Olsa */ 40619658171SJiri Olsa err = abs(err); 40719658171SJiri Olsa 40819658171SJiri Olsa switch (err) { 40919658171SJiri Olsa case EACCES: 410272ed29aSJiri Olsa e->str = strdup("can't access trace events"); 41119658171SJiri Olsa break; 41219658171SJiri Olsa case ENOENT: 413272ed29aSJiri Olsa e->str = strdup("unknown tracepoint"); 41419658171SJiri Olsa break; 41519658171SJiri Olsa default: 416272ed29aSJiri Olsa e->str = strdup("failed to add tracepoint"); 41719658171SJiri Olsa break; 41819658171SJiri Olsa } 41919658171SJiri Olsa 42019658171SJiri Olsa tracing_path__strerror_open_tp(err, help, sizeof(help), sys, name); 421272ed29aSJiri Olsa e->help = strdup(help); 42219658171SJiri Olsa } 42319658171SJiri Olsa 424c5cd8ac0SDavid Ahern static int add_tracepoint(struct list_head *list, int *idx, 425e2f9f8eaSJiri Olsa char *sys_name, char *evt_name, 426272ed29aSJiri Olsa struct parse_events_error *err, 427e637d177SHe Kuang struct list_head *head_config) 428bcd3279fSFrederic Weisbecker { 42982fe1c29SArnaldo Carvalho de Melo struct perf_evsel *evsel; 430bcd3279fSFrederic Weisbecker 431ef503831SArnaldo Carvalho de Melo evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++); 43219658171SJiri Olsa if (IS_ERR(evsel)) { 433272ed29aSJiri Olsa tracepoint_error(err, PTR_ERR(evsel), sys_name, evt_name); 4348dd2a131SJiri Olsa return PTR_ERR(evsel); 43519658171SJiri Olsa } 436bcd3279fSFrederic Weisbecker 437e637d177SHe Kuang if (head_config) { 438e637d177SHe Kuang LIST_HEAD(config_terms); 439e637d177SHe Kuang 440e637d177SHe Kuang if (get_config_terms(head_config, &config_terms)) 441e637d177SHe Kuang return -ENOMEM; 442e637d177SHe Kuang list_splice(&config_terms, &evsel->config_terms); 443e637d177SHe Kuang } 444e637d177SHe Kuang 44582fe1c29SArnaldo Carvalho de Melo list_add_tail(&evsel->node, list); 44682fe1c29SArnaldo Carvalho de Melo return 0; 447bcd3279fSFrederic Weisbecker } 448bcd3279fSFrederic Weisbecker 449c5cd8ac0SDavid Ahern static int add_tracepoint_multi_event(struct list_head *list, int *idx, 450e2f9f8eaSJiri Olsa char *sys_name, char *evt_name, 451272ed29aSJiri Olsa struct parse_events_error *err, 452e637d177SHe Kuang struct list_head *head_config) 453bcd3279fSFrederic Weisbecker { 454bcd3279fSFrederic Weisbecker char evt_path[MAXPATHLEN]; 455bcd3279fSFrederic Weisbecker struct dirent *evt_ent; 456bcd3279fSFrederic Weisbecker DIR *evt_dir; 45727bf90bfSJiri Olsa int ret = 0, found = 0; 458bcd3279fSFrederic Weisbecker 459ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); 460bcd3279fSFrederic Weisbecker evt_dir = opendir(evt_path); 461bcd3279fSFrederic Weisbecker if (!evt_dir) { 462272ed29aSJiri Olsa tracepoint_error(err, errno, sys_name, evt_name); 46389812fc8SJiri Olsa return -1; 464bcd3279fSFrederic Weisbecker } 465bcd3279fSFrederic Weisbecker 46689812fc8SJiri Olsa while (!ret && (evt_ent = readdir(evt_dir))) { 467bcd3279fSFrederic Weisbecker if (!strcmp(evt_ent->d_name, ".") 468bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "..") 469bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "enable") 470bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "filter")) 471bcd3279fSFrederic Weisbecker continue; 472bcd3279fSFrederic Weisbecker 47389812fc8SJiri Olsa if (!strglobmatch(evt_ent->d_name, evt_name)) 474fb1d2edfSMasami Hiramatsu continue; 475fb1d2edfSMasami Hiramatsu 47627bf90bfSJiri Olsa found++; 47727bf90bfSJiri Olsa 478e637d177SHe Kuang ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name, 479272ed29aSJiri Olsa err, head_config); 480bcd3279fSFrederic Weisbecker } 481bcd3279fSFrederic Weisbecker 48227bf90bfSJiri Olsa if (!found) { 48327bf90bfSJiri Olsa tracepoint_error(err, ENOENT, sys_name, evt_name); 48427bf90bfSJiri Olsa ret = -1; 48527bf90bfSJiri Olsa } 48627bf90bfSJiri Olsa 4870bd3f084SJiri Olsa closedir(evt_dir); 48889812fc8SJiri Olsa return ret; 489bcd3279fSFrederic Weisbecker } 490bcd3279fSFrederic Weisbecker 491c5cd8ac0SDavid Ahern static int add_tracepoint_event(struct list_head *list, int *idx, 492e2f9f8eaSJiri Olsa char *sys_name, char *evt_name, 493272ed29aSJiri Olsa struct parse_events_error *err, 494e637d177SHe Kuang struct list_head *head_config) 495f35488f9SJiri Olsa { 496f35488f9SJiri Olsa return strpbrk(evt_name, "*?") ? 497e637d177SHe Kuang add_tracepoint_multi_event(list, idx, sys_name, evt_name, 498272ed29aSJiri Olsa err, head_config) : 499e637d177SHe Kuang add_tracepoint(list, idx, sys_name, evt_name, 500272ed29aSJiri Olsa err, head_config); 501f35488f9SJiri Olsa } 502f35488f9SJiri Olsa 503c5cd8ac0SDavid Ahern static int add_tracepoint_multi_sys(struct list_head *list, int *idx, 504e2f9f8eaSJiri Olsa char *sys_name, char *evt_name, 505272ed29aSJiri Olsa struct parse_events_error *err, 506e637d177SHe Kuang struct list_head *head_config) 507f35488f9SJiri Olsa { 508f35488f9SJiri Olsa struct dirent *events_ent; 509f35488f9SJiri Olsa DIR *events_dir; 510f35488f9SJiri Olsa int ret = 0; 511f35488f9SJiri Olsa 512f35488f9SJiri Olsa events_dir = opendir(tracing_events_path); 513f35488f9SJiri Olsa if (!events_dir) { 514272ed29aSJiri Olsa tracepoint_error(err, errno, sys_name, evt_name); 515f35488f9SJiri Olsa return -1; 516f35488f9SJiri Olsa } 517f35488f9SJiri Olsa 518f35488f9SJiri Olsa while (!ret && (events_ent = readdir(events_dir))) { 519f35488f9SJiri Olsa if (!strcmp(events_ent->d_name, ".") 520f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "..") 521f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "enable") 522f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "header_event") 523f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "header_page")) 524f35488f9SJiri Olsa continue; 525f35488f9SJiri Olsa 526f35488f9SJiri Olsa if (!strglobmatch(events_ent->d_name, sys_name)) 527f35488f9SJiri Olsa continue; 528f35488f9SJiri Olsa 529f35488f9SJiri Olsa ret = add_tracepoint_event(list, idx, events_ent->d_name, 530272ed29aSJiri Olsa evt_name, err, head_config); 531f35488f9SJiri Olsa } 532f35488f9SJiri Olsa 533f35488f9SJiri Olsa closedir(events_dir); 534f35488f9SJiri Olsa return ret; 535f35488f9SJiri Olsa } 536f35488f9SJiri Olsa 5374edf30e3SWang Nan struct __add_bpf_event_param { 5384edf30e3SWang Nan struct parse_events_evlist *data; 5394edf30e3SWang Nan struct list_head *list; 5404edf30e3SWang Nan }; 5414edf30e3SWang Nan 5424edf30e3SWang Nan static int add_bpf_event(struct probe_trace_event *tev, int fd, 5434edf30e3SWang Nan void *_param) 5444edf30e3SWang Nan { 5454edf30e3SWang Nan LIST_HEAD(new_evsels); 5464edf30e3SWang Nan struct __add_bpf_event_param *param = _param; 5474edf30e3SWang Nan struct parse_events_evlist *evlist = param->data; 5484edf30e3SWang Nan struct list_head *list = param->list; 5491f45b1d4SWang Nan struct perf_evsel *pos; 5504edf30e3SWang Nan int err; 5514edf30e3SWang Nan 5524edf30e3SWang Nan pr_debug("add bpf event %s:%s and attach bpf program %d\n", 5534edf30e3SWang Nan tev->group, tev->event, fd); 5544edf30e3SWang Nan 5554edf30e3SWang Nan err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, tev->group, 5564edf30e3SWang Nan tev->event, evlist->error, NULL); 5574edf30e3SWang Nan if (err) { 5584edf30e3SWang Nan struct perf_evsel *evsel, *tmp; 5594edf30e3SWang Nan 5604edf30e3SWang Nan pr_debug("Failed to add BPF event %s:%s\n", 5614edf30e3SWang Nan tev->group, tev->event); 5624edf30e3SWang Nan list_for_each_entry_safe(evsel, tmp, &new_evsels, node) { 5634edf30e3SWang Nan list_del(&evsel->node); 5644edf30e3SWang Nan perf_evsel__delete(evsel); 5654edf30e3SWang Nan } 5664edf30e3SWang Nan return err; 5674edf30e3SWang Nan } 5684edf30e3SWang Nan pr_debug("adding %s:%s\n", tev->group, tev->event); 5694edf30e3SWang Nan 5701f45b1d4SWang Nan list_for_each_entry(pos, &new_evsels, node) { 5711f45b1d4SWang Nan pr_debug("adding %s:%s to %p\n", 5721f45b1d4SWang Nan tev->group, tev->event, pos); 5731f45b1d4SWang Nan pos->bpf_fd = fd; 5741f45b1d4SWang Nan } 5754edf30e3SWang Nan list_splice(&new_evsels, list); 5764edf30e3SWang Nan return 0; 5774edf30e3SWang Nan } 5784edf30e3SWang Nan 57984c86ca1SWang Nan int parse_events_load_bpf_obj(struct parse_events_evlist *data, 58084c86ca1SWang Nan struct list_head *list, 58184c86ca1SWang Nan struct bpf_object *obj) 58284c86ca1SWang Nan { 58384c86ca1SWang Nan int err; 58484c86ca1SWang Nan char errbuf[BUFSIZ]; 5854edf30e3SWang Nan struct __add_bpf_event_param param = {data, list}; 586aa3abf30SWang Nan static bool registered_unprobe_atexit = false; 58784c86ca1SWang Nan 58884c86ca1SWang Nan if (IS_ERR(obj) || !obj) { 58984c86ca1SWang Nan snprintf(errbuf, sizeof(errbuf), 59084c86ca1SWang Nan "Internal error: load bpf obj with NULL"); 59184c86ca1SWang Nan err = -EINVAL; 59284c86ca1SWang Nan goto errout; 59384c86ca1SWang Nan } 59484c86ca1SWang Nan 59584c86ca1SWang Nan /* 596aa3abf30SWang Nan * Register atexit handler before calling bpf__probe() so 597aa3abf30SWang Nan * bpf__probe() don't need to unprobe probe points its already 598aa3abf30SWang Nan * created when failure. 599aa3abf30SWang Nan */ 600aa3abf30SWang Nan if (!registered_unprobe_atexit) { 601aa3abf30SWang Nan atexit(bpf__clear); 602aa3abf30SWang Nan registered_unprobe_atexit = true; 603aa3abf30SWang Nan } 604aa3abf30SWang Nan 605aa3abf30SWang Nan err = bpf__probe(obj); 606aa3abf30SWang Nan if (err) { 607aa3abf30SWang Nan bpf__strerror_probe(obj, err, errbuf, sizeof(errbuf)); 608aa3abf30SWang Nan goto errout; 609aa3abf30SWang Nan } 610aa3abf30SWang Nan 6111e5e3ee8SWang Nan err = bpf__load(obj); 6121e5e3ee8SWang Nan if (err) { 6131e5e3ee8SWang Nan bpf__strerror_load(obj, err, errbuf, sizeof(errbuf)); 6141e5e3ee8SWang Nan goto errout; 6151e5e3ee8SWang Nan } 6161e5e3ee8SWang Nan 6174edf30e3SWang Nan err = bpf__foreach_tev(obj, add_bpf_event, ¶m); 6184edf30e3SWang Nan if (err) { 6194edf30e3SWang Nan snprintf(errbuf, sizeof(errbuf), 6204edf30e3SWang Nan "Attach events in BPF object failed"); 6214edf30e3SWang Nan goto errout; 6224edf30e3SWang Nan } 6234edf30e3SWang Nan 6244edf30e3SWang Nan return 0; 62584c86ca1SWang Nan errout: 62684c86ca1SWang Nan data->error->help = strdup("(add -v to see detail)"); 62784c86ca1SWang Nan data->error->str = strdup(errbuf); 62884c86ca1SWang Nan return err; 62984c86ca1SWang Nan } 63084c86ca1SWang Nan 63184c86ca1SWang Nan int parse_events_load_bpf(struct parse_events_evlist *data, 63284c86ca1SWang Nan struct list_head *list, 633d509db04SWang Nan char *bpf_file_name, 634d509db04SWang Nan bool source) 63584c86ca1SWang Nan { 63684c86ca1SWang Nan struct bpf_object *obj; 63784c86ca1SWang Nan 638d509db04SWang Nan obj = bpf__prepare_load(bpf_file_name, source); 6396371ca3bSWang Nan if (IS_ERR(obj)) { 64084c86ca1SWang Nan char errbuf[BUFSIZ]; 64184c86ca1SWang Nan int err; 64284c86ca1SWang Nan 6436371ca3bSWang Nan err = PTR_ERR(obj); 64484c86ca1SWang Nan 64584c86ca1SWang Nan if (err == -ENOTSUP) 64684c86ca1SWang Nan snprintf(errbuf, sizeof(errbuf), 64784c86ca1SWang Nan "BPF support is not compiled"); 64884c86ca1SWang Nan else 649d3e0ce39SWang Nan bpf__strerror_prepare_load(bpf_file_name, 650d3e0ce39SWang Nan source, 651d3e0ce39SWang Nan -err, errbuf, 652d3e0ce39SWang Nan sizeof(errbuf)); 65384c86ca1SWang Nan 65484c86ca1SWang Nan data->error->help = strdup("(add -v to see detail)"); 65584c86ca1SWang Nan data->error->str = strdup(errbuf); 65684c86ca1SWang Nan return err; 65784c86ca1SWang Nan } 65884c86ca1SWang Nan 65984c86ca1SWang Nan return parse_events_load_bpf_obj(data, list, obj); 66084c86ca1SWang Nan } 66184c86ca1SWang Nan 66289812fc8SJiri Olsa static int 66389812fc8SJiri Olsa parse_breakpoint_type(const char *type, struct perf_event_attr *attr) 6641b290d67SFrederic Weisbecker { 6651b290d67SFrederic Weisbecker int i; 6661b290d67SFrederic Weisbecker 6671b290d67SFrederic Weisbecker for (i = 0; i < 3; i++) { 66889812fc8SJiri Olsa if (!type || !type[i]) 6691b290d67SFrederic Weisbecker break; 6701b290d67SFrederic Weisbecker 6717582732fSJiri Olsa #define CHECK_SET_TYPE(bit) \ 6727582732fSJiri Olsa do { \ 6737582732fSJiri Olsa if (attr->bp_type & bit) \ 6747582732fSJiri Olsa return -EINVAL; \ 6757582732fSJiri Olsa else \ 6767582732fSJiri Olsa attr->bp_type |= bit; \ 6777582732fSJiri Olsa } while (0) 6787582732fSJiri Olsa 6791b290d67SFrederic Weisbecker switch (type[i]) { 6801b290d67SFrederic Weisbecker case 'r': 6817582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_R); 6821b290d67SFrederic Weisbecker break; 6831b290d67SFrederic Weisbecker case 'w': 6847582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_W); 6851b290d67SFrederic Weisbecker break; 6861b290d67SFrederic Weisbecker case 'x': 6877582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_X); 6881b290d67SFrederic Weisbecker break; 6891b290d67SFrederic Weisbecker default: 69089812fc8SJiri Olsa return -EINVAL; 6911b290d67SFrederic Weisbecker } 6921b290d67SFrederic Weisbecker } 69389812fc8SJiri Olsa 6947582732fSJiri Olsa #undef CHECK_SET_TYPE 6957582732fSJiri Olsa 6961b290d67SFrederic Weisbecker if (!attr->bp_type) /* Default */ 6971b290d67SFrederic Weisbecker attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 6981b290d67SFrederic Weisbecker 69989812fc8SJiri Olsa return 0; 7001b290d67SFrederic Weisbecker } 7011b290d67SFrederic Weisbecker 702c5cd8ac0SDavid Ahern int parse_events_add_breakpoint(struct list_head *list, int *idx, 7033741eb9fSJacob Shin void *ptr, char *type, u64 len) 7041b290d67SFrederic Weisbecker { 70589812fc8SJiri Olsa struct perf_event_attr attr; 7061b290d67SFrederic Weisbecker 70789812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 7089fafd98fSJiri Olsa attr.bp_addr = (unsigned long) ptr; 7091b290d67SFrederic Weisbecker 71089812fc8SJiri Olsa if (parse_breakpoint_type(type, &attr)) 71189812fc8SJiri Olsa return -EINVAL; 7121b290d67SFrederic Weisbecker 7133741eb9fSJacob Shin /* Provide some defaults if len is not specified */ 7143741eb9fSJacob Shin if (!len) { 71589812fc8SJiri Olsa if (attr.bp_type == HW_BREAKPOINT_X) 7163741eb9fSJacob Shin len = sizeof(long); 717aa59a485SFrederic Weisbecker else 7183741eb9fSJacob Shin len = HW_BREAKPOINT_LEN_4; 7193741eb9fSJacob Shin } 7203741eb9fSJacob Shin 7213741eb9fSJacob Shin attr.bp_len = len; 722aa59a485SFrederic Weisbecker 72389812fc8SJiri Olsa attr.type = PERF_TYPE_BREAKPOINT; 7244a841d65SJovi Zhang attr.sample_period = 1; 7251b290d67SFrederic Weisbecker 726930a2e29SJiri Olsa return add_event(list, idx, &attr, NULL, NULL); 7271b290d67SFrederic Weisbecker } 7281b290d67SFrederic Weisbecker 7293b0e371cSJiri Olsa static int check_type_val(struct parse_events_term *term, 7303b0e371cSJiri Olsa struct parse_events_error *err, 7313b0e371cSJiri Olsa int type) 7323b0e371cSJiri Olsa { 7333b0e371cSJiri Olsa if (type == term->type_val) 7343b0e371cSJiri Olsa return 0; 7353b0e371cSJiri Olsa 7363b0e371cSJiri Olsa if (err) { 7373b0e371cSJiri Olsa err->idx = term->err_val; 7383b0e371cSJiri Olsa if (type == PARSE_EVENTS__TERM_TYPE_NUM) 7393b0e371cSJiri Olsa err->str = strdup("expected numeric value"); 7403b0e371cSJiri Olsa else 7413b0e371cSJiri Olsa err->str = strdup("expected string value"); 7423b0e371cSJiri Olsa } 7433b0e371cSJiri Olsa return -EINVAL; 7443b0e371cSJiri Olsa } 7453b0e371cSJiri Olsa 7460b8891a8SHe Kuang typedef int config_term_func_t(struct perf_event_attr *attr, 7470b8891a8SHe Kuang struct parse_events_term *term, 7480b8891a8SHe Kuang struct parse_events_error *err); 7490b8891a8SHe Kuang 7500b8891a8SHe Kuang static int config_term_common(struct perf_event_attr *attr, 7513b0e371cSJiri Olsa struct parse_events_term *term, 7523b0e371cSJiri Olsa struct parse_events_error *err) 7538f707d84SJiri Olsa { 75416fa7e82SJiri Olsa #define CHECK_TYPE_VAL(type) \ 75516fa7e82SJiri Olsa do { \ 7563b0e371cSJiri Olsa if (check_type_val(term, err, PARSE_EVENTS__TERM_TYPE_ ## type)) \ 75716fa7e82SJiri Olsa return -EINVAL; \ 75816fa7e82SJiri Olsa } while (0) 75916fa7e82SJiri Olsa 76016fa7e82SJiri Olsa switch (term->type_term) { 7618f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG: 76216fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 7638f707d84SJiri Olsa attr->config = term->val.num; 7648f707d84SJiri Olsa break; 7658f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG1: 76616fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 7678f707d84SJiri Olsa attr->config1 = term->val.num; 7688f707d84SJiri Olsa break; 7698f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG2: 77016fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 7718f707d84SJiri Olsa attr->config2 = term->val.num; 7728f707d84SJiri Olsa break; 7738f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 77416fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 7758f707d84SJiri Olsa break; 77609af2a55SNamhyung Kim case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ: 77709af2a55SNamhyung Kim CHECK_TYPE_VAL(NUM); 77809af2a55SNamhyung Kim break; 7798f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: 7808f707d84SJiri Olsa /* 7818f707d84SJiri Olsa * TODO uncomment when the field is available 7828f707d84SJiri Olsa * attr->branch_sample_type = term->val.num; 7838f707d84SJiri Olsa */ 7848f707d84SJiri Olsa break; 78532067712SKan Liang case PARSE_EVENTS__TERM_TYPE_TIME: 78632067712SKan Liang CHECK_TYPE_VAL(NUM); 78732067712SKan Liang if (term->val.num > 1) { 78832067712SKan Liang err->str = strdup("expected 0 or 1"); 78932067712SKan Liang err->idx = term->err_val; 79032067712SKan Liang return -EINVAL; 79132067712SKan Liang } 79232067712SKan Liang break; 793d457c963SKan Liang case PARSE_EVENTS__TERM_TYPE_CALLGRAPH: 794d457c963SKan Liang CHECK_TYPE_VAL(STR); 795d457c963SKan Liang break; 796d457c963SKan Liang case PARSE_EVENTS__TERM_TYPE_STACKSIZE: 797d457c963SKan Liang CHECK_TYPE_VAL(NUM); 798d457c963SKan Liang break; 799374ce938SWang Nan case PARSE_EVENTS__TERM_TYPE_INHERIT: 800374ce938SWang Nan CHECK_TYPE_VAL(NUM); 801374ce938SWang Nan break; 802374ce938SWang Nan case PARSE_EVENTS__TERM_TYPE_NOINHERIT: 803374ce938SWang Nan CHECK_TYPE_VAL(NUM); 804374ce938SWang Nan break; 8056b5fc39bSJiri Olsa case PARSE_EVENTS__TERM_TYPE_NAME: 8066b5fc39bSJiri Olsa CHECK_TYPE_VAL(STR); 8076b5fc39bSJiri Olsa break; 8088f707d84SJiri Olsa default: 809ffeb883eSHe Kuang err->str = strdup("unknown term"); 810ffeb883eSHe Kuang err->idx = term->err_term; 811ffeb883eSHe Kuang err->help = parse_events_formats_error_string(NULL); 8128f707d84SJiri Olsa return -EINVAL; 8138f707d84SJiri Olsa } 81416fa7e82SJiri Olsa 8158f707d84SJiri Olsa return 0; 81616fa7e82SJiri Olsa #undef CHECK_TYPE_VAL 8178f707d84SJiri Olsa } 8188f707d84SJiri Olsa 8190b8891a8SHe Kuang static int config_term_pmu(struct perf_event_attr *attr, 8200b8891a8SHe Kuang struct parse_events_term *term, 8210b8891a8SHe Kuang struct parse_events_error *err) 8220b8891a8SHe Kuang { 8230b8891a8SHe Kuang if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER) 8240b8891a8SHe Kuang /* 8250b8891a8SHe Kuang * Always succeed for sysfs terms, as we dont know 8260b8891a8SHe Kuang * at this point what type they need to have. 8270b8891a8SHe Kuang */ 8280b8891a8SHe Kuang return 0; 8290b8891a8SHe Kuang else 8300b8891a8SHe Kuang return config_term_common(attr, term, err); 8310b8891a8SHe Kuang } 8320b8891a8SHe Kuang 833e637d177SHe Kuang static int config_term_tracepoint(struct perf_event_attr *attr, 834e637d177SHe Kuang struct parse_events_term *term, 835e637d177SHe Kuang struct parse_events_error *err) 836e637d177SHe Kuang { 837e637d177SHe Kuang switch (term->type_term) { 838e637d177SHe Kuang case PARSE_EVENTS__TERM_TYPE_CALLGRAPH: 839e637d177SHe Kuang case PARSE_EVENTS__TERM_TYPE_STACKSIZE: 840374ce938SWang Nan case PARSE_EVENTS__TERM_TYPE_INHERIT: 841374ce938SWang Nan case PARSE_EVENTS__TERM_TYPE_NOINHERIT: 842e637d177SHe Kuang return config_term_common(attr, term, err); 843e637d177SHe Kuang default: 844e637d177SHe Kuang if (err) { 845e637d177SHe Kuang err->idx = term->err_term; 846e637d177SHe Kuang err->str = strdup("unknown term"); 847e637d177SHe Kuang err->help = strdup("valid terms: call-graph,stack-size\n"); 848e637d177SHe Kuang } 849e637d177SHe Kuang return -EINVAL; 850e637d177SHe Kuang } 851e637d177SHe Kuang 852e637d177SHe Kuang return 0; 853e637d177SHe Kuang } 854e637d177SHe Kuang 8558f707d84SJiri Olsa static int config_attr(struct perf_event_attr *attr, 8563b0e371cSJiri Olsa struct list_head *head, 8570b8891a8SHe Kuang struct parse_events_error *err, 8580b8891a8SHe Kuang config_term_func_t config_term) 8598f707d84SJiri Olsa { 8606cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 8618f707d84SJiri Olsa 8628f707d84SJiri Olsa list_for_each_entry(term, head, list) 8633b0e371cSJiri Olsa if (config_term(attr, term, err)) 8648f707d84SJiri Olsa return -EINVAL; 8658f707d84SJiri Olsa 8668f707d84SJiri Olsa return 0; 8678f707d84SJiri Olsa } 8688f707d84SJiri Olsa 869930a2e29SJiri Olsa static int get_config_terms(struct list_head *head_config, 870930a2e29SJiri Olsa struct list_head *head_terms __maybe_unused) 871930a2e29SJiri Olsa { 872930a2e29SJiri Olsa #define ADD_CONFIG_TERM(__type, __name, __val) \ 873930a2e29SJiri Olsa do { \ 874930a2e29SJiri Olsa struct perf_evsel_config_term *__t; \ 875930a2e29SJiri Olsa \ 876930a2e29SJiri Olsa __t = zalloc(sizeof(*__t)); \ 877930a2e29SJiri Olsa if (!__t) \ 878930a2e29SJiri Olsa return -ENOMEM; \ 879930a2e29SJiri Olsa \ 880930a2e29SJiri Olsa INIT_LIST_HEAD(&__t->list); \ 881930a2e29SJiri Olsa __t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \ 882930a2e29SJiri Olsa __t->val.__name = __val; \ 883930a2e29SJiri Olsa list_add_tail(&__t->list, head_terms); \ 884930a2e29SJiri Olsa } while (0) 885930a2e29SJiri Olsa 886930a2e29SJiri Olsa struct parse_events_term *term; 887930a2e29SJiri Olsa 888930a2e29SJiri Olsa list_for_each_entry(term, head_config, list) { 889930a2e29SJiri Olsa switch (term->type_term) { 890ee4c7588SJiri Olsa case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 891ee4c7588SJiri Olsa ADD_CONFIG_TERM(PERIOD, period, term->val.num); 89232067712SKan Liang break; 89309af2a55SNamhyung Kim case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ: 89409af2a55SNamhyung Kim ADD_CONFIG_TERM(FREQ, freq, term->val.num); 89509af2a55SNamhyung Kim break; 89632067712SKan Liang case PARSE_EVENTS__TERM_TYPE_TIME: 89732067712SKan Liang ADD_CONFIG_TERM(TIME, time, term->val.num); 89832067712SKan Liang break; 899d457c963SKan Liang case PARSE_EVENTS__TERM_TYPE_CALLGRAPH: 900d457c963SKan Liang ADD_CONFIG_TERM(CALLGRAPH, callgraph, term->val.str); 901d457c963SKan Liang break; 902d457c963SKan Liang case PARSE_EVENTS__TERM_TYPE_STACKSIZE: 903d457c963SKan Liang ADD_CONFIG_TERM(STACK_USER, stack_user, term->val.num); 904d457c963SKan Liang break; 905374ce938SWang Nan case PARSE_EVENTS__TERM_TYPE_INHERIT: 906374ce938SWang Nan ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 1 : 0); 907374ce938SWang Nan break; 908374ce938SWang Nan case PARSE_EVENTS__TERM_TYPE_NOINHERIT: 909374ce938SWang Nan ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 0 : 1); 910374ce938SWang Nan break; 911930a2e29SJiri Olsa default: 912930a2e29SJiri Olsa break; 913930a2e29SJiri Olsa } 914930a2e29SJiri Olsa } 915930a2e29SJiri Olsa #undef ADD_EVSEL_CONFIG 916930a2e29SJiri Olsa return 0; 917930a2e29SJiri Olsa } 918930a2e29SJiri Olsa 919e637d177SHe Kuang int parse_events_add_tracepoint(struct list_head *list, int *idx, 920e637d177SHe Kuang char *sys, char *event, 921272ed29aSJiri Olsa struct parse_events_error *err, 922e637d177SHe Kuang struct list_head *head_config) 923e637d177SHe Kuang { 924e637d177SHe Kuang if (head_config) { 925e637d177SHe Kuang struct perf_event_attr attr; 926e637d177SHe Kuang 927272ed29aSJiri Olsa if (config_attr(&attr, head_config, err, 928e637d177SHe Kuang config_term_tracepoint)) 929e637d177SHe Kuang return -EINVAL; 930e637d177SHe Kuang } 931e637d177SHe Kuang 932e637d177SHe Kuang if (strpbrk(sys, "*?")) 933e637d177SHe Kuang return add_tracepoint_multi_sys(list, idx, sys, event, 934272ed29aSJiri Olsa err, head_config); 935e637d177SHe Kuang else 936e637d177SHe Kuang return add_tracepoint_event(list, idx, sys, event, 937272ed29aSJiri Olsa err, head_config); 938e637d177SHe Kuang } 939e637d177SHe Kuang 94087d650beSJiri Olsa int parse_events_add_numeric(struct parse_events_evlist *data, 94187d650beSJiri Olsa struct list_head *list, 942b527bab5SRobert Richter u32 type, u64 config, 9438f707d84SJiri Olsa struct list_head *head_config) 94474d5b588SJaswinder Singh Rajput { 94589812fc8SJiri Olsa struct perf_event_attr attr; 946930a2e29SJiri Olsa LIST_HEAD(config_terms); 94774d5b588SJaswinder Singh Rajput 94889812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 94989812fc8SJiri Olsa attr.type = type; 95089812fc8SJiri Olsa attr.config = config; 9518f707d84SJiri Olsa 952930a2e29SJiri Olsa if (head_config) { 9530b8891a8SHe Kuang if (config_attr(&attr, head_config, data->error, 9540b8891a8SHe Kuang config_term_common)) 9558f707d84SJiri Olsa return -EINVAL; 9568f707d84SJiri Olsa 957930a2e29SJiri Olsa if (get_config_terms(head_config, &config_terms)) 958930a2e29SJiri Olsa return -ENOMEM; 959930a2e29SJiri Olsa } 960930a2e29SJiri Olsa 961930a2e29SJiri Olsa return add_event(list, &data->idx, &attr, NULL, &config_terms); 962b908debdSIngo Molnar } 963b908debdSIngo Molnar 9646cee6cd3SArnaldo Carvalho de Melo static int parse_events__is_name_term(struct parse_events_term *term) 9656b5fc39bSJiri Olsa { 9666b5fc39bSJiri Olsa return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; 9676b5fc39bSJiri Olsa } 9686b5fc39bSJiri Olsa 9699db1763cSArnaldo Carvalho de Melo static char *pmu_event_name(struct list_head *head_terms) 9706b5fc39bSJiri Olsa { 9716cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 9726b5fc39bSJiri Olsa 9736b5fc39bSJiri Olsa list_for_each_entry(term, head_terms, list) 9746b5fc39bSJiri Olsa if (parse_events__is_name_term(term)) 9756b5fc39bSJiri Olsa return term->val.str; 9766b5fc39bSJiri Olsa 9779db1763cSArnaldo Carvalho de Melo return NULL; 9786b5fc39bSJiri Olsa } 9796b5fc39bSJiri Olsa 98036adec85SJiri Olsa int parse_events_add_pmu(struct parse_events_evlist *data, 98136adec85SJiri Olsa struct list_head *list, char *name, 98236adec85SJiri Olsa struct list_head *head_config) 9835f537a26SJiri Olsa { 9845f537a26SJiri Olsa struct perf_event_attr attr; 98546441bdcSMatt Fleming struct perf_pmu_info info; 9865f537a26SJiri Olsa struct perf_pmu *pmu; 987410136f5SStephane Eranian struct perf_evsel *evsel; 988930a2e29SJiri Olsa LIST_HEAD(config_terms); 9895f537a26SJiri Olsa 9905f537a26SJiri Olsa pmu = perf_pmu__find(name); 9915f537a26SJiri Olsa if (!pmu) 9925f537a26SJiri Olsa return -EINVAL; 9935f537a26SJiri Olsa 994dc0a6202SAdrian Hunter if (pmu->default_config) { 995dc0a6202SAdrian Hunter memcpy(&attr, pmu->default_config, 996dc0a6202SAdrian Hunter sizeof(struct perf_event_attr)); 997dc0a6202SAdrian Hunter } else { 9985f537a26SJiri Olsa memset(&attr, 0, sizeof(attr)); 999dc0a6202SAdrian Hunter } 10005f537a26SJiri Olsa 1001ad962273SAdrian Hunter if (!head_config) { 1002ad962273SAdrian Hunter attr.type = pmu->type; 1003930a2e29SJiri Olsa evsel = __add_event(list, &data->idx, &attr, NULL, pmu->cpus, NULL); 1004ad962273SAdrian Hunter return evsel ? 0 : -ENOMEM; 1005ad962273SAdrian Hunter } 1006ad962273SAdrian Hunter 100746441bdcSMatt Fleming if (perf_pmu__check_alias(pmu, head_config, &info)) 1008a6146d50SZheng Yan return -EINVAL; 1009a6146d50SZheng Yan 10105f537a26SJiri Olsa /* 10115f537a26SJiri Olsa * Configure hardcoded terms first, no need to check 10125f537a26SJiri Olsa * return value when called with fail == 0 ;) 10135f537a26SJiri Olsa */ 10140b8891a8SHe Kuang if (config_attr(&attr, head_config, data->error, config_term_pmu)) 1015c056ba6aSJiri Olsa return -EINVAL; 10165f537a26SJiri Olsa 1017930a2e29SJiri Olsa if (get_config_terms(head_config, &config_terms)) 1018930a2e29SJiri Olsa return -ENOMEM; 1019930a2e29SJiri Olsa 1020e64b020bSJiri Olsa if (perf_pmu__config(pmu, &attr, head_config, data->error)) 10215f537a26SJiri Olsa return -EINVAL; 10225f537a26SJiri Olsa 102336adec85SJiri Olsa evsel = __add_event(list, &data->idx, &attr, 1024930a2e29SJiri Olsa pmu_event_name(head_config), pmu->cpus, 1025930a2e29SJiri Olsa &config_terms); 1026410136f5SStephane Eranian if (evsel) { 102746441bdcSMatt Fleming evsel->unit = info.unit; 102846441bdcSMatt Fleming evsel->scale = info.scale; 1029044330c1SMatt Fleming evsel->per_pkg = info.per_pkg; 10301d9e446bSJiri Olsa evsel->snapshot = info.snapshot; 1031410136f5SStephane Eranian } 1032410136f5SStephane Eranian 1033410136f5SStephane Eranian return evsel ? 0 : -ENOMEM; 10345f537a26SJiri Olsa } 10355f537a26SJiri Olsa 10366a4bb04cSJiri Olsa int parse_events__modifier_group(struct list_head *list, 10376a4bb04cSJiri Olsa char *event_mod) 103889efb029SJiri Olsa { 10396a4bb04cSJiri Olsa return parse_events__modifier_event(list, event_mod, true); 10406a4bb04cSJiri Olsa } 10416a4bb04cSJiri Olsa 104263dab225SArnaldo Carvalho de Melo void parse_events__set_leader(char *name, struct list_head *list) 10436a4bb04cSJiri Olsa { 10446a4bb04cSJiri Olsa struct perf_evsel *leader; 10456a4bb04cSJiri Olsa 1046854f7363SWang Nan if (list_empty(list)) { 1047854f7363SWang Nan WARN_ONCE(true, "WARNING: failed to set leader: empty list"); 1048854f7363SWang Nan return; 1049854f7363SWang Nan } 1050854f7363SWang Nan 105163dab225SArnaldo Carvalho de Melo __perf_evlist__set_leader(list); 105263dab225SArnaldo Carvalho de Melo leader = list_entry(list->next, struct perf_evsel, node); 10536a4bb04cSJiri Olsa leader->group_name = name ? strdup(name) : NULL; 105489efb029SJiri Olsa } 105589efb029SJiri Olsa 1056c5cd8ac0SDavid Ahern /* list_event is assumed to point to malloc'ed memory */ 10575d7be90eSJiri Olsa void parse_events_update_lists(struct list_head *list_event, 10585d7be90eSJiri Olsa struct list_head *list_all) 10595d7be90eSJiri Olsa { 10605d7be90eSJiri Olsa /* 10615d7be90eSJiri Olsa * Called for single event definition. Update the 106289efb029SJiri Olsa * 'all event' list, and reinit the 'single event' 10635d7be90eSJiri Olsa * list, for next event definition. 10645d7be90eSJiri Olsa */ 10655d7be90eSJiri Olsa list_splice_tail(list_event, list_all); 1066b847cbdcSJiri Olsa free(list_event); 10675d7be90eSJiri Olsa } 10685d7be90eSJiri Olsa 1069f5b1135bSJiri Olsa struct event_modifier { 1070f5b1135bSJiri Olsa int eu; 1071f5b1135bSJiri Olsa int ek; 1072f5b1135bSJiri Olsa int eh; 1073f5b1135bSJiri Olsa int eH; 1074f5b1135bSJiri Olsa int eG; 1075a1e12da4SJiri Olsa int eI; 1076f5b1135bSJiri Olsa int precise; 10777f94af7aSJiri Olsa int precise_max; 1078f5b1135bSJiri Olsa int exclude_GH; 10793c176311SJiri Olsa int sample_read; 1080e9a7c414SMichael Ellerman int pinned; 1081f5b1135bSJiri Olsa }; 108261c45981SPaul Mackerras 1083f5b1135bSJiri Olsa static int get_event_modifier(struct event_modifier *mod, char *str, 1084f5b1135bSJiri Olsa struct perf_evsel *evsel) 1085f5b1135bSJiri Olsa { 1086f5b1135bSJiri Olsa int eu = evsel ? evsel->attr.exclude_user : 0; 1087f5b1135bSJiri Olsa int ek = evsel ? evsel->attr.exclude_kernel : 0; 1088f5b1135bSJiri Olsa int eh = evsel ? evsel->attr.exclude_hv : 0; 1089f5b1135bSJiri Olsa int eH = evsel ? evsel->attr.exclude_host : 0; 1090f5b1135bSJiri Olsa int eG = evsel ? evsel->attr.exclude_guest : 0; 1091a1e12da4SJiri Olsa int eI = evsel ? evsel->attr.exclude_idle : 0; 1092f5b1135bSJiri Olsa int precise = evsel ? evsel->attr.precise_ip : 0; 10937f94af7aSJiri Olsa int precise_max = 0; 10943c176311SJiri Olsa int sample_read = 0; 1095e9a7c414SMichael Ellerman int pinned = evsel ? evsel->attr.pinned : 0; 1096f5b1135bSJiri Olsa 1097f5b1135bSJiri Olsa int exclude = eu | ek | eh; 1098f5b1135bSJiri Olsa int exclude_GH = evsel ? evsel->exclude_GH : 0; 1099f5b1135bSJiri Olsa 1100f5b1135bSJiri Olsa memset(mod, 0, sizeof(*mod)); 1101ceb53fbfSIngo Molnar 110261c45981SPaul Mackerras while (*str) { 1103ab608344SPeter Zijlstra if (*str == 'u') { 1104ab608344SPeter Zijlstra if (!exclude) 1105ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 110661c45981SPaul Mackerras eu = 0; 1107ab608344SPeter Zijlstra } else if (*str == 'k') { 1108ab608344SPeter Zijlstra if (!exclude) 1109ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 111061c45981SPaul Mackerras ek = 0; 1111ab608344SPeter Zijlstra } else if (*str == 'h') { 1112ab608344SPeter Zijlstra if (!exclude) 1113ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 111461c45981SPaul Mackerras eh = 0; 111599320cc8SJoerg Roedel } else if (*str == 'G') { 111699320cc8SJoerg Roedel if (!exclude_GH) 111799320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 111899320cc8SJoerg Roedel eG = 0; 111999320cc8SJoerg Roedel } else if (*str == 'H') { 112099320cc8SJoerg Roedel if (!exclude_GH) 112199320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 112299320cc8SJoerg Roedel eH = 0; 1123a1e12da4SJiri Olsa } else if (*str == 'I') { 1124a1e12da4SJiri Olsa eI = 1; 1125ab608344SPeter Zijlstra } else if (*str == 'p') { 1126ab608344SPeter Zijlstra precise++; 11271342798cSDavid Ahern /* use of precise requires exclude_guest */ 11281342798cSDavid Ahern if (!exclude_GH) 11291342798cSDavid Ahern eG = 1; 11307f94af7aSJiri Olsa } else if (*str == 'P') { 11317f94af7aSJiri Olsa precise_max = 1; 11323c176311SJiri Olsa } else if (*str == 'S') { 11333c176311SJiri Olsa sample_read = 1; 1134e9a7c414SMichael Ellerman } else if (*str == 'D') { 1135e9a7c414SMichael Ellerman pinned = 1; 1136ab608344SPeter Zijlstra } else 113761c45981SPaul Mackerras break; 1138ab608344SPeter Zijlstra 113961c45981SPaul Mackerras ++str; 114061c45981SPaul Mackerras } 114174d5b588SJaswinder Singh Rajput 114286470930SIngo Molnar /* 114389812fc8SJiri Olsa * precise ip: 114489812fc8SJiri Olsa * 114589812fc8SJiri Olsa * 0 - SAMPLE_IP can have arbitrary skid 114689812fc8SJiri Olsa * 1 - SAMPLE_IP must have constant skid 114789812fc8SJiri Olsa * 2 - SAMPLE_IP requested to have 0 skid 114889812fc8SJiri Olsa * 3 - SAMPLE_IP must have 0 skid 114989812fc8SJiri Olsa * 115089812fc8SJiri Olsa * See also PERF_RECORD_MISC_EXACT_IP 115186470930SIngo Molnar */ 115289812fc8SJiri Olsa if (precise > 3) 115389812fc8SJiri Olsa return -EINVAL; 115486470930SIngo Molnar 1155f5b1135bSJiri Olsa mod->eu = eu; 1156f5b1135bSJiri Olsa mod->ek = ek; 1157f5b1135bSJiri Olsa mod->eh = eh; 1158f5b1135bSJiri Olsa mod->eH = eH; 1159f5b1135bSJiri Olsa mod->eG = eG; 1160a1e12da4SJiri Olsa mod->eI = eI; 1161f5b1135bSJiri Olsa mod->precise = precise; 11627f94af7aSJiri Olsa mod->precise_max = precise_max; 1163f5b1135bSJiri Olsa mod->exclude_GH = exclude_GH; 11643c176311SJiri Olsa mod->sample_read = sample_read; 1165e9a7c414SMichael Ellerman mod->pinned = pinned; 1166e9a7c414SMichael Ellerman 1167f5b1135bSJiri Olsa return 0; 1168f5b1135bSJiri Olsa } 1169f5b1135bSJiri Olsa 1170534123f4SJiri Olsa /* 1171534123f4SJiri Olsa * Basic modifier sanity check to validate it contains only one 1172534123f4SJiri Olsa * instance of any modifier (apart from 'p') present. 1173534123f4SJiri Olsa */ 1174534123f4SJiri Olsa static int check_modifier(char *str) 1175534123f4SJiri Olsa { 1176534123f4SJiri Olsa char *p = str; 1177534123f4SJiri Olsa 1178534123f4SJiri Olsa /* The sizeof includes 0 byte as well. */ 11797f94af7aSJiri Olsa if (strlen(str) > (sizeof("ukhGHpppPSDI") - 1)) 1180534123f4SJiri Olsa return -1; 1181534123f4SJiri Olsa 1182534123f4SJiri Olsa while (*p) { 1183534123f4SJiri Olsa if (*p != 'p' && strchr(p + 1, *p)) 1184534123f4SJiri Olsa return -1; 1185534123f4SJiri Olsa p++; 1186534123f4SJiri Olsa } 1187534123f4SJiri Olsa 1188534123f4SJiri Olsa return 0; 1189534123f4SJiri Olsa } 1190534123f4SJiri Olsa 1191f5b1135bSJiri Olsa int parse_events__modifier_event(struct list_head *list, char *str, bool add) 1192f5b1135bSJiri Olsa { 1193f5b1135bSJiri Olsa struct perf_evsel *evsel; 1194f5b1135bSJiri Olsa struct event_modifier mod; 1195f5b1135bSJiri Olsa 1196f5b1135bSJiri Olsa if (str == NULL) 1197f5b1135bSJiri Olsa return 0; 1198f5b1135bSJiri Olsa 1199534123f4SJiri Olsa if (check_modifier(str)) 1200534123f4SJiri Olsa return -EINVAL; 1201534123f4SJiri Olsa 1202f5b1135bSJiri Olsa if (!add && get_event_modifier(&mod, str, NULL)) 1203f5b1135bSJiri Olsa return -EINVAL; 1204f5b1135bSJiri Olsa 12050050f7aaSArnaldo Carvalho de Melo __evlist__for_each(list, evsel) { 1206f5b1135bSJiri Olsa if (add && get_event_modifier(&mod, str, evsel)) 1207f5b1135bSJiri Olsa return -EINVAL; 1208f5b1135bSJiri Olsa 1209f5b1135bSJiri Olsa evsel->attr.exclude_user = mod.eu; 1210f5b1135bSJiri Olsa evsel->attr.exclude_kernel = mod.ek; 1211f5b1135bSJiri Olsa evsel->attr.exclude_hv = mod.eh; 1212f5b1135bSJiri Olsa evsel->attr.precise_ip = mod.precise; 1213f5b1135bSJiri Olsa evsel->attr.exclude_host = mod.eH; 1214f5b1135bSJiri Olsa evsel->attr.exclude_guest = mod.eG; 1215a1e12da4SJiri Olsa evsel->attr.exclude_idle = mod.eI; 1216f5b1135bSJiri Olsa evsel->exclude_GH = mod.exclude_GH; 12173c176311SJiri Olsa evsel->sample_read = mod.sample_read; 12187f94af7aSJiri Olsa evsel->precise_max = mod.precise_max; 1219e9a7c414SMichael Ellerman 1220e9a7c414SMichael Ellerman if (perf_evsel__is_group_leader(evsel)) 1221e9a7c414SMichael Ellerman evsel->attr.pinned = mod.pinned; 1222ceb53fbfSIngo Molnar } 122386470930SIngo Molnar 122489812fc8SJiri Olsa return 0; 122586470930SIngo Molnar } 122686470930SIngo Molnar 1227ac2ba9f3SRobert Richter int parse_events_name(struct list_head *list, char *name) 1228ac2ba9f3SRobert Richter { 1229ac2ba9f3SRobert Richter struct perf_evsel *evsel; 1230ac2ba9f3SRobert Richter 12310050f7aaSArnaldo Carvalho de Melo __evlist__for_each(list, evsel) { 1232ac2ba9f3SRobert Richter if (!evsel->name) 1233ac2ba9f3SRobert Richter evsel->name = strdup(name); 1234ac2ba9f3SRobert Richter } 1235ac2ba9f3SRobert Richter 1236ac2ba9f3SRobert Richter return 0; 1237ac2ba9f3SRobert Richter } 1238ac2ba9f3SRobert Richter 1239dcb4e102SKan Liang static int 1240dcb4e102SKan Liang comp_pmu(const void *p1, const void *p2) 1241dcb4e102SKan Liang { 1242dcb4e102SKan Liang struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1; 1243dcb4e102SKan Liang struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2; 1244dcb4e102SKan Liang 1245dcb4e102SKan Liang return strcmp(pmu1->symbol, pmu2->symbol); 1246dcb4e102SKan Liang } 1247dcb4e102SKan Liang 1248dcb4e102SKan Liang static void perf_pmu__parse_cleanup(void) 1249dcb4e102SKan Liang { 1250dcb4e102SKan Liang if (perf_pmu_events_list_num > 0) { 1251dcb4e102SKan Liang struct perf_pmu_event_symbol *p; 1252dcb4e102SKan Liang int i; 1253dcb4e102SKan Liang 1254dcb4e102SKan Liang for (i = 0; i < perf_pmu_events_list_num; i++) { 1255dcb4e102SKan Liang p = perf_pmu_events_list + i; 1256dcb4e102SKan Liang free(p->symbol); 1257dcb4e102SKan Liang } 1258dcb4e102SKan Liang free(perf_pmu_events_list); 1259dcb4e102SKan Liang perf_pmu_events_list = NULL; 1260dcb4e102SKan Liang perf_pmu_events_list_num = 0; 1261dcb4e102SKan Liang } 1262dcb4e102SKan Liang } 1263dcb4e102SKan Liang 1264dcb4e102SKan Liang #define SET_SYMBOL(str, stype) \ 1265dcb4e102SKan Liang do { \ 1266dcb4e102SKan Liang p->symbol = str; \ 1267dcb4e102SKan Liang if (!p->symbol) \ 1268dcb4e102SKan Liang goto err; \ 1269dcb4e102SKan Liang p->type = stype; \ 1270dcb4e102SKan Liang } while (0) 1271dcb4e102SKan Liang 1272dcb4e102SKan Liang /* 1273dcb4e102SKan Liang * Read the pmu events list from sysfs 1274dcb4e102SKan Liang * Save it into perf_pmu_events_list 1275dcb4e102SKan Liang */ 1276dcb4e102SKan Liang static void perf_pmu__parse_init(void) 1277dcb4e102SKan Liang { 1278dcb4e102SKan Liang 1279dcb4e102SKan Liang struct perf_pmu *pmu = NULL; 1280dcb4e102SKan Liang struct perf_pmu_alias *alias; 1281dcb4e102SKan Liang int len = 0; 1282dcb4e102SKan Liang 1283dcb4e102SKan Liang pmu = perf_pmu__find("cpu"); 1284dcb4e102SKan Liang if ((pmu == NULL) || list_empty(&pmu->aliases)) { 1285dcb4e102SKan Liang perf_pmu_events_list_num = -1; 1286dcb4e102SKan Liang return; 1287dcb4e102SKan Liang } 1288dcb4e102SKan Liang list_for_each_entry(alias, &pmu->aliases, list) { 1289dcb4e102SKan Liang if (strchr(alias->name, '-')) 1290dcb4e102SKan Liang len++; 1291dcb4e102SKan Liang len++; 1292dcb4e102SKan Liang } 1293dcb4e102SKan Liang perf_pmu_events_list = malloc(sizeof(struct perf_pmu_event_symbol) * len); 1294dcb4e102SKan Liang if (!perf_pmu_events_list) 1295dcb4e102SKan Liang return; 1296dcb4e102SKan Liang perf_pmu_events_list_num = len; 1297dcb4e102SKan Liang 1298dcb4e102SKan Liang len = 0; 1299dcb4e102SKan Liang list_for_each_entry(alias, &pmu->aliases, list) { 1300dcb4e102SKan Liang struct perf_pmu_event_symbol *p = perf_pmu_events_list + len; 1301dcb4e102SKan Liang char *tmp = strchr(alias->name, '-'); 1302dcb4e102SKan Liang 1303dcb4e102SKan Liang if (tmp != NULL) { 1304dcb4e102SKan Liang SET_SYMBOL(strndup(alias->name, tmp - alias->name), 1305dcb4e102SKan Liang PMU_EVENT_SYMBOL_PREFIX); 1306dcb4e102SKan Liang p++; 1307dcb4e102SKan Liang SET_SYMBOL(strdup(++tmp), PMU_EVENT_SYMBOL_SUFFIX); 1308dcb4e102SKan Liang len += 2; 1309dcb4e102SKan Liang } else { 1310dcb4e102SKan Liang SET_SYMBOL(strdup(alias->name), PMU_EVENT_SYMBOL); 1311dcb4e102SKan Liang len++; 1312dcb4e102SKan Liang } 1313dcb4e102SKan Liang } 1314dcb4e102SKan Liang qsort(perf_pmu_events_list, len, 1315dcb4e102SKan Liang sizeof(struct perf_pmu_event_symbol), comp_pmu); 1316dcb4e102SKan Liang 1317dcb4e102SKan Liang return; 1318dcb4e102SKan Liang err: 1319dcb4e102SKan Liang perf_pmu__parse_cleanup(); 1320dcb4e102SKan Liang } 1321dcb4e102SKan Liang 1322dcb4e102SKan Liang enum perf_pmu_event_symbol_type 1323dcb4e102SKan Liang perf_pmu__parse_check(const char *name) 1324dcb4e102SKan Liang { 1325dcb4e102SKan Liang struct perf_pmu_event_symbol p, *r; 1326dcb4e102SKan Liang 1327dcb4e102SKan Liang /* scan kernel pmu events from sysfs if needed */ 1328dcb4e102SKan Liang if (perf_pmu_events_list_num == 0) 1329dcb4e102SKan Liang perf_pmu__parse_init(); 1330dcb4e102SKan Liang /* 1331dcb4e102SKan Liang * name "cpu" could be prefix of cpu-cycles or cpu// events. 1332dcb4e102SKan Liang * cpu-cycles has been handled by hardcode. 1333dcb4e102SKan Liang * So it must be cpu// events, not kernel pmu event. 1334dcb4e102SKan Liang */ 1335dcb4e102SKan Liang if ((perf_pmu_events_list_num <= 0) || !strcmp(name, "cpu")) 1336dcb4e102SKan Liang return PMU_EVENT_SYMBOL_ERR; 1337dcb4e102SKan Liang 1338dcb4e102SKan Liang p.symbol = strdup(name); 1339dcb4e102SKan Liang r = bsearch(&p, perf_pmu_events_list, 1340dcb4e102SKan Liang (size_t) perf_pmu_events_list_num, 1341dcb4e102SKan Liang sizeof(struct perf_pmu_event_symbol), comp_pmu); 1342dcb4e102SKan Liang free(p.symbol); 1343dcb4e102SKan Liang return r ? r->type : PMU_EVENT_SYMBOL_ERR; 1344dcb4e102SKan Liang } 1345dcb4e102SKan Liang 134690e2b22dSJiri Olsa static int parse_events__scanner(const char *str, void *data, int start_token) 1347ac20de6fSZheng Yan { 1348ac20de6fSZheng Yan YY_BUFFER_STATE buffer; 1349ac20de6fSZheng Yan void *scanner; 1350ac20de6fSZheng Yan int ret; 1351ac20de6fSZheng Yan 135290e2b22dSJiri Olsa ret = parse_events_lex_init_extra(start_token, &scanner); 1353ac20de6fSZheng Yan if (ret) 1354ac20de6fSZheng Yan return ret; 1355ac20de6fSZheng Yan 1356ac20de6fSZheng Yan buffer = parse_events__scan_string(str, scanner); 1357ac20de6fSZheng Yan 1358ac20de6fSZheng Yan #ifdef PARSER_DEBUG 1359ac20de6fSZheng Yan parse_events_debug = 1; 1360ac20de6fSZheng Yan #endif 1361ac20de6fSZheng Yan ret = parse_events_parse(data, scanner); 1362ac20de6fSZheng Yan 1363ac20de6fSZheng Yan parse_events__flush_buffer(buffer, scanner); 1364ac20de6fSZheng Yan parse_events__delete_buffer(buffer, scanner); 1365ac20de6fSZheng Yan parse_events_lex_destroy(scanner); 1366ac20de6fSZheng Yan return ret; 1367ac20de6fSZheng Yan } 1368ac20de6fSZheng Yan 136990e2b22dSJiri Olsa /* 137090e2b22dSJiri Olsa * parse event config string, return a list of event terms. 137190e2b22dSJiri Olsa */ 137290e2b22dSJiri Olsa int parse_events_terms(struct list_head *terms, const char *str) 137390e2b22dSJiri Olsa { 137423b6339bSArnaldo Carvalho de Melo struct parse_events_terms data = { 137590e2b22dSJiri Olsa .terms = NULL, 137690e2b22dSJiri Olsa }; 137790e2b22dSJiri Olsa int ret; 137890e2b22dSJiri Olsa 137990e2b22dSJiri Olsa ret = parse_events__scanner(str, &data, PE_START_TERMS); 138090e2b22dSJiri Olsa if (!ret) { 138190e2b22dSJiri Olsa list_splice(data.terms, terms); 138274cf249dSArnaldo Carvalho de Melo zfree(&data.terms); 138390e2b22dSJiri Olsa return 0; 138490e2b22dSJiri Olsa } 138590e2b22dSJiri Olsa 1386b2c34fdeSAdrian Hunter if (data.terms) 138790e2b22dSJiri Olsa parse_events__free_terms(data.terms); 138890e2b22dSJiri Olsa return ret; 138990e2b22dSJiri Olsa } 139090e2b22dSJiri Olsa 1391b39b8393SJiri Olsa int parse_events(struct perf_evlist *evlist, const char *str, 1392b39b8393SJiri Olsa struct parse_events_error *err) 139386470930SIngo Molnar { 139423b6339bSArnaldo Carvalho de Melo struct parse_events_evlist data = { 139546010ab2SJiri Olsa .list = LIST_HEAD_INIT(data.list), 139646010ab2SJiri Olsa .idx = evlist->nr_entries, 1397b39b8393SJiri Olsa .error = err, 139846010ab2SJiri Olsa }; 139946010ab2SJiri Olsa int ret; 140086470930SIngo Molnar 140190e2b22dSJiri Olsa ret = parse_events__scanner(str, &data, PE_START_EVENTS); 1402dcb4e102SKan Liang perf_pmu__parse_cleanup(); 140389812fc8SJiri Olsa if (!ret) { 140415bfd2ccSWang Nan struct perf_evsel *last; 140515bfd2ccSWang Nan 1406854f7363SWang Nan if (list_empty(&data.list)) { 1407854f7363SWang Nan WARN_ONCE(true, "WARNING: event parser found nothing"); 1408854f7363SWang Nan return -1; 1409854f7363SWang Nan } 1410854f7363SWang Nan 1411f114d6efSAdrian Hunter perf_evlist__splice_list_tail(evlist, &data.list); 141297f63e4aSNamhyung Kim evlist->nr_groups += data.nr_groups; 141315bfd2ccSWang Nan last = perf_evlist__last(evlist); 141415bfd2ccSWang Nan last->cmdline_group_boundary = true; 141515bfd2ccSWang Nan 141686470930SIngo Molnar return 0; 141786470930SIngo Molnar } 141886470930SIngo Molnar 14195d7be90eSJiri Olsa /* 14205d7be90eSJiri Olsa * There are 2 users - builtin-record and builtin-test objects. 14215d7be90eSJiri Olsa * Both call perf_evlist__delete in case of error, so we dont 14225d7be90eSJiri Olsa * need to bother. 14235d7be90eSJiri Olsa */ 142489812fc8SJiri Olsa return ret; 142589812fc8SJiri Olsa } 142689812fc8SJiri Olsa 1427b39b8393SJiri Olsa #define MAX_WIDTH 1000 1428b39b8393SJiri Olsa static int get_term_width(void) 1429b39b8393SJiri Olsa { 1430b39b8393SJiri Olsa struct winsize ws; 1431b39b8393SJiri Olsa 1432b39b8393SJiri Olsa get_term_dimensions(&ws); 1433b39b8393SJiri Olsa return ws.ws_col > MAX_WIDTH ? MAX_WIDTH : ws.ws_col; 1434b39b8393SJiri Olsa } 1435b39b8393SJiri Olsa 1436b39b8393SJiri Olsa static void parse_events_print_error(struct parse_events_error *err, 1437b39b8393SJiri Olsa const char *event) 1438b39b8393SJiri Olsa { 1439b39b8393SJiri Olsa const char *str = "invalid or unsupported event: "; 1440b39b8393SJiri Olsa char _buf[MAX_WIDTH]; 1441b39b8393SJiri Olsa char *buf = (char *) event; 1442b39b8393SJiri Olsa int idx = 0; 1443b39b8393SJiri Olsa 1444b39b8393SJiri Olsa if (err->str) { 1445b39b8393SJiri Olsa /* -2 for extra '' in the final fprintf */ 1446b39b8393SJiri Olsa int width = get_term_width() - 2; 1447b39b8393SJiri Olsa int len_event = strlen(event); 1448b39b8393SJiri Olsa int len_str, max_len, cut = 0; 1449b39b8393SJiri Olsa 1450b39b8393SJiri Olsa /* 1451b39b8393SJiri Olsa * Maximum error index indent, we will cut 1452b39b8393SJiri Olsa * the event string if it's bigger. 1453b39b8393SJiri Olsa */ 1454141b2d31SAdrian Hunter int max_err_idx = 13; 1455b39b8393SJiri Olsa 1456b39b8393SJiri Olsa /* 1457b39b8393SJiri Olsa * Let's be specific with the message when 1458b39b8393SJiri Olsa * we have the precise error. 1459b39b8393SJiri Olsa */ 1460b39b8393SJiri Olsa str = "event syntax error: "; 1461b39b8393SJiri Olsa len_str = strlen(str); 1462b39b8393SJiri Olsa max_len = width - len_str; 1463b39b8393SJiri Olsa 1464b39b8393SJiri Olsa buf = _buf; 1465b39b8393SJiri Olsa 1466b39b8393SJiri Olsa /* We're cutting from the beggining. */ 1467b39b8393SJiri Olsa if (err->idx > max_err_idx) 1468b39b8393SJiri Olsa cut = err->idx - max_err_idx; 1469b39b8393SJiri Olsa 1470b39b8393SJiri Olsa strncpy(buf, event + cut, max_len); 1471b39b8393SJiri Olsa 1472b39b8393SJiri Olsa /* Mark cut parts with '..' on both sides. */ 1473b39b8393SJiri Olsa if (cut) 1474b39b8393SJiri Olsa buf[0] = buf[1] = '.'; 1475b39b8393SJiri Olsa 1476b39b8393SJiri Olsa if ((len_event - cut) > max_len) { 1477b39b8393SJiri Olsa buf[max_len - 1] = buf[max_len - 2] = '.'; 1478b39b8393SJiri Olsa buf[max_len] = 0; 1479b39b8393SJiri Olsa } 1480b39b8393SJiri Olsa 1481b39b8393SJiri Olsa idx = len_str + err->idx - cut; 1482b39b8393SJiri Olsa } 1483b39b8393SJiri Olsa 1484b39b8393SJiri Olsa fprintf(stderr, "%s'%s'\n", str, buf); 1485b39b8393SJiri Olsa if (idx) { 1486b39b8393SJiri Olsa fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err->str); 1487b39b8393SJiri Olsa if (err->help) 1488b39b8393SJiri Olsa fprintf(stderr, "\n%s\n", err->help); 1489b39b8393SJiri Olsa free(err->str); 1490b39b8393SJiri Olsa free(err->help); 1491b39b8393SJiri Olsa } 1492b39b8393SJiri Olsa 1493b39b8393SJiri Olsa fprintf(stderr, "Run 'perf list' for a list of valid events\n"); 1494b39b8393SJiri Olsa } 1495b39b8393SJiri Olsa 1496b39b8393SJiri Olsa #undef MAX_WIDTH 1497b39b8393SJiri Olsa 1498f120f9d5SJiri Olsa int parse_events_option(const struct option *opt, const char *str, 14991d037ca1SIrina Tirdea int unset __maybe_unused) 1500f120f9d5SJiri Olsa { 1501f120f9d5SJiri Olsa struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 1502b39b8393SJiri Olsa struct parse_events_error err = { .idx = 0, }; 1503b39b8393SJiri Olsa int ret = parse_events(evlist, str, &err); 15049175ce1fSAndi Kleen 1505b39b8393SJiri Olsa if (ret) 1506b39b8393SJiri Olsa parse_events_print_error(&err, str); 1507b39b8393SJiri Olsa 15089175ce1fSAndi Kleen return ret; 1509f120f9d5SJiri Olsa } 1510f120f9d5SJiri Olsa 15114ba1faa1SWang Nan static int 15124ba1faa1SWang Nan foreach_evsel_in_last_glob(struct perf_evlist *evlist, 15134ba1faa1SWang Nan int (*func)(struct perf_evsel *evsel, 15144ba1faa1SWang Nan const void *arg), 15154ba1faa1SWang Nan const void *arg) 1516c171b552SLi Zefan { 151769aad6f1SArnaldo Carvalho de Melo struct perf_evsel *last = NULL; 15184ba1faa1SWang Nan int err; 1519c171b552SLi Zefan 1520854f7363SWang Nan /* 1521854f7363SWang Nan * Don't return when list_empty, give func a chance to report 1522854f7363SWang Nan * error when it found last == NULL. 1523854f7363SWang Nan * 1524854f7363SWang Nan * So no need to WARN here, let *func do this. 1525854f7363SWang Nan */ 1526361c99a6SArnaldo Carvalho de Melo if (evlist->nr_entries > 0) 15270c21f736SArnaldo Carvalho de Melo last = perf_evlist__last(evlist); 152869aad6f1SArnaldo Carvalho de Melo 152915bfd2ccSWang Nan do { 15304ba1faa1SWang Nan err = (*func)(last, arg); 15314ba1faa1SWang Nan if (err) 1532c171b552SLi Zefan return -1; 15334ba1faa1SWang Nan if (!last) 15344ba1faa1SWang Nan return 0; 1535c171b552SLi Zefan 153615bfd2ccSWang Nan if (last->node.prev == &evlist->entries) 153715bfd2ccSWang Nan return 0; 153815bfd2ccSWang Nan last = list_entry(last->node.prev, struct perf_evsel, node); 153915bfd2ccSWang Nan } while (!last->cmdline_group_boundary); 154015bfd2ccSWang Nan 1541c171b552SLi Zefan return 0; 1542c171b552SLi Zefan } 1543c171b552SLi Zefan 15444ba1faa1SWang Nan static int set_filter(struct perf_evsel *evsel, const void *arg) 15454ba1faa1SWang Nan { 15464ba1faa1SWang Nan const char *str = arg; 15474ba1faa1SWang Nan 15484ba1faa1SWang Nan if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) { 15494ba1faa1SWang Nan fprintf(stderr, 15504ba1faa1SWang Nan "--filter option should follow a -e tracepoint option\n"); 15514ba1faa1SWang Nan return -1; 15524ba1faa1SWang Nan } 15534ba1faa1SWang Nan 15544ba1faa1SWang Nan if (perf_evsel__append_filter(evsel, "&&", str) < 0) { 15554ba1faa1SWang Nan fprintf(stderr, 15564ba1faa1SWang Nan "not enough memory to hold filter string\n"); 15574ba1faa1SWang Nan return -1; 15584ba1faa1SWang Nan } 15594ba1faa1SWang Nan 15604ba1faa1SWang Nan return 0; 15614ba1faa1SWang Nan } 15624ba1faa1SWang Nan 15634ba1faa1SWang Nan int parse_filter(const struct option *opt, const char *str, 15644ba1faa1SWang Nan int unset __maybe_unused) 15654ba1faa1SWang Nan { 15664ba1faa1SWang Nan struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 15674ba1faa1SWang Nan 15684ba1faa1SWang Nan return foreach_evsel_in_last_glob(evlist, set_filter, 15694ba1faa1SWang Nan (const void *)str); 15704ba1faa1SWang Nan } 15714ba1faa1SWang Nan 15724ba1faa1SWang Nan static int add_exclude_perf_filter(struct perf_evsel *evsel, 15734ba1faa1SWang Nan const void *arg __maybe_unused) 15744ba1faa1SWang Nan { 15754ba1faa1SWang Nan char new_filter[64]; 15764ba1faa1SWang Nan 15774ba1faa1SWang Nan if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) { 15784ba1faa1SWang Nan fprintf(stderr, 15794ba1faa1SWang Nan "--exclude-perf option should follow a -e tracepoint option\n"); 15804ba1faa1SWang Nan return -1; 15814ba1faa1SWang Nan } 15824ba1faa1SWang Nan 15834ba1faa1SWang Nan snprintf(new_filter, sizeof(new_filter), "common_pid != %d", getpid()); 15844ba1faa1SWang Nan 15854ba1faa1SWang Nan if (perf_evsel__append_filter(evsel, "&&", new_filter) < 0) { 15864ba1faa1SWang Nan fprintf(stderr, 15874ba1faa1SWang Nan "not enough memory to hold filter string\n"); 15884ba1faa1SWang Nan return -1; 15894ba1faa1SWang Nan } 15904ba1faa1SWang Nan 15914ba1faa1SWang Nan return 0; 15924ba1faa1SWang Nan } 15934ba1faa1SWang Nan 15944ba1faa1SWang Nan int exclude_perf(const struct option *opt, 15954ba1faa1SWang Nan const char *arg __maybe_unused, 15964ba1faa1SWang Nan int unset __maybe_unused) 15974ba1faa1SWang Nan { 15984ba1faa1SWang Nan struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 15994ba1faa1SWang Nan 16004ba1faa1SWang Nan return foreach_evsel_in_last_glob(evlist, add_exclude_perf_filter, 16014ba1faa1SWang Nan NULL); 16024ba1faa1SWang Nan } 16034ba1faa1SWang Nan 160486470930SIngo Molnar static const char * const event_type_descriptors[] = { 160586470930SIngo Molnar "Hardware event", 160686470930SIngo Molnar "Software event", 160786470930SIngo Molnar "Tracepoint event", 160886470930SIngo Molnar "Hardware cache event", 160941bdcb23SLiming Wang "Raw hardware event descriptor", 161041bdcb23SLiming Wang "Hardware breakpoint", 161186470930SIngo Molnar }; 161286470930SIngo Molnar 1613ab0e4800SYunlong Song static int cmp_string(const void *a, const void *b) 1614ab0e4800SYunlong Song { 1615ab0e4800SYunlong Song const char * const *as = a; 1616ab0e4800SYunlong Song const char * const *bs = b; 1617ab0e4800SYunlong Song 1618ab0e4800SYunlong Song return strcmp(*as, *bs); 1619ab0e4800SYunlong Song } 1620ab0e4800SYunlong Song 162186470930SIngo Molnar /* 1622f6bdafefSJason Baron * Print the events from <debugfs_mount_point>/tracing/events 1623f6bdafefSJason Baron */ 1624f6bdafefSJason Baron 1625a3277d2dSFrederic Weisbecker void print_tracepoint_events(const char *subsys_glob, const char *event_glob, 1626a3277d2dSFrederic Weisbecker bool name_only) 1627f6bdafefSJason Baron { 1628f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 1629f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1630f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 1631725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 1632ab0e4800SYunlong Song char **evt_list = NULL; 1633ab0e4800SYunlong Song unsigned int evt_i = 0, evt_num = 0; 1634ab0e4800SYunlong Song bool evt_num_known = false; 1635f6bdafefSJason Baron 1636ab0e4800SYunlong Song restart: 1637ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 1638f6bdafefSJason Baron if (!sys_dir) 1639725b1368SEric Dumazet return; 1640f6bdafefSJason Baron 1641ab0e4800SYunlong Song if (evt_num_known) { 1642ab0e4800SYunlong Song evt_list = zalloc(sizeof(char *) * evt_num); 1643ab0e4800SYunlong Song if (!evt_list) 1644ab0e4800SYunlong Song goto out_close_sys_dir; 1645ab0e4800SYunlong Song } 1646ab0e4800SYunlong Song 16476b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 1648668b8788SArnaldo Carvalho de Melo if (subsys_glob != NULL && 1649668b8788SArnaldo Carvalho de Melo !strglobmatch(sys_dirent.d_name, subsys_glob)) 1650668b8788SArnaldo Carvalho de Melo continue; 1651725b1368SEric Dumazet 1652ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 1653725b1368SEric Dumazet sys_dirent.d_name); 1654725b1368SEric Dumazet evt_dir = opendir(dir_path); 1655725b1368SEric Dumazet if (!evt_dir) 16566b58e7f1SUlrich Drepper continue; 1657725b1368SEric Dumazet 16586b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 1659668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 1660668b8788SArnaldo Carvalho de Melo !strglobmatch(evt_dirent.d_name, event_glob)) 1661668b8788SArnaldo Carvalho de Melo continue; 1662668b8788SArnaldo Carvalho de Melo 1663ab0e4800SYunlong Song if (!evt_num_known) { 1664ab0e4800SYunlong Song evt_num++; 1665a3277d2dSFrederic Weisbecker continue; 1666a3277d2dSFrederic Weisbecker } 1667a3277d2dSFrederic Weisbecker 1668f6bdafefSJason Baron snprintf(evt_path, MAXPATHLEN, "%s:%s", 1669f6bdafefSJason Baron sys_dirent.d_name, evt_dirent.d_name); 1670ab0e4800SYunlong Song 1671ab0e4800SYunlong Song evt_list[evt_i] = strdup(evt_path); 1672ab0e4800SYunlong Song if (evt_list[evt_i] == NULL) 1673ab0e4800SYunlong Song goto out_close_evt_dir; 1674ab0e4800SYunlong Song evt_i++; 1675f6bdafefSJason Baron } 1676f6bdafefSJason Baron closedir(evt_dir); 1677f6bdafefSJason Baron } 1678f6bdafefSJason Baron closedir(sys_dir); 1679ab0e4800SYunlong Song 1680ab0e4800SYunlong Song if (!evt_num_known) { 1681ab0e4800SYunlong Song evt_num_known = true; 1682ab0e4800SYunlong Song goto restart; 1683ab0e4800SYunlong Song } 1684ab0e4800SYunlong Song qsort(evt_list, evt_num, sizeof(char *), cmp_string); 1685ab0e4800SYunlong Song evt_i = 0; 1686ab0e4800SYunlong Song while (evt_i < evt_num) { 1687ab0e4800SYunlong Song if (name_only) { 1688ab0e4800SYunlong Song printf("%s ", evt_list[evt_i++]); 1689ab0e4800SYunlong Song continue; 1690ab0e4800SYunlong Song } 1691ab0e4800SYunlong Song printf(" %-50s [%s]\n", evt_list[evt_i++], 1692ab0e4800SYunlong Song event_type_descriptors[PERF_TYPE_TRACEPOINT]); 1693ab0e4800SYunlong Song } 1694dfc431cbSArnaldo Carvalho de Melo if (evt_num && pager_in_use()) 1695ab0e4800SYunlong Song printf("\n"); 1696ab0e4800SYunlong Song 1697ab0e4800SYunlong Song out_free: 1698ab0e4800SYunlong Song evt_num = evt_i; 1699ab0e4800SYunlong Song for (evt_i = 0; evt_i < evt_num; evt_i++) 1700ab0e4800SYunlong Song zfree(&evt_list[evt_i]); 1701ab0e4800SYunlong Song zfree(&evt_list); 1702ab0e4800SYunlong Song return; 1703ab0e4800SYunlong Song 1704ab0e4800SYunlong Song out_close_evt_dir: 1705ab0e4800SYunlong Song closedir(evt_dir); 1706ab0e4800SYunlong Song out_close_sys_dir: 1707ab0e4800SYunlong Song closedir(sys_dir); 1708ab0e4800SYunlong Song 1709ab0e4800SYunlong Song printf("FATAL: not enough memory to print %s\n", 1710ab0e4800SYunlong Song event_type_descriptors[PERF_TYPE_TRACEPOINT]); 1711ab0e4800SYunlong Song if (evt_list) 1712ab0e4800SYunlong Song goto out_free; 1713f6bdafefSJason Baron } 1714f6bdafefSJason Baron 1715f6bdafefSJason Baron /* 171620c457b8SThomas Renninger * Check whether event is in <debugfs_mount_point>/tracing/events 171720c457b8SThomas Renninger */ 171820c457b8SThomas Renninger 171920c457b8SThomas Renninger int is_valid_tracepoint(const char *event_string) 172020c457b8SThomas Renninger { 172120c457b8SThomas Renninger DIR *sys_dir, *evt_dir; 172220c457b8SThomas Renninger struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 172320c457b8SThomas Renninger char evt_path[MAXPATHLEN]; 172420c457b8SThomas Renninger char dir_path[MAXPATHLEN]; 172520c457b8SThomas Renninger 1726ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 172720c457b8SThomas Renninger if (!sys_dir) 172820c457b8SThomas Renninger return 0; 172920c457b8SThomas Renninger 173020c457b8SThomas Renninger for_each_subsystem(sys_dir, sys_dirent, sys_next) { 173120c457b8SThomas Renninger 1732ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 173320c457b8SThomas Renninger sys_dirent.d_name); 173420c457b8SThomas Renninger evt_dir = opendir(dir_path); 173520c457b8SThomas Renninger if (!evt_dir) 173620c457b8SThomas Renninger continue; 173720c457b8SThomas Renninger 173820c457b8SThomas Renninger for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 173920c457b8SThomas Renninger snprintf(evt_path, MAXPATHLEN, "%s:%s", 174020c457b8SThomas Renninger sys_dirent.d_name, evt_dirent.d_name); 174120c457b8SThomas Renninger if (!strcmp(evt_path, event_string)) { 174220c457b8SThomas Renninger closedir(evt_dir); 174320c457b8SThomas Renninger closedir(sys_dir); 174420c457b8SThomas Renninger return 1; 174520c457b8SThomas Renninger } 174620c457b8SThomas Renninger } 174720c457b8SThomas Renninger closedir(evt_dir); 174820c457b8SThomas Renninger } 174920c457b8SThomas Renninger closedir(sys_dir); 175020c457b8SThomas Renninger return 0; 175120c457b8SThomas Renninger } 175220c457b8SThomas Renninger 1753b41f1cecSNamhyung Kim static bool is_event_supported(u8 type, unsigned config) 1754b41f1cecSNamhyung Kim { 1755b41f1cecSNamhyung Kim bool ret = true; 175688fee52eSVince Weaver int open_return; 1757b41f1cecSNamhyung Kim struct perf_evsel *evsel; 1758b41f1cecSNamhyung Kim struct perf_event_attr attr = { 1759b41f1cecSNamhyung Kim .type = type, 1760b41f1cecSNamhyung Kim .config = config, 1761b41f1cecSNamhyung Kim .disabled = 1, 1762b41f1cecSNamhyung Kim }; 1763b41f1cecSNamhyung Kim struct { 1764b41f1cecSNamhyung Kim struct thread_map map; 1765b41f1cecSNamhyung Kim int threads[1]; 1766b41f1cecSNamhyung Kim } tmap = { 1767b41f1cecSNamhyung Kim .map.nr = 1, 1768b41f1cecSNamhyung Kim .threads = { 0 }, 1769b41f1cecSNamhyung Kim }; 1770b41f1cecSNamhyung Kim 1771ef503831SArnaldo Carvalho de Melo evsel = perf_evsel__new(&attr); 1772b41f1cecSNamhyung Kim if (evsel) { 177388fee52eSVince Weaver open_return = perf_evsel__open(evsel, NULL, &tmap.map); 177488fee52eSVince Weaver ret = open_return >= 0; 177588fee52eSVince Weaver 177688fee52eSVince Weaver if (open_return == -EACCES) { 177788fee52eSVince Weaver /* 177888fee52eSVince Weaver * This happens if the paranoid value 177988fee52eSVince Weaver * /proc/sys/kernel/perf_event_paranoid is set to 2 178088fee52eSVince Weaver * Re-run with exclude_kernel set; we don't do that 178188fee52eSVince Weaver * by default as some ARM machines do not support it. 178288fee52eSVince Weaver * 178388fee52eSVince Weaver */ 178488fee52eSVince Weaver evsel->attr.exclude_kernel = 1; 1785b41f1cecSNamhyung Kim ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; 178688fee52eSVince Weaver } 1787b41f1cecSNamhyung Kim perf_evsel__delete(evsel); 1788b41f1cecSNamhyung Kim } 1789b41f1cecSNamhyung Kim 1790b41f1cecSNamhyung Kim return ret; 1791b41f1cecSNamhyung Kim } 1792b41f1cecSNamhyung Kim 1793a3277d2dSFrederic Weisbecker int print_hwcache_events(const char *event_glob, bool name_only) 1794668b8788SArnaldo Carvalho de Melo { 1795ab0e4800SYunlong Song unsigned int type, op, i, evt_i = 0, evt_num = 0; 17960b668bc9SArnaldo Carvalho de Melo char name[64]; 1797ab0e4800SYunlong Song char **evt_list = NULL; 1798ab0e4800SYunlong Song bool evt_num_known = false; 1799ab0e4800SYunlong Song 1800ab0e4800SYunlong Song restart: 1801ab0e4800SYunlong Song if (evt_num_known) { 1802ab0e4800SYunlong Song evt_list = zalloc(sizeof(char *) * evt_num); 1803ab0e4800SYunlong Song if (!evt_list) 1804ab0e4800SYunlong Song goto out_enomem; 1805ab0e4800SYunlong Song } 1806668b8788SArnaldo Carvalho de Melo 1807668b8788SArnaldo Carvalho de Melo for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 1808668b8788SArnaldo Carvalho de Melo for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 1809668b8788SArnaldo Carvalho de Melo /* skip invalid cache type */ 18100b668bc9SArnaldo Carvalho de Melo if (!perf_evsel__is_cache_op_valid(type, op)) 1811668b8788SArnaldo Carvalho de Melo continue; 1812668b8788SArnaldo Carvalho de Melo 1813668b8788SArnaldo Carvalho de Melo for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 18140b668bc9SArnaldo Carvalho de Melo __perf_evsel__hw_cache_type_op_res_name(type, op, i, 18150b668bc9SArnaldo Carvalho de Melo name, sizeof(name)); 1816947b4ad1SIngo Molnar if (event_glob != NULL && !strglobmatch(name, event_glob)) 1817668b8788SArnaldo Carvalho de Melo continue; 1818668b8788SArnaldo Carvalho de Melo 1819b41f1cecSNamhyung Kim if (!is_event_supported(PERF_TYPE_HW_CACHE, 1820b41f1cecSNamhyung Kim type | (op << 8) | (i << 16))) 1821b41f1cecSNamhyung Kim continue; 1822b41f1cecSNamhyung Kim 1823ab0e4800SYunlong Song if (!evt_num_known) { 1824ab0e4800SYunlong Song evt_num++; 1825ab0e4800SYunlong Song continue; 1826ab0e4800SYunlong Song } 1827ab0e4800SYunlong Song 1828ab0e4800SYunlong Song evt_list[evt_i] = strdup(name); 1829ab0e4800SYunlong Song if (evt_list[evt_i] == NULL) 1830ab0e4800SYunlong Song goto out_enomem; 1831ab0e4800SYunlong Song evt_i++; 1832668b8788SArnaldo Carvalho de Melo } 1833668b8788SArnaldo Carvalho de Melo } 1834668b8788SArnaldo Carvalho de Melo } 1835668b8788SArnaldo Carvalho de Melo 1836ab0e4800SYunlong Song if (!evt_num_known) { 1837ab0e4800SYunlong Song evt_num_known = true; 1838ab0e4800SYunlong Song goto restart; 1839ab0e4800SYunlong Song } 1840ab0e4800SYunlong Song qsort(evt_list, evt_num, sizeof(char *), cmp_string); 1841ab0e4800SYunlong Song evt_i = 0; 1842ab0e4800SYunlong Song while (evt_i < evt_num) { 1843ab0e4800SYunlong Song if (name_only) { 1844ab0e4800SYunlong Song printf("%s ", evt_list[evt_i++]); 1845ab0e4800SYunlong Song continue; 1846ab0e4800SYunlong Song } 1847ab0e4800SYunlong Song printf(" %-50s [%s]\n", evt_list[evt_i++], 1848ab0e4800SYunlong Song event_type_descriptors[PERF_TYPE_HW_CACHE]); 1849ab0e4800SYunlong Song } 1850dfc431cbSArnaldo Carvalho de Melo if (evt_num && pager_in_use()) 1851dc098b35SAndi Kleen printf("\n"); 1852ab0e4800SYunlong Song 1853ab0e4800SYunlong Song out_free: 1854ab0e4800SYunlong Song evt_num = evt_i; 1855ab0e4800SYunlong Song for (evt_i = 0; evt_i < evt_num; evt_i++) 1856ab0e4800SYunlong Song zfree(&evt_list[evt_i]); 1857ab0e4800SYunlong Song zfree(&evt_list); 1858ab0e4800SYunlong Song return evt_num; 1859ab0e4800SYunlong Song 1860ab0e4800SYunlong Song out_enomem: 1861ab0e4800SYunlong Song printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]); 1862ab0e4800SYunlong Song if (evt_list) 1863ab0e4800SYunlong Song goto out_free; 1864ab0e4800SYunlong Song return evt_num; 1865668b8788SArnaldo Carvalho de Melo } 1866668b8788SArnaldo Carvalho de Melo 1867705750f2SYunlong Song void print_symbol_events(const char *event_glob, unsigned type, 1868a3277d2dSFrederic Weisbecker struct event_symbol *syms, unsigned max, 1869a3277d2dSFrederic Weisbecker bool name_only) 187086470930SIngo Molnar { 1871ab0e4800SYunlong Song unsigned int i, evt_i = 0, evt_num = 0; 1872947b4ad1SIngo Molnar char name[MAX_NAME_LEN]; 1873ab0e4800SYunlong Song char **evt_list = NULL; 1874ab0e4800SYunlong Song bool evt_num_known = false; 1875ab0e4800SYunlong Song 1876ab0e4800SYunlong Song restart: 1877ab0e4800SYunlong Song if (evt_num_known) { 1878ab0e4800SYunlong Song evt_list = zalloc(sizeof(char *) * evt_num); 1879ab0e4800SYunlong Song if (!evt_list) 1880ab0e4800SYunlong Song goto out_enomem; 1881ab0e4800SYunlong Song syms -= max; 1882ab0e4800SYunlong Song } 188386470930SIngo Molnar 18841dc12760SJiri Olsa for (i = 0; i < max; i++, syms++) { 1885668b8788SArnaldo Carvalho de Melo 1886e37df6c7SArnaldo Carvalho de Melo if (event_glob != NULL && syms->symbol != NULL && 1887668b8788SArnaldo Carvalho de Melo !(strglobmatch(syms->symbol, event_glob) || 1888668b8788SArnaldo Carvalho de Melo (syms->alias && strglobmatch(syms->alias, event_glob)))) 1889668b8788SArnaldo Carvalho de Melo continue; 189086470930SIngo Molnar 1891b41f1cecSNamhyung Kim if (!is_event_supported(type, i)) 1892b41f1cecSNamhyung Kim continue; 1893b41f1cecSNamhyung Kim 1894ab0e4800SYunlong Song if (!evt_num_known) { 1895ab0e4800SYunlong Song evt_num++; 1896a3277d2dSFrederic Weisbecker continue; 1897a3277d2dSFrederic Weisbecker } 1898a3277d2dSFrederic Weisbecker 1899ab0e4800SYunlong Song if (!name_only && strlen(syms->alias)) 1900947b4ad1SIngo Molnar snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 190174d5b588SJaswinder Singh Rajput else 1902947b4ad1SIngo Molnar strncpy(name, syms->symbol, MAX_NAME_LEN); 190386470930SIngo Molnar 1904ab0e4800SYunlong Song evt_list[evt_i] = strdup(name); 1905ab0e4800SYunlong Song if (evt_list[evt_i] == NULL) 1906ab0e4800SYunlong Song goto out_enomem; 1907ab0e4800SYunlong Song evt_i++; 190886470930SIngo Molnar } 190986470930SIngo Molnar 1910ab0e4800SYunlong Song if (!evt_num_known) { 1911ab0e4800SYunlong Song evt_num_known = true; 1912ab0e4800SYunlong Song goto restart; 1913ab0e4800SYunlong Song } 1914ab0e4800SYunlong Song qsort(evt_list, evt_num, sizeof(char *), cmp_string); 1915ab0e4800SYunlong Song evt_i = 0; 1916ab0e4800SYunlong Song while (evt_i < evt_num) { 1917ab0e4800SYunlong Song if (name_only) { 1918ab0e4800SYunlong Song printf("%s ", evt_list[evt_i++]); 1919ab0e4800SYunlong Song continue; 1920ab0e4800SYunlong Song } 1921ab0e4800SYunlong Song printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); 1922ab0e4800SYunlong Song } 1923dfc431cbSArnaldo Carvalho de Melo if (evt_num && pager_in_use()) 1924689d3018SMarti Raudsepp printf("\n"); 1925ab0e4800SYunlong Song 1926ab0e4800SYunlong Song out_free: 1927ab0e4800SYunlong Song evt_num = evt_i; 1928ab0e4800SYunlong Song for (evt_i = 0; evt_i < evt_num; evt_i++) 1929ab0e4800SYunlong Song zfree(&evt_list[evt_i]); 1930ab0e4800SYunlong Song zfree(&evt_list); 1931ab0e4800SYunlong Song return; 1932ab0e4800SYunlong Song 1933ab0e4800SYunlong Song out_enomem: 1934ab0e4800SYunlong Song printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); 1935ab0e4800SYunlong Song if (evt_list) 1936ab0e4800SYunlong Song goto out_free; 1937668b8788SArnaldo Carvalho de Melo } 19381dc12760SJiri Olsa 19391dc12760SJiri Olsa /* 19401dc12760SJiri Olsa * Print the help text for the event symbols: 19411dc12760SJiri Olsa */ 1942a3277d2dSFrederic Weisbecker void print_events(const char *event_glob, bool name_only) 19431dc12760SJiri Olsa { 19441dc12760SJiri Olsa print_symbol_events(event_glob, PERF_TYPE_HARDWARE, 1945a3277d2dSFrederic Weisbecker event_symbols_hw, PERF_COUNT_HW_MAX, name_only); 19461dc12760SJiri Olsa 19471dc12760SJiri Olsa print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, 1948a3277d2dSFrederic Weisbecker event_symbols_sw, PERF_COUNT_SW_MAX, name_only); 19491dc12760SJiri Olsa 1950a3277d2dSFrederic Weisbecker print_hwcache_events(event_glob, name_only); 195173c24cb8SJaswinder Singh Rajput 1952dc098b35SAndi Kleen print_pmu_events(event_glob, name_only); 1953dc098b35SAndi Kleen 1954668b8788SArnaldo Carvalho de Melo if (event_glob != NULL) 1955668b8788SArnaldo Carvalho de Melo return; 195673c24cb8SJaswinder Singh Rajput 1957a3277d2dSFrederic Weisbecker if (!name_only) { 1958947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 19595f537a26SJiri Olsa "rNNN", 19601cf4a063SArnaldo Carvalho de Melo event_type_descriptors[PERF_TYPE_RAW]); 19615f537a26SJiri Olsa printf(" %-50s [%s]\n", 19625f537a26SJiri Olsa "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 19635f537a26SJiri Olsa event_type_descriptors[PERF_TYPE_RAW]); 1964dfc431cbSArnaldo Carvalho de Melo if (pager_in_use()) 1965dfc431cbSArnaldo Carvalho de Melo printf(" (see 'man perf-list' on how to encode it)\n\n"); 196686470930SIngo Molnar 1967947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 19683741eb9fSJacob Shin "mem:<addr>[/len][:access]", 196941bdcb23SLiming Wang event_type_descriptors[PERF_TYPE_BREAKPOINT]); 1970dfc431cbSArnaldo Carvalho de Melo if (pager_in_use()) 19711b290d67SFrederic Weisbecker printf("\n"); 1972a3277d2dSFrederic Weisbecker } 19731b290d67SFrederic Weisbecker 1974a3277d2dSFrederic Weisbecker print_tracepoint_events(NULL, NULL, name_only); 197586470930SIngo Molnar } 19768f707d84SJiri Olsa 19776cee6cd3SArnaldo Carvalho de Melo int parse_events__is_hardcoded_term(struct parse_events_term *term) 19788f707d84SJiri Olsa { 197916fa7e82SJiri Olsa return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; 19808f707d84SJiri Olsa } 19818f707d84SJiri Olsa 19826cee6cd3SArnaldo Carvalho de Melo static int new_term(struct parse_events_term **_term, int type_val, 198316fa7e82SJiri Olsa int type_term, char *config, 1984cecf3a2eSJiri Olsa char *str, u64 num, int err_term, int err_val) 19858f707d84SJiri Olsa { 19866cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 19878f707d84SJiri Olsa 19888f707d84SJiri Olsa term = zalloc(sizeof(*term)); 19898f707d84SJiri Olsa if (!term) 19908f707d84SJiri Olsa return -ENOMEM; 19918f707d84SJiri Olsa 19928f707d84SJiri Olsa INIT_LIST_HEAD(&term->list); 199316fa7e82SJiri Olsa term->type_val = type_val; 199416fa7e82SJiri Olsa term->type_term = type_term; 19958f707d84SJiri Olsa term->config = config; 1996cecf3a2eSJiri Olsa term->err_term = err_term; 1997cecf3a2eSJiri Olsa term->err_val = err_val; 19988f707d84SJiri Olsa 199916fa7e82SJiri Olsa switch (type_val) { 20008f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_NUM: 20018f707d84SJiri Olsa term->val.num = num; 20028f707d84SJiri Olsa break; 20038f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_STR: 20048f707d84SJiri Olsa term->val.str = str; 20058f707d84SJiri Olsa break; 20068f707d84SJiri Olsa default: 20074be8be6bSAdrian Hunter free(term); 20088f707d84SJiri Olsa return -EINVAL; 20098f707d84SJiri Olsa } 20108f707d84SJiri Olsa 20118f707d84SJiri Olsa *_term = term; 20128f707d84SJiri Olsa return 0; 20138f707d84SJiri Olsa } 20148f707d84SJiri Olsa 20156cee6cd3SArnaldo Carvalho de Melo int parse_events_term__num(struct parse_events_term **term, 2016cecf3a2eSJiri Olsa int type_term, char *config, u64 num, 2017bb78ce7dSAdrian Hunter void *loc_term_, void *loc_val_) 201816fa7e82SJiri Olsa { 2019bb78ce7dSAdrian Hunter YYLTYPE *loc_term = loc_term_; 2020bb78ce7dSAdrian Hunter YYLTYPE *loc_val = loc_val_; 2021bb78ce7dSAdrian Hunter 202216fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, 2023cecf3a2eSJiri Olsa config, NULL, num, 2024cecf3a2eSJiri Olsa loc_term ? loc_term->first_column : 0, 2025cecf3a2eSJiri Olsa loc_val ? loc_val->first_column : 0); 202616fa7e82SJiri Olsa } 202716fa7e82SJiri Olsa 20286cee6cd3SArnaldo Carvalho de Melo int parse_events_term__str(struct parse_events_term **term, 2029cecf3a2eSJiri Olsa int type_term, char *config, char *str, 2030bb78ce7dSAdrian Hunter void *loc_term_, void *loc_val_) 203116fa7e82SJiri Olsa { 2032bb78ce7dSAdrian Hunter YYLTYPE *loc_term = loc_term_; 2033bb78ce7dSAdrian Hunter YYLTYPE *loc_val = loc_val_; 2034bb78ce7dSAdrian Hunter 203516fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, 2036cecf3a2eSJiri Olsa config, str, 0, 2037cecf3a2eSJiri Olsa loc_term ? loc_term->first_column : 0, 2038cecf3a2eSJiri Olsa loc_val ? loc_val->first_column : 0); 203916fa7e82SJiri Olsa } 204016fa7e82SJiri Olsa 20416cee6cd3SArnaldo Carvalho de Melo int parse_events_term__sym_hw(struct parse_events_term **term, 20421d33d6dcSJiri Olsa char *config, unsigned idx) 20431d33d6dcSJiri Olsa { 20441d33d6dcSJiri Olsa struct event_symbol *sym; 20451d33d6dcSJiri Olsa 20461d33d6dcSJiri Olsa BUG_ON(idx >= PERF_COUNT_HW_MAX); 20471d33d6dcSJiri Olsa sym = &event_symbols_hw[idx]; 20481d33d6dcSJiri Olsa 20491d33d6dcSJiri Olsa if (config) 20501d33d6dcSJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 20511d33d6dcSJiri Olsa PARSE_EVENTS__TERM_TYPE_USER, config, 2052cecf3a2eSJiri Olsa (char *) sym->symbol, 0, 0, 0); 20531d33d6dcSJiri Olsa else 20541d33d6dcSJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 20551d33d6dcSJiri Olsa PARSE_EVENTS__TERM_TYPE_USER, 2056cecf3a2eSJiri Olsa (char *) "event", (char *) sym->symbol, 2057cecf3a2eSJiri Olsa 0, 0, 0); 20581d33d6dcSJiri Olsa } 20591d33d6dcSJiri Olsa 20606cee6cd3SArnaldo Carvalho de Melo int parse_events_term__clone(struct parse_events_term **new, 20616cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term) 2062a6146d50SZheng Yan { 2063a6146d50SZheng Yan return new_term(new, term->type_val, term->type_term, term->config, 2064cecf3a2eSJiri Olsa term->val.str, term->val.num, 2065cecf3a2eSJiri Olsa term->err_term, term->err_val); 2066a6146d50SZheng Yan } 2067a6146d50SZheng Yan 20688f707d84SJiri Olsa void parse_events__free_terms(struct list_head *terms) 20698f707d84SJiri Olsa { 20706cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term, *h; 20718f707d84SJiri Olsa 20728f707d84SJiri Olsa list_for_each_entry_safe(term, h, terms, list) 20738f707d84SJiri Olsa free(term); 20748f707d84SJiri Olsa } 2075b39b8393SJiri Olsa 2076b39b8393SJiri Olsa void parse_events_evlist_error(struct parse_events_evlist *data, 2077b39b8393SJiri Olsa int idx, const char *str) 2078b39b8393SJiri Olsa { 2079b39b8393SJiri Olsa struct parse_events_error *err = data->error; 2080b39b8393SJiri Olsa 2081a6ced2beSAdrian Hunter if (!err) 2082a6ced2beSAdrian Hunter return; 2083b39b8393SJiri Olsa err->idx = idx; 2084b39b8393SJiri Olsa err->str = strdup(str); 2085b39b8393SJiri Olsa WARN_ONCE(!err->str, "WARNING: failed to allocate error string"); 2086b39b8393SJiri Olsa } 2087ffeb883eSHe Kuang 2088ffeb883eSHe Kuang /* 2089ffeb883eSHe Kuang * Return string contains valid config terms of an event. 2090ffeb883eSHe Kuang * @additional_terms: For terms such as PMU sysfs terms. 2091ffeb883eSHe Kuang */ 2092ffeb883eSHe Kuang char *parse_events_formats_error_string(char *additional_terms) 2093ffeb883eSHe Kuang { 2094ffeb883eSHe Kuang char *str; 2095ffeb883eSHe Kuang static const char *static_terms = "config,config1,config2,name," 2096ffeb883eSHe Kuang "period,freq,branch_type,time," 2097ffeb883eSHe Kuang "call-graph,stack-size\n"; 2098ffeb883eSHe Kuang 2099ffeb883eSHe Kuang /* valid terms */ 2100ffeb883eSHe Kuang if (additional_terms) { 2101ffeb883eSHe Kuang if (!asprintf(&str, "valid terms: %s,%s", 2102ffeb883eSHe Kuang additional_terms, static_terms)) 2103ffeb883eSHe Kuang goto fail; 2104ffeb883eSHe Kuang } else { 2105ffeb883eSHe Kuang if (!asprintf(&str, "valid terms: %s", static_terms)) 2106ffeb883eSHe Kuang goto fail; 2107ffeb883eSHe Kuang } 2108ffeb883eSHe Kuang return str; 2109ffeb883eSHe Kuang 2110ffeb883eSHe Kuang fail: 2111ffeb883eSHe Kuang return NULL; 2112ffeb883eSHe Kuang } 2113