1d2709c7cSDavid Howells #include <linux/hw_breakpoint.h> 286470930SIngo Molnar #include "util.h" 36b58e7f1SUlrich Drepper #include "../perf.h" 4361c99a6SArnaldo Carvalho de Melo #include "evlist.h" 569aad6f1SArnaldo Carvalho de Melo #include "evsel.h" 686470930SIngo Molnar #include "parse-options.h" 786470930SIngo Molnar #include "parse-events.h" 886470930SIngo Molnar #include "exec_cmd.h" 942f60c2dSKan Liang #include "string.h" 105aab621bSArnaldo Carvalho de Melo #include "symbol.h" 115beeded1SJason Baron #include "cache.h" 128755a8f2SArjan van de Ven #include "header.h" 136e81c74cSMasami Hiramatsu #include "debug.h" 14553873e1SBorislav Petkov #include <api/fs/debugfs.h> 15ac20de6fSZheng Yan #include "parse-events-bison.h" 1690e2b22dSJiri Olsa #define YY_EXTRA_TYPE int 1789812fc8SJiri Olsa #include "parse-events-flex.h" 185f537a26SJiri Olsa #include "pmu.h" 19b41f1cecSNamhyung Kim #include "thread_map.h" 20f30a79b0SJiri Olsa #include "cpumap.h" 21b39b8393SJiri Olsa #include "asm/bug.h" 2289812fc8SJiri Olsa 2389812fc8SJiri Olsa #define MAX_NAME_LEN 100 2486470930SIngo Molnar 2582ba1f2fSJiri Olsa #ifdef PARSER_DEBUG 2682ba1f2fSJiri Olsa extern int parse_events_debug; 2782ba1f2fSJiri Olsa #endif 28ac20de6fSZheng Yan int parse_events_parse(void *data, void *scanner); 29bcd3279fSFrederic Weisbecker 30dcb4e102SKan Liang static struct perf_pmu_event_symbol *perf_pmu_events_list; 31dcb4e102SKan Liang /* 32dcb4e102SKan Liang * The variable indicates the number of supported pmu event symbols. 33dcb4e102SKan Liang * 0 means not initialized and ready to init 34dcb4e102SKan Liang * -1 means failed to init, don't try anymore 35dcb4e102SKan Liang * >0 is the number of supported pmu event symbols 36dcb4e102SKan Liang */ 37dcb4e102SKan Liang static int perf_pmu_events_list_num; 38dcb4e102SKan Liang 39705750f2SYunlong Song struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = { 401dc12760SJiri Olsa [PERF_COUNT_HW_CPU_CYCLES] = { 411dc12760SJiri Olsa .symbol = "cpu-cycles", 421dc12760SJiri Olsa .alias = "cycles", 431dc12760SJiri Olsa }, 441dc12760SJiri Olsa [PERF_COUNT_HW_INSTRUCTIONS] = { 451dc12760SJiri Olsa .symbol = "instructions", 461dc12760SJiri Olsa .alias = "", 471dc12760SJiri Olsa }, 481dc12760SJiri Olsa [PERF_COUNT_HW_CACHE_REFERENCES] = { 491dc12760SJiri Olsa .symbol = "cache-references", 501dc12760SJiri Olsa .alias = "", 511dc12760SJiri Olsa }, 521dc12760SJiri Olsa [PERF_COUNT_HW_CACHE_MISSES] = { 531dc12760SJiri Olsa .symbol = "cache-misses", 541dc12760SJiri Olsa .alias = "", 551dc12760SJiri Olsa }, 561dc12760SJiri Olsa [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 571dc12760SJiri Olsa .symbol = "branch-instructions", 581dc12760SJiri Olsa .alias = "branches", 591dc12760SJiri Olsa }, 601dc12760SJiri Olsa [PERF_COUNT_HW_BRANCH_MISSES] = { 611dc12760SJiri Olsa .symbol = "branch-misses", 621dc12760SJiri Olsa .alias = "", 631dc12760SJiri Olsa }, 641dc12760SJiri Olsa [PERF_COUNT_HW_BUS_CYCLES] = { 651dc12760SJiri Olsa .symbol = "bus-cycles", 661dc12760SJiri Olsa .alias = "", 671dc12760SJiri Olsa }, 681dc12760SJiri Olsa [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = { 691dc12760SJiri Olsa .symbol = "stalled-cycles-frontend", 701dc12760SJiri Olsa .alias = "idle-cycles-frontend", 711dc12760SJiri Olsa }, 721dc12760SJiri Olsa [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = { 731dc12760SJiri Olsa .symbol = "stalled-cycles-backend", 741dc12760SJiri Olsa .alias = "idle-cycles-backend", 751dc12760SJiri Olsa }, 761dc12760SJiri Olsa [PERF_COUNT_HW_REF_CPU_CYCLES] = { 771dc12760SJiri Olsa .symbol = "ref-cycles", 781dc12760SJiri Olsa .alias = "", 791dc12760SJiri Olsa }, 801dc12760SJiri Olsa }; 8186470930SIngo Molnar 82705750f2SYunlong Song struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { 831dc12760SJiri Olsa [PERF_COUNT_SW_CPU_CLOCK] = { 841dc12760SJiri Olsa .symbol = "cpu-clock", 851dc12760SJiri Olsa .alias = "", 861dc12760SJiri Olsa }, 871dc12760SJiri Olsa [PERF_COUNT_SW_TASK_CLOCK] = { 881dc12760SJiri Olsa .symbol = "task-clock", 891dc12760SJiri Olsa .alias = "", 901dc12760SJiri Olsa }, 911dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS] = { 921dc12760SJiri Olsa .symbol = "page-faults", 931dc12760SJiri Olsa .alias = "faults", 941dc12760SJiri Olsa }, 951dc12760SJiri Olsa [PERF_COUNT_SW_CONTEXT_SWITCHES] = { 961dc12760SJiri Olsa .symbol = "context-switches", 971dc12760SJiri Olsa .alias = "cs", 981dc12760SJiri Olsa }, 991dc12760SJiri Olsa [PERF_COUNT_SW_CPU_MIGRATIONS] = { 1001dc12760SJiri Olsa .symbol = "cpu-migrations", 1011dc12760SJiri Olsa .alias = "migrations", 1021dc12760SJiri Olsa }, 1031dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS_MIN] = { 1041dc12760SJiri Olsa .symbol = "minor-faults", 1051dc12760SJiri Olsa .alias = "", 1061dc12760SJiri Olsa }, 1071dc12760SJiri Olsa [PERF_COUNT_SW_PAGE_FAULTS_MAJ] = { 1081dc12760SJiri Olsa .symbol = "major-faults", 1091dc12760SJiri Olsa .alias = "", 1101dc12760SJiri Olsa }, 1111dc12760SJiri Olsa [PERF_COUNT_SW_ALIGNMENT_FAULTS] = { 1121dc12760SJiri Olsa .symbol = "alignment-faults", 1131dc12760SJiri Olsa .alias = "", 1141dc12760SJiri Olsa }, 1151dc12760SJiri Olsa [PERF_COUNT_SW_EMULATION_FAULTS] = { 1161dc12760SJiri Olsa .symbol = "emulation-faults", 1171dc12760SJiri Olsa .alias = "", 1181dc12760SJiri Olsa }, 119d22d1a2aSAdrian Hunter [PERF_COUNT_SW_DUMMY] = { 120d22d1a2aSAdrian Hunter .symbol = "dummy", 121d22d1a2aSAdrian Hunter .alias = "", 122d22d1a2aSAdrian Hunter }, 12386470930SIngo Molnar }; 12486470930SIngo Molnar 125cdd6c482SIngo Molnar #define __PERF_EVENT_FIELD(config, name) \ 126cdd6c482SIngo Molnar ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 12786470930SIngo Molnar 128cdd6c482SIngo Molnar #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 129cdd6c482SIngo Molnar #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 130cdd6c482SIngo Molnar #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 131cdd6c482SIngo Molnar #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 13286470930SIngo Molnar 1336b58e7f1SUlrich Drepper #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 134f6bdafefSJason Baron while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 1356b58e7f1SUlrich Drepper if (sys_dirent.d_type == DT_DIR && \ 136f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".")) && \ 137f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".."))) 138f6bdafefSJason Baron 139ae07b63fSPeter Zijlstra static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 140ae07b63fSPeter Zijlstra { 141ae07b63fSPeter Zijlstra char evt_path[MAXPATHLEN]; 142ae07b63fSPeter Zijlstra int fd; 143ae07b63fSPeter Zijlstra 144ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path, 145ae07b63fSPeter Zijlstra sys_dir->d_name, evt_dir->d_name); 146ae07b63fSPeter Zijlstra fd = open(evt_path, O_RDONLY); 147ae07b63fSPeter Zijlstra if (fd < 0) 148ae07b63fSPeter Zijlstra return -EINVAL; 149ae07b63fSPeter Zijlstra close(fd); 150ae07b63fSPeter Zijlstra 151ae07b63fSPeter Zijlstra return 0; 152ae07b63fSPeter Zijlstra } 153ae07b63fSPeter Zijlstra 1546b58e7f1SUlrich Drepper #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ 155f6bdafefSJason Baron while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 1566b58e7f1SUlrich Drepper if (evt_dirent.d_type == DT_DIR && \ 157f6bdafefSJason Baron (strcmp(evt_dirent.d_name, ".")) && \ 158ae07b63fSPeter Zijlstra (strcmp(evt_dirent.d_name, "..")) && \ 159ae07b63fSPeter Zijlstra (!tp_event_has_id(&sys_dirent, &evt_dirent))) 160f6bdafefSJason Baron 161270bbbe8SLi Zefan #define MAX_EVENT_LENGTH 512 162f6bdafefSJason Baron 163f6bdafefSJason Baron 1641ef2ed10SFrederic Weisbecker struct tracepoint_path *tracepoint_id_to_path(u64 config) 165f6bdafefSJason Baron { 1661ef2ed10SFrederic Weisbecker struct tracepoint_path *path = NULL; 167f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 168f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1698aa8a7c8SStephane Eranian char id_buf[24]; 170725b1368SEric Dumazet int fd; 171f6bdafefSJason Baron u64 id; 172f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 173725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 174f6bdafefSJason Baron 175ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 176f6bdafefSJason Baron if (!sys_dir) 177725b1368SEric Dumazet return NULL; 178f6bdafefSJason Baron 1796b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 180725b1368SEric Dumazet 181ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 182725b1368SEric Dumazet sys_dirent.d_name); 183725b1368SEric Dumazet evt_dir = opendir(dir_path); 184725b1368SEric Dumazet if (!evt_dir) 1856b58e7f1SUlrich Drepper continue; 186725b1368SEric Dumazet 1876b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 188725b1368SEric Dumazet 189725b1368SEric Dumazet snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 190f6bdafefSJason Baron evt_dirent.d_name); 191725b1368SEric Dumazet fd = open(evt_path, O_RDONLY); 192f6bdafefSJason Baron if (fd < 0) 193f6bdafefSJason Baron continue; 194f6bdafefSJason Baron if (read(fd, id_buf, sizeof(id_buf)) < 0) { 195f6bdafefSJason Baron close(fd); 196f6bdafefSJason Baron continue; 197f6bdafefSJason Baron } 198f6bdafefSJason Baron close(fd); 199f6bdafefSJason Baron id = atoll(id_buf); 200f6bdafefSJason Baron if (id == config) { 201f6bdafefSJason Baron closedir(evt_dir); 202f6bdafefSJason Baron closedir(sys_dir); 20359b4caebSJulia Lawall path = zalloc(sizeof(*path)); 2041ef2ed10SFrederic Weisbecker path->system = malloc(MAX_EVENT_LENGTH); 2051ef2ed10SFrederic Weisbecker if (!path->system) { 2061ef2ed10SFrederic Weisbecker free(path); 2071ef2ed10SFrederic Weisbecker return NULL; 2081ef2ed10SFrederic Weisbecker } 2091ef2ed10SFrederic Weisbecker path->name = malloc(MAX_EVENT_LENGTH); 2101ef2ed10SFrederic Weisbecker if (!path->name) { 21174cf249dSArnaldo Carvalho de Melo zfree(&path->system); 2121ef2ed10SFrederic Weisbecker free(path); 2131ef2ed10SFrederic Weisbecker return NULL; 2141ef2ed10SFrederic Weisbecker } 2151ef2ed10SFrederic Weisbecker strncpy(path->system, sys_dirent.d_name, 2161ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2171ef2ed10SFrederic Weisbecker strncpy(path->name, evt_dirent.d_name, 2181ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2191ef2ed10SFrederic Weisbecker return path; 220f6bdafefSJason Baron } 221f6bdafefSJason Baron } 222f6bdafefSJason Baron closedir(evt_dir); 223f6bdafefSJason Baron } 224f6bdafefSJason Baron 225f6bdafefSJason Baron closedir(sys_dir); 2261ef2ed10SFrederic Weisbecker return NULL; 2271ef2ed10SFrederic Weisbecker } 2281ef2ed10SFrederic Weisbecker 229e7c93f09SNamhyung Kim struct tracepoint_path *tracepoint_name_to_path(const char *name) 230e7c93f09SNamhyung Kim { 231e7c93f09SNamhyung Kim struct tracepoint_path *path = zalloc(sizeof(*path)); 232e7c93f09SNamhyung Kim char *str = strchr(name, ':'); 233e7c93f09SNamhyung Kim 234e7c93f09SNamhyung Kim if (path == NULL || str == NULL) { 235e7c93f09SNamhyung Kim free(path); 236e7c93f09SNamhyung Kim return NULL; 237e7c93f09SNamhyung Kim } 238e7c93f09SNamhyung Kim 239e7c93f09SNamhyung Kim path->system = strndup(name, str - name); 240e7c93f09SNamhyung Kim path->name = strdup(str+1); 241e7c93f09SNamhyung Kim 242e7c93f09SNamhyung Kim if (path->system == NULL || path->name == NULL) { 24374cf249dSArnaldo Carvalho de Melo zfree(&path->system); 24474cf249dSArnaldo Carvalho de Melo zfree(&path->name); 245e7c93f09SNamhyung Kim free(path); 246e7c93f09SNamhyung Kim path = NULL; 247e7c93f09SNamhyung Kim } 248e7c93f09SNamhyung Kim 249e7c93f09SNamhyung Kim return path; 250e7c93f09SNamhyung Kim } 251e7c93f09SNamhyung Kim 2521424dc96SDavid Ahern const char *event_type(int type) 2531424dc96SDavid Ahern { 2541424dc96SDavid Ahern switch (type) { 2551424dc96SDavid Ahern case PERF_TYPE_HARDWARE: 2561424dc96SDavid Ahern return "hardware"; 2571424dc96SDavid Ahern 2581424dc96SDavid Ahern case PERF_TYPE_SOFTWARE: 2591424dc96SDavid Ahern return "software"; 2601424dc96SDavid Ahern 2611424dc96SDavid Ahern case PERF_TYPE_TRACEPOINT: 2621424dc96SDavid Ahern return "tracepoint"; 2631424dc96SDavid Ahern 2641424dc96SDavid Ahern case PERF_TYPE_HW_CACHE: 2651424dc96SDavid Ahern return "hardware-cache"; 2661424dc96SDavid Ahern 2671424dc96SDavid Ahern default: 2681424dc96SDavid Ahern break; 2691424dc96SDavid Ahern } 2701424dc96SDavid Ahern 2711424dc96SDavid Ahern return "unknown"; 2721424dc96SDavid Ahern } 2731424dc96SDavid Ahern 2747ae92e74SYan, Zheng 2757ae92e74SYan, Zheng 276410136f5SStephane Eranian static struct perf_evsel * 277410136f5SStephane Eranian __add_event(struct list_head *list, int *idx, 2787ae92e74SYan, Zheng struct perf_event_attr *attr, 279930a2e29SJiri Olsa char *name, struct cpu_map *cpus, 280930a2e29SJiri Olsa struct list_head *config_terms) 28189812fc8SJiri Olsa { 28289812fc8SJiri Olsa struct perf_evsel *evsel; 28389812fc8SJiri Olsa 28489812fc8SJiri Olsa event_attr_init(attr); 28589812fc8SJiri Olsa 286ef503831SArnaldo Carvalho de Melo evsel = perf_evsel__new_idx(attr, (*idx)++); 287c5cd8ac0SDavid Ahern if (!evsel) 288410136f5SStephane Eranian return NULL; 28989812fc8SJiri Olsa 290f30a79b0SJiri Olsa if (cpus) 291f30a79b0SJiri Olsa evsel->cpus = cpu_map__get(cpus); 292f30a79b0SJiri Olsa 2939db1763cSArnaldo Carvalho de Melo if (name) 29489812fc8SJiri Olsa evsel->name = strdup(name); 295930a2e29SJiri Olsa 296930a2e29SJiri Olsa if (config_terms) 297930a2e29SJiri Olsa list_splice(config_terms, &evsel->config_terms); 298930a2e29SJiri Olsa 299b847cbdcSJiri Olsa list_add_tail(&evsel->node, list); 300410136f5SStephane Eranian return evsel; 30189812fc8SJiri Olsa } 30289812fc8SJiri Olsa 303c5cd8ac0SDavid Ahern static int add_event(struct list_head *list, int *idx, 304930a2e29SJiri Olsa struct perf_event_attr *attr, char *name, 305930a2e29SJiri Olsa struct list_head *config_terms) 3067ae92e74SYan, Zheng { 307930a2e29SJiri Olsa return __add_event(list, idx, attr, name, NULL, config_terms) ? 0 : -ENOMEM; 3087ae92e74SYan, Zheng } 3097ae92e74SYan, Zheng 3100b668bc9SArnaldo Carvalho de Melo static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) 31186470930SIngo Molnar { 31286470930SIngo Molnar int i, j; 31361c45981SPaul Mackerras int n, longest = -1; 31486470930SIngo Molnar 31586470930SIngo Molnar for (i = 0; i < size; i++) { 3160b668bc9SArnaldo Carvalho de Melo for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) { 31761c45981SPaul Mackerras n = strlen(names[i][j]); 31889812fc8SJiri Olsa if (n > longest && !strncasecmp(str, names[i][j], n)) 31961c45981SPaul Mackerras longest = n; 32061c45981SPaul Mackerras } 32189812fc8SJiri Olsa if (longest > 0) 32286470930SIngo Molnar return i; 32386470930SIngo Molnar } 32486470930SIngo Molnar 3258953645fSIngo Molnar return -1; 32686470930SIngo Molnar } 32786470930SIngo Molnar 328c5cd8ac0SDavid Ahern int parse_events_add_cache(struct list_head *list, int *idx, 32989812fc8SJiri Olsa char *type, char *op_result1, char *op_result2) 33086470930SIngo Molnar { 33189812fc8SJiri Olsa struct perf_event_attr attr; 33289812fc8SJiri Olsa char name[MAX_NAME_LEN]; 33361c45981SPaul Mackerras int cache_type = -1, cache_op = -1, cache_result = -1; 33489812fc8SJiri Olsa char *op_result[2] = { op_result1, op_result2 }; 33589812fc8SJiri Olsa int i, n; 33686470930SIngo Molnar 33786470930SIngo Molnar /* 33886470930SIngo Molnar * No fallback - if we cannot get a clear cache type 33986470930SIngo Molnar * then bail out: 34086470930SIngo Molnar */ 3410b668bc9SArnaldo Carvalho de Melo cache_type = parse_aliases(type, perf_evsel__hw_cache, 34289812fc8SJiri Olsa PERF_COUNT_HW_CACHE_MAX); 34386470930SIngo Molnar if (cache_type == -1) 34489812fc8SJiri Olsa return -EINVAL; 34586470930SIngo Molnar 34689812fc8SJiri Olsa n = snprintf(name, MAX_NAME_LEN, "%s", type); 34789812fc8SJiri Olsa 34889812fc8SJiri Olsa for (i = 0; (i < 2) && (op_result[i]); i++) { 34989812fc8SJiri Olsa char *str = op_result[i]; 35089812fc8SJiri Olsa 351275ef387SJiri Olsa n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str); 35261c45981SPaul Mackerras 35361c45981SPaul Mackerras if (cache_op == -1) { 3540b668bc9SArnaldo Carvalho de Melo cache_op = parse_aliases(str, perf_evsel__hw_cache_op, 35561c45981SPaul Mackerras PERF_COUNT_HW_CACHE_OP_MAX); 35661c45981SPaul Mackerras if (cache_op >= 0) { 3570b668bc9SArnaldo Carvalho de Melo if (!perf_evsel__is_cache_op_valid(cache_type, cache_op)) 35889812fc8SJiri Olsa return -EINVAL; 35961c45981SPaul Mackerras continue; 36061c45981SPaul Mackerras } 36161c45981SPaul Mackerras } 36261c45981SPaul Mackerras 36361c45981SPaul Mackerras if (cache_result == -1) { 3640b668bc9SArnaldo Carvalho de Melo cache_result = parse_aliases(str, perf_evsel__hw_cache_result, 36561c45981SPaul Mackerras PERF_COUNT_HW_CACHE_RESULT_MAX); 36661c45981SPaul Mackerras if (cache_result >= 0) 36761c45981SPaul Mackerras continue; 36861c45981SPaul Mackerras } 36961c45981SPaul Mackerras } 37061c45981SPaul Mackerras 37186470930SIngo Molnar /* 37286470930SIngo Molnar * Fall back to reads: 37386470930SIngo Molnar */ 3748953645fSIngo Molnar if (cache_op == -1) 3758953645fSIngo Molnar cache_op = PERF_COUNT_HW_CACHE_OP_READ; 37686470930SIngo Molnar 37786470930SIngo Molnar /* 37886470930SIngo Molnar * Fall back to accesses: 37986470930SIngo Molnar */ 38086470930SIngo Molnar if (cache_result == -1) 38186470930SIngo Molnar cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 38286470930SIngo Molnar 38389812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 38489812fc8SJiri Olsa attr.config = cache_type | (cache_op << 8) | (cache_result << 16); 38589812fc8SJiri Olsa attr.type = PERF_TYPE_HW_CACHE; 386930a2e29SJiri Olsa return add_event(list, idx, &attr, name, NULL); 38786470930SIngo Molnar } 38886470930SIngo Molnar 389c5cd8ac0SDavid Ahern static int add_tracepoint(struct list_head *list, int *idx, 39089812fc8SJiri Olsa char *sys_name, char *evt_name) 391bcd3279fSFrederic Weisbecker { 39282fe1c29SArnaldo Carvalho de Melo struct perf_evsel *evsel; 393bcd3279fSFrederic Weisbecker 394ef503831SArnaldo Carvalho de Melo evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++); 395c5cd8ac0SDavid Ahern if (!evsel) 39682fe1c29SArnaldo Carvalho de Melo return -ENOMEM; 397bcd3279fSFrederic Weisbecker 39882fe1c29SArnaldo Carvalho de Melo list_add_tail(&evsel->node, list); 399c5cd8ac0SDavid Ahern 40082fe1c29SArnaldo Carvalho de Melo return 0; 401bcd3279fSFrederic Weisbecker } 402bcd3279fSFrederic Weisbecker 403c5cd8ac0SDavid Ahern static int add_tracepoint_multi_event(struct list_head *list, int *idx, 40489812fc8SJiri Olsa char *sys_name, char *evt_name) 405bcd3279fSFrederic Weisbecker { 406bcd3279fSFrederic Weisbecker char evt_path[MAXPATHLEN]; 407bcd3279fSFrederic Weisbecker struct dirent *evt_ent; 408bcd3279fSFrederic Weisbecker DIR *evt_dir; 40989812fc8SJiri Olsa int ret = 0; 410bcd3279fSFrederic Weisbecker 411ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); 412bcd3279fSFrederic Weisbecker evt_dir = opendir(evt_path); 413bcd3279fSFrederic Weisbecker if (!evt_dir) { 414bcd3279fSFrederic Weisbecker perror("Can't open event dir"); 41589812fc8SJiri Olsa return -1; 416bcd3279fSFrederic Weisbecker } 417bcd3279fSFrederic Weisbecker 41889812fc8SJiri Olsa while (!ret && (evt_ent = readdir(evt_dir))) { 419bcd3279fSFrederic Weisbecker if (!strcmp(evt_ent->d_name, ".") 420bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "..") 421bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "enable") 422bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "filter")) 423bcd3279fSFrederic Weisbecker continue; 424bcd3279fSFrederic Weisbecker 42589812fc8SJiri Olsa if (!strglobmatch(evt_ent->d_name, evt_name)) 426fb1d2edfSMasami Hiramatsu continue; 427fb1d2edfSMasami Hiramatsu 42889812fc8SJiri Olsa ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name); 429bcd3279fSFrederic Weisbecker } 430bcd3279fSFrederic Weisbecker 4310bd3f084SJiri Olsa closedir(evt_dir); 43289812fc8SJiri Olsa return ret; 433bcd3279fSFrederic Weisbecker } 434bcd3279fSFrederic Weisbecker 435c5cd8ac0SDavid Ahern static int add_tracepoint_event(struct list_head *list, int *idx, 436f35488f9SJiri Olsa char *sys_name, char *evt_name) 437f35488f9SJiri Olsa { 438f35488f9SJiri Olsa return strpbrk(evt_name, "*?") ? 439f35488f9SJiri Olsa add_tracepoint_multi_event(list, idx, sys_name, evt_name) : 440f35488f9SJiri Olsa add_tracepoint(list, idx, sys_name, evt_name); 441f35488f9SJiri Olsa } 442f35488f9SJiri Olsa 443c5cd8ac0SDavid Ahern static int add_tracepoint_multi_sys(struct list_head *list, int *idx, 444f35488f9SJiri Olsa char *sys_name, char *evt_name) 445f35488f9SJiri Olsa { 446f35488f9SJiri Olsa struct dirent *events_ent; 447f35488f9SJiri Olsa DIR *events_dir; 448f35488f9SJiri Olsa int ret = 0; 449f35488f9SJiri Olsa 450f35488f9SJiri Olsa events_dir = opendir(tracing_events_path); 451f35488f9SJiri Olsa if (!events_dir) { 452f35488f9SJiri Olsa perror("Can't open event dir"); 453f35488f9SJiri Olsa return -1; 454f35488f9SJiri Olsa } 455f35488f9SJiri Olsa 456f35488f9SJiri Olsa while (!ret && (events_ent = readdir(events_dir))) { 457f35488f9SJiri Olsa if (!strcmp(events_ent->d_name, ".") 458f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "..") 459f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "enable") 460f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "header_event") 461f35488f9SJiri Olsa || !strcmp(events_ent->d_name, "header_page")) 462f35488f9SJiri Olsa continue; 463f35488f9SJiri Olsa 464f35488f9SJiri Olsa if (!strglobmatch(events_ent->d_name, sys_name)) 465f35488f9SJiri Olsa continue; 466f35488f9SJiri Olsa 467f35488f9SJiri Olsa ret = add_tracepoint_event(list, idx, events_ent->d_name, 468f35488f9SJiri Olsa evt_name); 469f35488f9SJiri Olsa } 470f35488f9SJiri Olsa 471f35488f9SJiri Olsa closedir(events_dir); 472f35488f9SJiri Olsa return ret; 473f35488f9SJiri Olsa } 474f35488f9SJiri Olsa 475c5cd8ac0SDavid Ahern int parse_events_add_tracepoint(struct list_head *list, int *idx, 47689812fc8SJiri Olsa char *sys, char *event) 477f6bdafefSJason Baron { 478f35488f9SJiri Olsa if (strpbrk(sys, "*?")) 479f35488f9SJiri Olsa return add_tracepoint_multi_sys(list, idx, sys, event); 480f35488f9SJiri Olsa else 481f35488f9SJiri Olsa return add_tracepoint_event(list, idx, sys, event); 4823a9f131fSFrederic Weisbecker } 4833a9f131fSFrederic Weisbecker 48489812fc8SJiri Olsa static int 48589812fc8SJiri Olsa parse_breakpoint_type(const char *type, struct perf_event_attr *attr) 4861b290d67SFrederic Weisbecker { 4871b290d67SFrederic Weisbecker int i; 4881b290d67SFrederic Weisbecker 4891b290d67SFrederic Weisbecker for (i = 0; i < 3; i++) { 49089812fc8SJiri Olsa if (!type || !type[i]) 4911b290d67SFrederic Weisbecker break; 4921b290d67SFrederic Weisbecker 4937582732fSJiri Olsa #define CHECK_SET_TYPE(bit) \ 4947582732fSJiri Olsa do { \ 4957582732fSJiri Olsa if (attr->bp_type & bit) \ 4967582732fSJiri Olsa return -EINVAL; \ 4977582732fSJiri Olsa else \ 4987582732fSJiri Olsa attr->bp_type |= bit; \ 4997582732fSJiri Olsa } while (0) 5007582732fSJiri Olsa 5011b290d67SFrederic Weisbecker switch (type[i]) { 5021b290d67SFrederic Weisbecker case 'r': 5037582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_R); 5041b290d67SFrederic Weisbecker break; 5051b290d67SFrederic Weisbecker case 'w': 5067582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_W); 5071b290d67SFrederic Weisbecker break; 5081b290d67SFrederic Weisbecker case 'x': 5097582732fSJiri Olsa CHECK_SET_TYPE(HW_BREAKPOINT_X); 5101b290d67SFrederic Weisbecker break; 5111b290d67SFrederic Weisbecker default: 51289812fc8SJiri Olsa return -EINVAL; 5131b290d67SFrederic Weisbecker } 5141b290d67SFrederic Weisbecker } 51589812fc8SJiri Olsa 5167582732fSJiri Olsa #undef CHECK_SET_TYPE 5177582732fSJiri Olsa 5181b290d67SFrederic Weisbecker if (!attr->bp_type) /* Default */ 5191b290d67SFrederic Weisbecker attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 5201b290d67SFrederic Weisbecker 52189812fc8SJiri Olsa return 0; 5221b290d67SFrederic Weisbecker } 5231b290d67SFrederic Weisbecker 524c5cd8ac0SDavid Ahern int parse_events_add_breakpoint(struct list_head *list, int *idx, 5253741eb9fSJacob Shin void *ptr, char *type, u64 len) 5261b290d67SFrederic Weisbecker { 52789812fc8SJiri Olsa struct perf_event_attr attr; 5281b290d67SFrederic Weisbecker 52989812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 5309fafd98fSJiri Olsa attr.bp_addr = (unsigned long) ptr; 5311b290d67SFrederic Weisbecker 53289812fc8SJiri Olsa if (parse_breakpoint_type(type, &attr)) 53389812fc8SJiri Olsa return -EINVAL; 5341b290d67SFrederic Weisbecker 5353741eb9fSJacob Shin /* Provide some defaults if len is not specified */ 5363741eb9fSJacob Shin if (!len) { 53789812fc8SJiri Olsa if (attr.bp_type == HW_BREAKPOINT_X) 5383741eb9fSJacob Shin len = sizeof(long); 539aa59a485SFrederic Weisbecker else 5403741eb9fSJacob Shin len = HW_BREAKPOINT_LEN_4; 5413741eb9fSJacob Shin } 5423741eb9fSJacob Shin 5433741eb9fSJacob Shin attr.bp_len = len; 544aa59a485SFrederic Weisbecker 54589812fc8SJiri Olsa attr.type = PERF_TYPE_BREAKPOINT; 5464a841d65SJovi Zhang attr.sample_period = 1; 5471b290d67SFrederic Weisbecker 548930a2e29SJiri Olsa return add_event(list, idx, &attr, NULL, NULL); 5491b290d67SFrederic Weisbecker } 5501b290d67SFrederic Weisbecker 5513b0e371cSJiri Olsa static int check_type_val(struct parse_events_term *term, 5523b0e371cSJiri Olsa struct parse_events_error *err, 5533b0e371cSJiri Olsa int type) 5543b0e371cSJiri Olsa { 5553b0e371cSJiri Olsa if (type == term->type_val) 5563b0e371cSJiri Olsa return 0; 5573b0e371cSJiri Olsa 5583b0e371cSJiri Olsa if (err) { 5593b0e371cSJiri Olsa err->idx = term->err_val; 5603b0e371cSJiri Olsa if (type == PARSE_EVENTS__TERM_TYPE_NUM) 5613b0e371cSJiri Olsa err->str = strdup("expected numeric value"); 5623b0e371cSJiri Olsa else 5633b0e371cSJiri Olsa err->str = strdup("expected string value"); 5643b0e371cSJiri Olsa } 5653b0e371cSJiri Olsa return -EINVAL; 5663b0e371cSJiri Olsa } 5673b0e371cSJiri Olsa 5688f707d84SJiri Olsa static int config_term(struct perf_event_attr *attr, 5693b0e371cSJiri Olsa struct parse_events_term *term, 5703b0e371cSJiri Olsa struct parse_events_error *err) 5718f707d84SJiri Olsa { 57216fa7e82SJiri Olsa #define CHECK_TYPE_VAL(type) \ 57316fa7e82SJiri Olsa do { \ 5743b0e371cSJiri Olsa if (check_type_val(term, err, PARSE_EVENTS__TERM_TYPE_ ## type)) \ 57516fa7e82SJiri Olsa return -EINVAL; \ 57616fa7e82SJiri Olsa } while (0) 57716fa7e82SJiri Olsa 57816fa7e82SJiri Olsa switch (term->type_term) { 579c056ba6aSJiri Olsa case PARSE_EVENTS__TERM_TYPE_USER: 580c056ba6aSJiri Olsa /* 581c056ba6aSJiri Olsa * Always succeed for sysfs terms, as we dont know 582c056ba6aSJiri Olsa * at this point what type they need to have. 583c056ba6aSJiri Olsa */ 584c056ba6aSJiri Olsa return 0; 5858f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG: 58616fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5878f707d84SJiri Olsa attr->config = term->val.num; 5888f707d84SJiri Olsa break; 5898f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG1: 59016fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5918f707d84SJiri Olsa attr->config1 = term->val.num; 5928f707d84SJiri Olsa break; 5938f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG2: 59416fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5958f707d84SJiri Olsa attr->config2 = term->val.num; 5968f707d84SJiri Olsa break; 5978f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 59816fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 5998f707d84SJiri Olsa break; 60009af2a55SNamhyung Kim case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ: 60109af2a55SNamhyung Kim CHECK_TYPE_VAL(NUM); 60209af2a55SNamhyung Kim break; 6038f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: 6048f707d84SJiri Olsa /* 6058f707d84SJiri Olsa * TODO uncomment when the field is available 6068f707d84SJiri Olsa * attr->branch_sample_type = term->val.num; 6078f707d84SJiri Olsa */ 6088f707d84SJiri Olsa break; 60932067712SKan Liang case PARSE_EVENTS__TERM_TYPE_TIME: 61032067712SKan Liang CHECK_TYPE_VAL(NUM); 61132067712SKan Liang if (term->val.num > 1) { 61232067712SKan Liang err->str = strdup("expected 0 or 1"); 61332067712SKan Liang err->idx = term->err_val; 61432067712SKan Liang return -EINVAL; 61532067712SKan Liang } 61632067712SKan Liang break; 617d457c963SKan Liang case PARSE_EVENTS__TERM_TYPE_CALLGRAPH: 618d457c963SKan Liang CHECK_TYPE_VAL(STR); 619d457c963SKan Liang break; 620d457c963SKan Liang case PARSE_EVENTS__TERM_TYPE_STACKSIZE: 621d457c963SKan Liang CHECK_TYPE_VAL(NUM); 622d457c963SKan Liang break; 6236b5fc39bSJiri Olsa case PARSE_EVENTS__TERM_TYPE_NAME: 6246b5fc39bSJiri Olsa CHECK_TYPE_VAL(STR); 6256b5fc39bSJiri Olsa break; 6268f707d84SJiri Olsa default: 6278f707d84SJiri Olsa return -EINVAL; 6288f707d84SJiri Olsa } 62916fa7e82SJiri Olsa 6308f707d84SJiri Olsa return 0; 63116fa7e82SJiri Olsa #undef CHECK_TYPE_VAL 6328f707d84SJiri Olsa } 6338f707d84SJiri Olsa 6348f707d84SJiri Olsa static int config_attr(struct perf_event_attr *attr, 6353b0e371cSJiri Olsa struct list_head *head, 6363b0e371cSJiri Olsa struct parse_events_error *err) 6378f707d84SJiri Olsa { 6386cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 6398f707d84SJiri Olsa 6408f707d84SJiri Olsa list_for_each_entry(term, head, list) 6413b0e371cSJiri Olsa if (config_term(attr, term, err)) 6428f707d84SJiri Olsa return -EINVAL; 6438f707d84SJiri Olsa 6448f707d84SJiri Olsa return 0; 6458f707d84SJiri Olsa } 6468f707d84SJiri Olsa 647930a2e29SJiri Olsa static int get_config_terms(struct list_head *head_config, 648930a2e29SJiri Olsa struct list_head *head_terms __maybe_unused) 649930a2e29SJiri Olsa { 650930a2e29SJiri Olsa #define ADD_CONFIG_TERM(__type, __name, __val) \ 651930a2e29SJiri Olsa do { \ 652930a2e29SJiri Olsa struct perf_evsel_config_term *__t; \ 653930a2e29SJiri Olsa \ 654930a2e29SJiri Olsa __t = zalloc(sizeof(*__t)); \ 655930a2e29SJiri Olsa if (!__t) \ 656930a2e29SJiri Olsa return -ENOMEM; \ 657930a2e29SJiri Olsa \ 658930a2e29SJiri Olsa INIT_LIST_HEAD(&__t->list); \ 659930a2e29SJiri Olsa __t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \ 660930a2e29SJiri Olsa __t->val.__name = __val; \ 661930a2e29SJiri Olsa list_add_tail(&__t->list, head_terms); \ 662930a2e29SJiri Olsa } while (0) 663930a2e29SJiri Olsa 664930a2e29SJiri Olsa struct parse_events_term *term; 665930a2e29SJiri Olsa 666930a2e29SJiri Olsa list_for_each_entry(term, head_config, list) { 667930a2e29SJiri Olsa switch (term->type_term) { 668ee4c7588SJiri Olsa case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 669ee4c7588SJiri Olsa ADD_CONFIG_TERM(PERIOD, period, term->val.num); 67032067712SKan Liang break; 67109af2a55SNamhyung Kim case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ: 67209af2a55SNamhyung Kim ADD_CONFIG_TERM(FREQ, freq, term->val.num); 67309af2a55SNamhyung Kim break; 67432067712SKan Liang case PARSE_EVENTS__TERM_TYPE_TIME: 67532067712SKan Liang ADD_CONFIG_TERM(TIME, time, term->val.num); 67632067712SKan Liang break; 677d457c963SKan Liang case PARSE_EVENTS__TERM_TYPE_CALLGRAPH: 678d457c963SKan Liang ADD_CONFIG_TERM(CALLGRAPH, callgraph, term->val.str); 679d457c963SKan Liang break; 680d457c963SKan Liang case PARSE_EVENTS__TERM_TYPE_STACKSIZE: 681d457c963SKan Liang ADD_CONFIG_TERM(STACK_USER, stack_user, term->val.num); 682d457c963SKan Liang break; 683930a2e29SJiri Olsa default: 684930a2e29SJiri Olsa break; 685930a2e29SJiri Olsa } 686930a2e29SJiri Olsa } 687930a2e29SJiri Olsa #undef ADD_EVSEL_CONFIG 688930a2e29SJiri Olsa return 0; 689930a2e29SJiri Olsa } 690930a2e29SJiri Olsa 69187d650beSJiri Olsa int parse_events_add_numeric(struct parse_events_evlist *data, 69287d650beSJiri Olsa struct list_head *list, 693b527bab5SRobert Richter u32 type, u64 config, 6948f707d84SJiri Olsa struct list_head *head_config) 69574d5b588SJaswinder Singh Rajput { 69689812fc8SJiri Olsa struct perf_event_attr attr; 697930a2e29SJiri Olsa LIST_HEAD(config_terms); 69874d5b588SJaswinder Singh Rajput 69989812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 70089812fc8SJiri Olsa attr.type = type; 70189812fc8SJiri Olsa attr.config = config; 7028f707d84SJiri Olsa 703930a2e29SJiri Olsa if (head_config) { 704930a2e29SJiri Olsa if (config_attr(&attr, head_config, data->error)) 7058f707d84SJiri Olsa return -EINVAL; 7068f707d84SJiri Olsa 707930a2e29SJiri Olsa if (get_config_terms(head_config, &config_terms)) 708930a2e29SJiri Olsa return -ENOMEM; 709930a2e29SJiri Olsa } 710930a2e29SJiri Olsa 711930a2e29SJiri Olsa return add_event(list, &data->idx, &attr, NULL, &config_terms); 712b908debdSIngo Molnar } 713b908debdSIngo Molnar 7146cee6cd3SArnaldo Carvalho de Melo static int parse_events__is_name_term(struct parse_events_term *term) 7156b5fc39bSJiri Olsa { 7166b5fc39bSJiri Olsa return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; 7176b5fc39bSJiri Olsa } 7186b5fc39bSJiri Olsa 7199db1763cSArnaldo Carvalho de Melo static char *pmu_event_name(struct list_head *head_terms) 7206b5fc39bSJiri Olsa { 7216cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 7226b5fc39bSJiri Olsa 7236b5fc39bSJiri Olsa list_for_each_entry(term, head_terms, list) 7246b5fc39bSJiri Olsa if (parse_events__is_name_term(term)) 7256b5fc39bSJiri Olsa return term->val.str; 7266b5fc39bSJiri Olsa 7279db1763cSArnaldo Carvalho de Melo return NULL; 7286b5fc39bSJiri Olsa } 7296b5fc39bSJiri Olsa 73036adec85SJiri Olsa int parse_events_add_pmu(struct parse_events_evlist *data, 73136adec85SJiri Olsa struct list_head *list, char *name, 73236adec85SJiri Olsa struct list_head *head_config) 7335f537a26SJiri Olsa { 7345f537a26SJiri Olsa struct perf_event_attr attr; 73546441bdcSMatt Fleming struct perf_pmu_info info; 7365f537a26SJiri Olsa struct perf_pmu *pmu; 737410136f5SStephane Eranian struct perf_evsel *evsel; 738930a2e29SJiri Olsa LIST_HEAD(config_terms); 7395f537a26SJiri Olsa 7405f537a26SJiri Olsa pmu = perf_pmu__find(name); 7415f537a26SJiri Olsa if (!pmu) 7425f537a26SJiri Olsa return -EINVAL; 7435f537a26SJiri Olsa 744dc0a6202SAdrian Hunter if (pmu->default_config) { 745dc0a6202SAdrian Hunter memcpy(&attr, pmu->default_config, 746dc0a6202SAdrian Hunter sizeof(struct perf_event_attr)); 747dc0a6202SAdrian Hunter } else { 7485f537a26SJiri Olsa memset(&attr, 0, sizeof(attr)); 749dc0a6202SAdrian Hunter } 7505f537a26SJiri Olsa 751ad962273SAdrian Hunter if (!head_config) { 752ad962273SAdrian Hunter attr.type = pmu->type; 753930a2e29SJiri Olsa evsel = __add_event(list, &data->idx, &attr, NULL, pmu->cpus, NULL); 754ad962273SAdrian Hunter return evsel ? 0 : -ENOMEM; 755ad962273SAdrian Hunter } 756ad962273SAdrian Hunter 75746441bdcSMatt Fleming if (perf_pmu__check_alias(pmu, head_config, &info)) 758a6146d50SZheng Yan return -EINVAL; 759a6146d50SZheng Yan 7605f537a26SJiri Olsa /* 7615f537a26SJiri Olsa * Configure hardcoded terms first, no need to check 7625f537a26SJiri Olsa * return value when called with fail == 0 ;) 7635f537a26SJiri Olsa */ 7643b0e371cSJiri Olsa if (config_attr(&attr, head_config, data->error)) 765c056ba6aSJiri Olsa return -EINVAL; 7665f537a26SJiri Olsa 767930a2e29SJiri Olsa if (get_config_terms(head_config, &config_terms)) 768930a2e29SJiri Olsa return -ENOMEM; 769930a2e29SJiri Olsa 770e64b020bSJiri Olsa if (perf_pmu__config(pmu, &attr, head_config, data->error)) 7715f537a26SJiri Olsa return -EINVAL; 7725f537a26SJiri Olsa 77336adec85SJiri Olsa evsel = __add_event(list, &data->idx, &attr, 774930a2e29SJiri Olsa pmu_event_name(head_config), pmu->cpus, 775930a2e29SJiri Olsa &config_terms); 776410136f5SStephane Eranian if (evsel) { 77746441bdcSMatt Fleming evsel->unit = info.unit; 77846441bdcSMatt Fleming evsel->scale = info.scale; 779044330c1SMatt Fleming evsel->per_pkg = info.per_pkg; 7801d9e446bSJiri Olsa evsel->snapshot = info.snapshot; 781410136f5SStephane Eranian } 782410136f5SStephane Eranian 783410136f5SStephane Eranian return evsel ? 0 : -ENOMEM; 7845f537a26SJiri Olsa } 7855f537a26SJiri Olsa 7866a4bb04cSJiri Olsa int parse_events__modifier_group(struct list_head *list, 7876a4bb04cSJiri Olsa char *event_mod) 78889efb029SJiri Olsa { 7896a4bb04cSJiri Olsa return parse_events__modifier_event(list, event_mod, true); 7906a4bb04cSJiri Olsa } 7916a4bb04cSJiri Olsa 79263dab225SArnaldo Carvalho de Melo void parse_events__set_leader(char *name, struct list_head *list) 7936a4bb04cSJiri Olsa { 7946a4bb04cSJiri Olsa struct perf_evsel *leader; 7956a4bb04cSJiri Olsa 79663dab225SArnaldo Carvalho de Melo __perf_evlist__set_leader(list); 79763dab225SArnaldo Carvalho de Melo leader = list_entry(list->next, struct perf_evsel, node); 7986a4bb04cSJiri Olsa leader->group_name = name ? strdup(name) : NULL; 79989efb029SJiri Olsa } 80089efb029SJiri Olsa 801c5cd8ac0SDavid Ahern /* list_event is assumed to point to malloc'ed memory */ 8025d7be90eSJiri Olsa void parse_events_update_lists(struct list_head *list_event, 8035d7be90eSJiri Olsa struct list_head *list_all) 8045d7be90eSJiri Olsa { 8055d7be90eSJiri Olsa /* 8065d7be90eSJiri Olsa * Called for single event definition. Update the 80789efb029SJiri Olsa * 'all event' list, and reinit the 'single event' 8085d7be90eSJiri Olsa * list, for next event definition. 8095d7be90eSJiri Olsa */ 8105d7be90eSJiri Olsa list_splice_tail(list_event, list_all); 811b847cbdcSJiri Olsa free(list_event); 8125d7be90eSJiri Olsa } 8135d7be90eSJiri Olsa 814f5b1135bSJiri Olsa struct event_modifier { 815f5b1135bSJiri Olsa int eu; 816f5b1135bSJiri Olsa int ek; 817f5b1135bSJiri Olsa int eh; 818f5b1135bSJiri Olsa int eH; 819f5b1135bSJiri Olsa int eG; 820a1e12da4SJiri Olsa int eI; 821f5b1135bSJiri Olsa int precise; 822f5b1135bSJiri Olsa int exclude_GH; 8233c176311SJiri Olsa int sample_read; 824e9a7c414SMichael Ellerman int pinned; 825f5b1135bSJiri Olsa }; 82661c45981SPaul Mackerras 827f5b1135bSJiri Olsa static int get_event_modifier(struct event_modifier *mod, char *str, 828f5b1135bSJiri Olsa struct perf_evsel *evsel) 829f5b1135bSJiri Olsa { 830f5b1135bSJiri Olsa int eu = evsel ? evsel->attr.exclude_user : 0; 831f5b1135bSJiri Olsa int ek = evsel ? evsel->attr.exclude_kernel : 0; 832f5b1135bSJiri Olsa int eh = evsel ? evsel->attr.exclude_hv : 0; 833f5b1135bSJiri Olsa int eH = evsel ? evsel->attr.exclude_host : 0; 834f5b1135bSJiri Olsa int eG = evsel ? evsel->attr.exclude_guest : 0; 835a1e12da4SJiri Olsa int eI = evsel ? evsel->attr.exclude_idle : 0; 836f5b1135bSJiri Olsa int precise = evsel ? evsel->attr.precise_ip : 0; 8373c176311SJiri Olsa int sample_read = 0; 838e9a7c414SMichael Ellerman int pinned = evsel ? evsel->attr.pinned : 0; 839f5b1135bSJiri Olsa 840f5b1135bSJiri Olsa int exclude = eu | ek | eh; 841f5b1135bSJiri Olsa int exclude_GH = evsel ? evsel->exclude_GH : 0; 842f5b1135bSJiri Olsa 843f5b1135bSJiri Olsa memset(mod, 0, sizeof(*mod)); 844ceb53fbfSIngo Molnar 84561c45981SPaul Mackerras while (*str) { 846ab608344SPeter Zijlstra if (*str == 'u') { 847ab608344SPeter Zijlstra if (!exclude) 848ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 84961c45981SPaul Mackerras eu = 0; 850ab608344SPeter Zijlstra } else if (*str == 'k') { 851ab608344SPeter Zijlstra if (!exclude) 852ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 85361c45981SPaul Mackerras ek = 0; 854ab608344SPeter Zijlstra } else if (*str == 'h') { 855ab608344SPeter Zijlstra if (!exclude) 856ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 85761c45981SPaul Mackerras eh = 0; 85899320cc8SJoerg Roedel } else if (*str == 'G') { 85999320cc8SJoerg Roedel if (!exclude_GH) 86099320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 86199320cc8SJoerg Roedel eG = 0; 86299320cc8SJoerg Roedel } else if (*str == 'H') { 86399320cc8SJoerg Roedel if (!exclude_GH) 86499320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 86599320cc8SJoerg Roedel eH = 0; 866a1e12da4SJiri Olsa } else if (*str == 'I') { 867a1e12da4SJiri Olsa eI = 1; 868ab608344SPeter Zijlstra } else if (*str == 'p') { 869ab608344SPeter Zijlstra precise++; 8701342798cSDavid Ahern /* use of precise requires exclude_guest */ 8711342798cSDavid Ahern if (!exclude_GH) 8721342798cSDavid Ahern eG = 1; 8733c176311SJiri Olsa } else if (*str == 'S') { 8743c176311SJiri Olsa sample_read = 1; 875e9a7c414SMichael Ellerman } else if (*str == 'D') { 876e9a7c414SMichael Ellerman pinned = 1; 877ab608344SPeter Zijlstra } else 87861c45981SPaul Mackerras break; 879ab608344SPeter Zijlstra 88061c45981SPaul Mackerras ++str; 88161c45981SPaul Mackerras } 88274d5b588SJaswinder Singh Rajput 88386470930SIngo Molnar /* 88489812fc8SJiri Olsa * precise ip: 88589812fc8SJiri Olsa * 88689812fc8SJiri Olsa * 0 - SAMPLE_IP can have arbitrary skid 88789812fc8SJiri Olsa * 1 - SAMPLE_IP must have constant skid 88889812fc8SJiri Olsa * 2 - SAMPLE_IP requested to have 0 skid 88989812fc8SJiri Olsa * 3 - SAMPLE_IP must have 0 skid 89089812fc8SJiri Olsa * 89189812fc8SJiri Olsa * See also PERF_RECORD_MISC_EXACT_IP 89286470930SIngo Molnar */ 89389812fc8SJiri Olsa if (precise > 3) 89489812fc8SJiri Olsa return -EINVAL; 89586470930SIngo Molnar 896f5b1135bSJiri Olsa mod->eu = eu; 897f5b1135bSJiri Olsa mod->ek = ek; 898f5b1135bSJiri Olsa mod->eh = eh; 899f5b1135bSJiri Olsa mod->eH = eH; 900f5b1135bSJiri Olsa mod->eG = eG; 901a1e12da4SJiri Olsa mod->eI = eI; 902f5b1135bSJiri Olsa mod->precise = precise; 903f5b1135bSJiri Olsa mod->exclude_GH = exclude_GH; 9043c176311SJiri Olsa mod->sample_read = sample_read; 905e9a7c414SMichael Ellerman mod->pinned = pinned; 906e9a7c414SMichael Ellerman 907f5b1135bSJiri Olsa return 0; 908f5b1135bSJiri Olsa } 909f5b1135bSJiri Olsa 910534123f4SJiri Olsa /* 911534123f4SJiri Olsa * Basic modifier sanity check to validate it contains only one 912534123f4SJiri Olsa * instance of any modifier (apart from 'p') present. 913534123f4SJiri Olsa */ 914534123f4SJiri Olsa static int check_modifier(char *str) 915534123f4SJiri Olsa { 916534123f4SJiri Olsa char *p = str; 917534123f4SJiri Olsa 918534123f4SJiri Olsa /* The sizeof includes 0 byte as well. */ 919a1e12da4SJiri Olsa if (strlen(str) > (sizeof("ukhGHpppSDI") - 1)) 920534123f4SJiri Olsa return -1; 921534123f4SJiri Olsa 922534123f4SJiri Olsa while (*p) { 923534123f4SJiri Olsa if (*p != 'p' && strchr(p + 1, *p)) 924534123f4SJiri Olsa return -1; 925534123f4SJiri Olsa p++; 926534123f4SJiri Olsa } 927534123f4SJiri Olsa 928534123f4SJiri Olsa return 0; 929534123f4SJiri Olsa } 930534123f4SJiri Olsa 931f5b1135bSJiri Olsa int parse_events__modifier_event(struct list_head *list, char *str, bool add) 932f5b1135bSJiri Olsa { 933f5b1135bSJiri Olsa struct perf_evsel *evsel; 934f5b1135bSJiri Olsa struct event_modifier mod; 935f5b1135bSJiri Olsa 936f5b1135bSJiri Olsa if (str == NULL) 937f5b1135bSJiri Olsa return 0; 938f5b1135bSJiri Olsa 939534123f4SJiri Olsa if (check_modifier(str)) 940534123f4SJiri Olsa return -EINVAL; 941534123f4SJiri Olsa 942f5b1135bSJiri Olsa if (!add && get_event_modifier(&mod, str, NULL)) 943f5b1135bSJiri Olsa return -EINVAL; 944f5b1135bSJiri Olsa 9450050f7aaSArnaldo Carvalho de Melo __evlist__for_each(list, evsel) { 946f5b1135bSJiri Olsa if (add && get_event_modifier(&mod, str, evsel)) 947f5b1135bSJiri Olsa return -EINVAL; 948f5b1135bSJiri Olsa 949f5b1135bSJiri Olsa evsel->attr.exclude_user = mod.eu; 950f5b1135bSJiri Olsa evsel->attr.exclude_kernel = mod.ek; 951f5b1135bSJiri Olsa evsel->attr.exclude_hv = mod.eh; 952f5b1135bSJiri Olsa evsel->attr.precise_ip = mod.precise; 953f5b1135bSJiri Olsa evsel->attr.exclude_host = mod.eH; 954f5b1135bSJiri Olsa evsel->attr.exclude_guest = mod.eG; 955a1e12da4SJiri Olsa evsel->attr.exclude_idle = mod.eI; 956f5b1135bSJiri Olsa evsel->exclude_GH = mod.exclude_GH; 9573c176311SJiri Olsa evsel->sample_read = mod.sample_read; 958e9a7c414SMichael Ellerman 959e9a7c414SMichael Ellerman if (perf_evsel__is_group_leader(evsel)) 960e9a7c414SMichael Ellerman evsel->attr.pinned = mod.pinned; 961ceb53fbfSIngo Molnar } 96286470930SIngo Molnar 96389812fc8SJiri Olsa return 0; 96486470930SIngo Molnar } 96586470930SIngo Molnar 966ac2ba9f3SRobert Richter int parse_events_name(struct list_head *list, char *name) 967ac2ba9f3SRobert Richter { 968ac2ba9f3SRobert Richter struct perf_evsel *evsel; 969ac2ba9f3SRobert Richter 9700050f7aaSArnaldo Carvalho de Melo __evlist__for_each(list, evsel) { 971ac2ba9f3SRobert Richter if (!evsel->name) 972ac2ba9f3SRobert Richter evsel->name = strdup(name); 973ac2ba9f3SRobert Richter } 974ac2ba9f3SRobert Richter 975ac2ba9f3SRobert Richter return 0; 976ac2ba9f3SRobert Richter } 977ac2ba9f3SRobert Richter 978dcb4e102SKan Liang static int 979dcb4e102SKan Liang comp_pmu(const void *p1, const void *p2) 980dcb4e102SKan Liang { 981dcb4e102SKan Liang struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1; 982dcb4e102SKan Liang struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2; 983dcb4e102SKan Liang 984dcb4e102SKan Liang return strcmp(pmu1->symbol, pmu2->symbol); 985dcb4e102SKan Liang } 986dcb4e102SKan Liang 987dcb4e102SKan Liang static void perf_pmu__parse_cleanup(void) 988dcb4e102SKan Liang { 989dcb4e102SKan Liang if (perf_pmu_events_list_num > 0) { 990dcb4e102SKan Liang struct perf_pmu_event_symbol *p; 991dcb4e102SKan Liang int i; 992dcb4e102SKan Liang 993dcb4e102SKan Liang for (i = 0; i < perf_pmu_events_list_num; i++) { 994dcb4e102SKan Liang p = perf_pmu_events_list + i; 995dcb4e102SKan Liang free(p->symbol); 996dcb4e102SKan Liang } 997dcb4e102SKan Liang free(perf_pmu_events_list); 998dcb4e102SKan Liang perf_pmu_events_list = NULL; 999dcb4e102SKan Liang perf_pmu_events_list_num = 0; 1000dcb4e102SKan Liang } 1001dcb4e102SKan Liang } 1002dcb4e102SKan Liang 1003dcb4e102SKan Liang #define SET_SYMBOL(str, stype) \ 1004dcb4e102SKan Liang do { \ 1005dcb4e102SKan Liang p->symbol = str; \ 1006dcb4e102SKan Liang if (!p->symbol) \ 1007dcb4e102SKan Liang goto err; \ 1008dcb4e102SKan Liang p->type = stype; \ 1009dcb4e102SKan Liang } while (0) 1010dcb4e102SKan Liang 1011dcb4e102SKan Liang /* 1012dcb4e102SKan Liang * Read the pmu events list from sysfs 1013dcb4e102SKan Liang * Save it into perf_pmu_events_list 1014dcb4e102SKan Liang */ 1015dcb4e102SKan Liang static void perf_pmu__parse_init(void) 1016dcb4e102SKan Liang { 1017dcb4e102SKan Liang 1018dcb4e102SKan Liang struct perf_pmu *pmu = NULL; 1019dcb4e102SKan Liang struct perf_pmu_alias *alias; 1020dcb4e102SKan Liang int len = 0; 1021dcb4e102SKan Liang 1022dcb4e102SKan Liang pmu = perf_pmu__find("cpu"); 1023dcb4e102SKan Liang if ((pmu == NULL) || list_empty(&pmu->aliases)) { 1024dcb4e102SKan Liang perf_pmu_events_list_num = -1; 1025dcb4e102SKan Liang return; 1026dcb4e102SKan Liang } 1027dcb4e102SKan Liang list_for_each_entry(alias, &pmu->aliases, list) { 1028dcb4e102SKan Liang if (strchr(alias->name, '-')) 1029dcb4e102SKan Liang len++; 1030dcb4e102SKan Liang len++; 1031dcb4e102SKan Liang } 1032dcb4e102SKan Liang perf_pmu_events_list = malloc(sizeof(struct perf_pmu_event_symbol) * len); 1033dcb4e102SKan Liang if (!perf_pmu_events_list) 1034dcb4e102SKan Liang return; 1035dcb4e102SKan Liang perf_pmu_events_list_num = len; 1036dcb4e102SKan Liang 1037dcb4e102SKan Liang len = 0; 1038dcb4e102SKan Liang list_for_each_entry(alias, &pmu->aliases, list) { 1039dcb4e102SKan Liang struct perf_pmu_event_symbol *p = perf_pmu_events_list + len; 1040dcb4e102SKan Liang char *tmp = strchr(alias->name, '-'); 1041dcb4e102SKan Liang 1042dcb4e102SKan Liang if (tmp != NULL) { 1043dcb4e102SKan Liang SET_SYMBOL(strndup(alias->name, tmp - alias->name), 1044dcb4e102SKan Liang PMU_EVENT_SYMBOL_PREFIX); 1045dcb4e102SKan Liang p++; 1046dcb4e102SKan Liang SET_SYMBOL(strdup(++tmp), PMU_EVENT_SYMBOL_SUFFIX); 1047dcb4e102SKan Liang len += 2; 1048dcb4e102SKan Liang } else { 1049dcb4e102SKan Liang SET_SYMBOL(strdup(alias->name), PMU_EVENT_SYMBOL); 1050dcb4e102SKan Liang len++; 1051dcb4e102SKan Liang } 1052dcb4e102SKan Liang } 1053dcb4e102SKan Liang qsort(perf_pmu_events_list, len, 1054dcb4e102SKan Liang sizeof(struct perf_pmu_event_symbol), comp_pmu); 1055dcb4e102SKan Liang 1056dcb4e102SKan Liang return; 1057dcb4e102SKan Liang err: 1058dcb4e102SKan Liang perf_pmu__parse_cleanup(); 1059dcb4e102SKan Liang } 1060dcb4e102SKan Liang 1061dcb4e102SKan Liang enum perf_pmu_event_symbol_type 1062dcb4e102SKan Liang perf_pmu__parse_check(const char *name) 1063dcb4e102SKan Liang { 1064dcb4e102SKan Liang struct perf_pmu_event_symbol p, *r; 1065dcb4e102SKan Liang 1066dcb4e102SKan Liang /* scan kernel pmu events from sysfs if needed */ 1067dcb4e102SKan Liang if (perf_pmu_events_list_num == 0) 1068dcb4e102SKan Liang perf_pmu__parse_init(); 1069dcb4e102SKan Liang /* 1070dcb4e102SKan Liang * name "cpu" could be prefix of cpu-cycles or cpu// events. 1071dcb4e102SKan Liang * cpu-cycles has been handled by hardcode. 1072dcb4e102SKan Liang * So it must be cpu// events, not kernel pmu event. 1073dcb4e102SKan Liang */ 1074dcb4e102SKan Liang if ((perf_pmu_events_list_num <= 0) || !strcmp(name, "cpu")) 1075dcb4e102SKan Liang return PMU_EVENT_SYMBOL_ERR; 1076dcb4e102SKan Liang 1077dcb4e102SKan Liang p.symbol = strdup(name); 1078dcb4e102SKan Liang r = bsearch(&p, perf_pmu_events_list, 1079dcb4e102SKan Liang (size_t) perf_pmu_events_list_num, 1080dcb4e102SKan Liang sizeof(struct perf_pmu_event_symbol), comp_pmu); 1081dcb4e102SKan Liang free(p.symbol); 1082dcb4e102SKan Liang return r ? r->type : PMU_EVENT_SYMBOL_ERR; 1083dcb4e102SKan Liang } 1084dcb4e102SKan Liang 108590e2b22dSJiri Olsa static int parse_events__scanner(const char *str, void *data, int start_token) 1086ac20de6fSZheng Yan { 1087ac20de6fSZheng Yan YY_BUFFER_STATE buffer; 1088ac20de6fSZheng Yan void *scanner; 1089ac20de6fSZheng Yan int ret; 1090ac20de6fSZheng Yan 109190e2b22dSJiri Olsa ret = parse_events_lex_init_extra(start_token, &scanner); 1092ac20de6fSZheng Yan if (ret) 1093ac20de6fSZheng Yan return ret; 1094ac20de6fSZheng Yan 1095ac20de6fSZheng Yan buffer = parse_events__scan_string(str, scanner); 1096ac20de6fSZheng Yan 1097ac20de6fSZheng Yan #ifdef PARSER_DEBUG 1098ac20de6fSZheng Yan parse_events_debug = 1; 1099ac20de6fSZheng Yan #endif 1100ac20de6fSZheng Yan ret = parse_events_parse(data, scanner); 1101ac20de6fSZheng Yan 1102ac20de6fSZheng Yan parse_events__flush_buffer(buffer, scanner); 1103ac20de6fSZheng Yan parse_events__delete_buffer(buffer, scanner); 1104ac20de6fSZheng Yan parse_events_lex_destroy(scanner); 1105ac20de6fSZheng Yan return ret; 1106ac20de6fSZheng Yan } 1107ac20de6fSZheng Yan 110890e2b22dSJiri Olsa /* 110990e2b22dSJiri Olsa * parse event config string, return a list of event terms. 111090e2b22dSJiri Olsa */ 111190e2b22dSJiri Olsa int parse_events_terms(struct list_head *terms, const char *str) 111290e2b22dSJiri Olsa { 111323b6339bSArnaldo Carvalho de Melo struct parse_events_terms data = { 111490e2b22dSJiri Olsa .terms = NULL, 111590e2b22dSJiri Olsa }; 111690e2b22dSJiri Olsa int ret; 111790e2b22dSJiri Olsa 111890e2b22dSJiri Olsa ret = parse_events__scanner(str, &data, PE_START_TERMS); 111990e2b22dSJiri Olsa if (!ret) { 112090e2b22dSJiri Olsa list_splice(data.terms, terms); 112174cf249dSArnaldo Carvalho de Melo zfree(&data.terms); 112290e2b22dSJiri Olsa return 0; 112390e2b22dSJiri Olsa } 112490e2b22dSJiri Olsa 1125b2c34fdeSAdrian Hunter if (data.terms) 112690e2b22dSJiri Olsa parse_events__free_terms(data.terms); 112790e2b22dSJiri Olsa return ret; 112890e2b22dSJiri Olsa } 112990e2b22dSJiri Olsa 1130b39b8393SJiri Olsa int parse_events(struct perf_evlist *evlist, const char *str, 1131b39b8393SJiri Olsa struct parse_events_error *err) 113286470930SIngo Molnar { 113323b6339bSArnaldo Carvalho de Melo struct parse_events_evlist data = { 113446010ab2SJiri Olsa .list = LIST_HEAD_INIT(data.list), 113546010ab2SJiri Olsa .idx = evlist->nr_entries, 1136b39b8393SJiri Olsa .error = err, 113746010ab2SJiri Olsa }; 113846010ab2SJiri Olsa int ret; 113986470930SIngo Molnar 114090e2b22dSJiri Olsa ret = parse_events__scanner(str, &data, PE_START_EVENTS); 1141dcb4e102SKan Liang perf_pmu__parse_cleanup(); 114289812fc8SJiri Olsa if (!ret) { 114315bfd2ccSWang Nan struct perf_evsel *last; 114415bfd2ccSWang Nan 1145*f114d6efSAdrian Hunter perf_evlist__splice_list_tail(evlist, &data.list); 114697f63e4aSNamhyung Kim evlist->nr_groups += data.nr_groups; 114715bfd2ccSWang Nan last = perf_evlist__last(evlist); 114815bfd2ccSWang Nan last->cmdline_group_boundary = true; 114915bfd2ccSWang Nan 115086470930SIngo Molnar return 0; 115186470930SIngo Molnar } 115286470930SIngo Molnar 11535d7be90eSJiri Olsa /* 11545d7be90eSJiri Olsa * There are 2 users - builtin-record and builtin-test objects. 11555d7be90eSJiri Olsa * Both call perf_evlist__delete in case of error, so we dont 11565d7be90eSJiri Olsa * need to bother. 11575d7be90eSJiri Olsa */ 115889812fc8SJiri Olsa return ret; 115989812fc8SJiri Olsa } 116089812fc8SJiri Olsa 1161b39b8393SJiri Olsa #define MAX_WIDTH 1000 1162b39b8393SJiri Olsa static int get_term_width(void) 1163b39b8393SJiri Olsa { 1164b39b8393SJiri Olsa struct winsize ws; 1165b39b8393SJiri Olsa 1166b39b8393SJiri Olsa get_term_dimensions(&ws); 1167b39b8393SJiri Olsa return ws.ws_col > MAX_WIDTH ? MAX_WIDTH : ws.ws_col; 1168b39b8393SJiri Olsa } 1169b39b8393SJiri Olsa 1170b39b8393SJiri Olsa static void parse_events_print_error(struct parse_events_error *err, 1171b39b8393SJiri Olsa const char *event) 1172b39b8393SJiri Olsa { 1173b39b8393SJiri Olsa const char *str = "invalid or unsupported event: "; 1174b39b8393SJiri Olsa char _buf[MAX_WIDTH]; 1175b39b8393SJiri Olsa char *buf = (char *) event; 1176b39b8393SJiri Olsa int idx = 0; 1177b39b8393SJiri Olsa 1178b39b8393SJiri Olsa if (err->str) { 1179b39b8393SJiri Olsa /* -2 for extra '' in the final fprintf */ 1180b39b8393SJiri Olsa int width = get_term_width() - 2; 1181b39b8393SJiri Olsa int len_event = strlen(event); 1182b39b8393SJiri Olsa int len_str, max_len, cut = 0; 1183b39b8393SJiri Olsa 1184b39b8393SJiri Olsa /* 1185b39b8393SJiri Olsa * Maximum error index indent, we will cut 1186b39b8393SJiri Olsa * the event string if it's bigger. 1187b39b8393SJiri Olsa */ 1188141b2d31SAdrian Hunter int max_err_idx = 13; 1189b39b8393SJiri Olsa 1190b39b8393SJiri Olsa /* 1191b39b8393SJiri Olsa * Let's be specific with the message when 1192b39b8393SJiri Olsa * we have the precise error. 1193b39b8393SJiri Olsa */ 1194b39b8393SJiri Olsa str = "event syntax error: "; 1195b39b8393SJiri Olsa len_str = strlen(str); 1196b39b8393SJiri Olsa max_len = width - len_str; 1197b39b8393SJiri Olsa 1198b39b8393SJiri Olsa buf = _buf; 1199b39b8393SJiri Olsa 1200b39b8393SJiri Olsa /* We're cutting from the beggining. */ 1201b39b8393SJiri Olsa if (err->idx > max_err_idx) 1202b39b8393SJiri Olsa cut = err->idx - max_err_idx; 1203b39b8393SJiri Olsa 1204b39b8393SJiri Olsa strncpy(buf, event + cut, max_len); 1205b39b8393SJiri Olsa 1206b39b8393SJiri Olsa /* Mark cut parts with '..' on both sides. */ 1207b39b8393SJiri Olsa if (cut) 1208b39b8393SJiri Olsa buf[0] = buf[1] = '.'; 1209b39b8393SJiri Olsa 1210b39b8393SJiri Olsa if ((len_event - cut) > max_len) { 1211b39b8393SJiri Olsa buf[max_len - 1] = buf[max_len - 2] = '.'; 1212b39b8393SJiri Olsa buf[max_len] = 0; 1213b39b8393SJiri Olsa } 1214b39b8393SJiri Olsa 1215b39b8393SJiri Olsa idx = len_str + err->idx - cut; 1216b39b8393SJiri Olsa } 1217b39b8393SJiri Olsa 1218b39b8393SJiri Olsa fprintf(stderr, "%s'%s'\n", str, buf); 1219b39b8393SJiri Olsa if (idx) { 1220b39b8393SJiri Olsa fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err->str); 1221b39b8393SJiri Olsa if (err->help) 1222b39b8393SJiri Olsa fprintf(stderr, "\n%s\n", err->help); 1223b39b8393SJiri Olsa free(err->str); 1224b39b8393SJiri Olsa free(err->help); 1225b39b8393SJiri Olsa } 1226b39b8393SJiri Olsa 1227b39b8393SJiri Olsa fprintf(stderr, "Run 'perf list' for a list of valid events\n"); 1228b39b8393SJiri Olsa } 1229b39b8393SJiri Olsa 1230b39b8393SJiri Olsa #undef MAX_WIDTH 1231b39b8393SJiri Olsa 1232f120f9d5SJiri Olsa int parse_events_option(const struct option *opt, const char *str, 12331d037ca1SIrina Tirdea int unset __maybe_unused) 1234f120f9d5SJiri Olsa { 1235f120f9d5SJiri Olsa struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 1236b39b8393SJiri Olsa struct parse_events_error err = { .idx = 0, }; 1237b39b8393SJiri Olsa int ret = parse_events(evlist, str, &err); 12389175ce1fSAndi Kleen 1239b39b8393SJiri Olsa if (ret) 1240b39b8393SJiri Olsa parse_events_print_error(&err, str); 1241b39b8393SJiri Olsa 12429175ce1fSAndi Kleen return ret; 1243f120f9d5SJiri Olsa } 1244f120f9d5SJiri Olsa 12454ba1faa1SWang Nan static int 12464ba1faa1SWang Nan foreach_evsel_in_last_glob(struct perf_evlist *evlist, 12474ba1faa1SWang Nan int (*func)(struct perf_evsel *evsel, 12484ba1faa1SWang Nan const void *arg), 12494ba1faa1SWang Nan const void *arg) 1250c171b552SLi Zefan { 125169aad6f1SArnaldo Carvalho de Melo struct perf_evsel *last = NULL; 12524ba1faa1SWang Nan int err; 1253c171b552SLi Zefan 1254361c99a6SArnaldo Carvalho de Melo if (evlist->nr_entries > 0) 12550c21f736SArnaldo Carvalho de Melo last = perf_evlist__last(evlist); 125669aad6f1SArnaldo Carvalho de Melo 125715bfd2ccSWang Nan do { 12584ba1faa1SWang Nan err = (*func)(last, arg); 12594ba1faa1SWang Nan if (err) 1260c171b552SLi Zefan return -1; 12614ba1faa1SWang Nan if (!last) 12624ba1faa1SWang Nan return 0; 1263c171b552SLi Zefan 126415bfd2ccSWang Nan if (last->node.prev == &evlist->entries) 126515bfd2ccSWang Nan return 0; 126615bfd2ccSWang Nan last = list_entry(last->node.prev, struct perf_evsel, node); 126715bfd2ccSWang Nan } while (!last->cmdline_group_boundary); 126815bfd2ccSWang Nan 1269c171b552SLi Zefan return 0; 1270c171b552SLi Zefan } 1271c171b552SLi Zefan 12724ba1faa1SWang Nan static int set_filter(struct perf_evsel *evsel, const void *arg) 12734ba1faa1SWang Nan { 12744ba1faa1SWang Nan const char *str = arg; 12754ba1faa1SWang Nan 12764ba1faa1SWang Nan if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) { 12774ba1faa1SWang Nan fprintf(stderr, 12784ba1faa1SWang Nan "--filter option should follow a -e tracepoint option\n"); 12794ba1faa1SWang Nan return -1; 12804ba1faa1SWang Nan } 12814ba1faa1SWang Nan 12824ba1faa1SWang Nan if (perf_evsel__append_filter(evsel, "&&", str) < 0) { 12834ba1faa1SWang Nan fprintf(stderr, 12844ba1faa1SWang Nan "not enough memory to hold filter string\n"); 12854ba1faa1SWang Nan return -1; 12864ba1faa1SWang Nan } 12874ba1faa1SWang Nan 12884ba1faa1SWang Nan return 0; 12894ba1faa1SWang Nan } 12904ba1faa1SWang Nan 12914ba1faa1SWang Nan int parse_filter(const struct option *opt, const char *str, 12924ba1faa1SWang Nan int unset __maybe_unused) 12934ba1faa1SWang Nan { 12944ba1faa1SWang Nan struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 12954ba1faa1SWang Nan 12964ba1faa1SWang Nan return foreach_evsel_in_last_glob(evlist, set_filter, 12974ba1faa1SWang Nan (const void *)str); 12984ba1faa1SWang Nan } 12994ba1faa1SWang Nan 13004ba1faa1SWang Nan static int add_exclude_perf_filter(struct perf_evsel *evsel, 13014ba1faa1SWang Nan const void *arg __maybe_unused) 13024ba1faa1SWang Nan { 13034ba1faa1SWang Nan char new_filter[64]; 13044ba1faa1SWang Nan 13054ba1faa1SWang Nan if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) { 13064ba1faa1SWang Nan fprintf(stderr, 13074ba1faa1SWang Nan "--exclude-perf option should follow a -e tracepoint option\n"); 13084ba1faa1SWang Nan return -1; 13094ba1faa1SWang Nan } 13104ba1faa1SWang Nan 13114ba1faa1SWang Nan snprintf(new_filter, sizeof(new_filter), "common_pid != %d", getpid()); 13124ba1faa1SWang Nan 13134ba1faa1SWang Nan if (perf_evsel__append_filter(evsel, "&&", new_filter) < 0) { 13144ba1faa1SWang Nan fprintf(stderr, 13154ba1faa1SWang Nan "not enough memory to hold filter string\n"); 13164ba1faa1SWang Nan return -1; 13174ba1faa1SWang Nan } 13184ba1faa1SWang Nan 13194ba1faa1SWang Nan return 0; 13204ba1faa1SWang Nan } 13214ba1faa1SWang Nan 13224ba1faa1SWang Nan int exclude_perf(const struct option *opt, 13234ba1faa1SWang Nan const char *arg __maybe_unused, 13244ba1faa1SWang Nan int unset __maybe_unused) 13254ba1faa1SWang Nan { 13264ba1faa1SWang Nan struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 13274ba1faa1SWang Nan 13284ba1faa1SWang Nan return foreach_evsel_in_last_glob(evlist, add_exclude_perf_filter, 13294ba1faa1SWang Nan NULL); 13304ba1faa1SWang Nan } 13314ba1faa1SWang Nan 133286470930SIngo Molnar static const char * const event_type_descriptors[] = { 133386470930SIngo Molnar "Hardware event", 133486470930SIngo Molnar "Software event", 133586470930SIngo Molnar "Tracepoint event", 133686470930SIngo Molnar "Hardware cache event", 133741bdcb23SLiming Wang "Raw hardware event descriptor", 133841bdcb23SLiming Wang "Hardware breakpoint", 133986470930SIngo Molnar }; 134086470930SIngo Molnar 1341ab0e4800SYunlong Song static int cmp_string(const void *a, const void *b) 1342ab0e4800SYunlong Song { 1343ab0e4800SYunlong Song const char * const *as = a; 1344ab0e4800SYunlong Song const char * const *bs = b; 1345ab0e4800SYunlong Song 1346ab0e4800SYunlong Song return strcmp(*as, *bs); 1347ab0e4800SYunlong Song } 1348ab0e4800SYunlong Song 134986470930SIngo Molnar /* 1350f6bdafefSJason Baron * Print the events from <debugfs_mount_point>/tracing/events 1351f6bdafefSJason Baron */ 1352f6bdafefSJason Baron 1353a3277d2dSFrederic Weisbecker void print_tracepoint_events(const char *subsys_glob, const char *event_glob, 1354a3277d2dSFrederic Weisbecker bool name_only) 1355f6bdafefSJason Baron { 1356f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 1357f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1358f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 1359725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 1360ab0e4800SYunlong Song char **evt_list = NULL; 1361ab0e4800SYunlong Song unsigned int evt_i = 0, evt_num = 0; 1362ab0e4800SYunlong Song bool evt_num_known = false; 1363f6bdafefSJason Baron 1364ab0e4800SYunlong Song restart: 1365ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 1366f6bdafefSJason Baron if (!sys_dir) 1367725b1368SEric Dumazet return; 1368f6bdafefSJason Baron 1369ab0e4800SYunlong Song if (evt_num_known) { 1370ab0e4800SYunlong Song evt_list = zalloc(sizeof(char *) * evt_num); 1371ab0e4800SYunlong Song if (!evt_list) 1372ab0e4800SYunlong Song goto out_close_sys_dir; 1373ab0e4800SYunlong Song } 1374ab0e4800SYunlong Song 13756b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 1376668b8788SArnaldo Carvalho de Melo if (subsys_glob != NULL && 1377668b8788SArnaldo Carvalho de Melo !strglobmatch(sys_dirent.d_name, subsys_glob)) 1378668b8788SArnaldo Carvalho de Melo continue; 1379725b1368SEric Dumazet 1380ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 1381725b1368SEric Dumazet sys_dirent.d_name); 1382725b1368SEric Dumazet evt_dir = opendir(dir_path); 1383725b1368SEric Dumazet if (!evt_dir) 13846b58e7f1SUlrich Drepper continue; 1385725b1368SEric Dumazet 13866b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 1387668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 1388668b8788SArnaldo Carvalho de Melo !strglobmatch(evt_dirent.d_name, event_glob)) 1389668b8788SArnaldo Carvalho de Melo continue; 1390668b8788SArnaldo Carvalho de Melo 1391ab0e4800SYunlong Song if (!evt_num_known) { 1392ab0e4800SYunlong Song evt_num++; 1393a3277d2dSFrederic Weisbecker continue; 1394a3277d2dSFrederic Weisbecker } 1395a3277d2dSFrederic Weisbecker 1396f6bdafefSJason Baron snprintf(evt_path, MAXPATHLEN, "%s:%s", 1397f6bdafefSJason Baron sys_dirent.d_name, evt_dirent.d_name); 1398ab0e4800SYunlong Song 1399ab0e4800SYunlong Song evt_list[evt_i] = strdup(evt_path); 1400ab0e4800SYunlong Song if (evt_list[evt_i] == NULL) 1401ab0e4800SYunlong Song goto out_close_evt_dir; 1402ab0e4800SYunlong Song evt_i++; 1403f6bdafefSJason Baron } 1404f6bdafefSJason Baron closedir(evt_dir); 1405f6bdafefSJason Baron } 1406f6bdafefSJason Baron closedir(sys_dir); 1407ab0e4800SYunlong Song 1408ab0e4800SYunlong Song if (!evt_num_known) { 1409ab0e4800SYunlong Song evt_num_known = true; 1410ab0e4800SYunlong Song goto restart; 1411ab0e4800SYunlong Song } 1412ab0e4800SYunlong Song qsort(evt_list, evt_num, sizeof(char *), cmp_string); 1413ab0e4800SYunlong Song evt_i = 0; 1414ab0e4800SYunlong Song while (evt_i < evt_num) { 1415ab0e4800SYunlong Song if (name_only) { 1416ab0e4800SYunlong Song printf("%s ", evt_list[evt_i++]); 1417ab0e4800SYunlong Song continue; 1418ab0e4800SYunlong Song } 1419ab0e4800SYunlong Song printf(" %-50s [%s]\n", evt_list[evt_i++], 1420ab0e4800SYunlong Song event_type_descriptors[PERF_TYPE_TRACEPOINT]); 1421ab0e4800SYunlong Song } 1422ab0e4800SYunlong Song if (evt_num) 1423ab0e4800SYunlong Song printf("\n"); 1424ab0e4800SYunlong Song 1425ab0e4800SYunlong Song out_free: 1426ab0e4800SYunlong Song evt_num = evt_i; 1427ab0e4800SYunlong Song for (evt_i = 0; evt_i < evt_num; evt_i++) 1428ab0e4800SYunlong Song zfree(&evt_list[evt_i]); 1429ab0e4800SYunlong Song zfree(&evt_list); 1430ab0e4800SYunlong Song return; 1431ab0e4800SYunlong Song 1432ab0e4800SYunlong Song out_close_evt_dir: 1433ab0e4800SYunlong Song closedir(evt_dir); 1434ab0e4800SYunlong Song out_close_sys_dir: 1435ab0e4800SYunlong Song closedir(sys_dir); 1436ab0e4800SYunlong Song 1437ab0e4800SYunlong Song printf("FATAL: not enough memory to print %s\n", 1438ab0e4800SYunlong Song event_type_descriptors[PERF_TYPE_TRACEPOINT]); 1439ab0e4800SYunlong Song if (evt_list) 1440ab0e4800SYunlong Song goto out_free; 1441f6bdafefSJason Baron } 1442f6bdafefSJason Baron 1443f6bdafefSJason Baron /* 144420c457b8SThomas Renninger * Check whether event is in <debugfs_mount_point>/tracing/events 144520c457b8SThomas Renninger */ 144620c457b8SThomas Renninger 144720c457b8SThomas Renninger int is_valid_tracepoint(const char *event_string) 144820c457b8SThomas Renninger { 144920c457b8SThomas Renninger DIR *sys_dir, *evt_dir; 145020c457b8SThomas Renninger struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 145120c457b8SThomas Renninger char evt_path[MAXPATHLEN]; 145220c457b8SThomas Renninger char dir_path[MAXPATHLEN]; 145320c457b8SThomas Renninger 1454ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 145520c457b8SThomas Renninger if (!sys_dir) 145620c457b8SThomas Renninger return 0; 145720c457b8SThomas Renninger 145820c457b8SThomas Renninger for_each_subsystem(sys_dir, sys_dirent, sys_next) { 145920c457b8SThomas Renninger 1460ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 146120c457b8SThomas Renninger sys_dirent.d_name); 146220c457b8SThomas Renninger evt_dir = opendir(dir_path); 146320c457b8SThomas Renninger if (!evt_dir) 146420c457b8SThomas Renninger continue; 146520c457b8SThomas Renninger 146620c457b8SThomas Renninger for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 146720c457b8SThomas Renninger snprintf(evt_path, MAXPATHLEN, "%s:%s", 146820c457b8SThomas Renninger sys_dirent.d_name, evt_dirent.d_name); 146920c457b8SThomas Renninger if (!strcmp(evt_path, event_string)) { 147020c457b8SThomas Renninger closedir(evt_dir); 147120c457b8SThomas Renninger closedir(sys_dir); 147220c457b8SThomas Renninger return 1; 147320c457b8SThomas Renninger } 147420c457b8SThomas Renninger } 147520c457b8SThomas Renninger closedir(evt_dir); 147620c457b8SThomas Renninger } 147720c457b8SThomas Renninger closedir(sys_dir); 147820c457b8SThomas Renninger return 0; 147920c457b8SThomas Renninger } 148020c457b8SThomas Renninger 1481b41f1cecSNamhyung Kim static bool is_event_supported(u8 type, unsigned config) 1482b41f1cecSNamhyung Kim { 1483b41f1cecSNamhyung Kim bool ret = true; 148488fee52eSVince Weaver int open_return; 1485b41f1cecSNamhyung Kim struct perf_evsel *evsel; 1486b41f1cecSNamhyung Kim struct perf_event_attr attr = { 1487b41f1cecSNamhyung Kim .type = type, 1488b41f1cecSNamhyung Kim .config = config, 1489b41f1cecSNamhyung Kim .disabled = 1, 1490b41f1cecSNamhyung Kim }; 1491b41f1cecSNamhyung Kim struct { 1492b41f1cecSNamhyung Kim struct thread_map map; 1493b41f1cecSNamhyung Kim int threads[1]; 1494b41f1cecSNamhyung Kim } tmap = { 1495b41f1cecSNamhyung Kim .map.nr = 1, 1496b41f1cecSNamhyung Kim .threads = { 0 }, 1497b41f1cecSNamhyung Kim }; 1498b41f1cecSNamhyung Kim 1499ef503831SArnaldo Carvalho de Melo evsel = perf_evsel__new(&attr); 1500b41f1cecSNamhyung Kim if (evsel) { 150188fee52eSVince Weaver open_return = perf_evsel__open(evsel, NULL, &tmap.map); 150288fee52eSVince Weaver ret = open_return >= 0; 150388fee52eSVince Weaver 150488fee52eSVince Weaver if (open_return == -EACCES) { 150588fee52eSVince Weaver /* 150688fee52eSVince Weaver * This happens if the paranoid value 150788fee52eSVince Weaver * /proc/sys/kernel/perf_event_paranoid is set to 2 150888fee52eSVince Weaver * Re-run with exclude_kernel set; we don't do that 150988fee52eSVince Weaver * by default as some ARM machines do not support it. 151088fee52eSVince Weaver * 151188fee52eSVince Weaver */ 151288fee52eSVince Weaver evsel->attr.exclude_kernel = 1; 1513b41f1cecSNamhyung Kim ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; 151488fee52eSVince Weaver } 1515b41f1cecSNamhyung Kim perf_evsel__delete(evsel); 1516b41f1cecSNamhyung Kim } 1517b41f1cecSNamhyung Kim 1518b41f1cecSNamhyung Kim return ret; 1519b41f1cecSNamhyung Kim } 1520b41f1cecSNamhyung Kim 1521a3277d2dSFrederic Weisbecker int print_hwcache_events(const char *event_glob, bool name_only) 1522668b8788SArnaldo Carvalho de Melo { 1523ab0e4800SYunlong Song unsigned int type, op, i, evt_i = 0, evt_num = 0; 15240b668bc9SArnaldo Carvalho de Melo char name[64]; 1525ab0e4800SYunlong Song char **evt_list = NULL; 1526ab0e4800SYunlong Song bool evt_num_known = false; 1527ab0e4800SYunlong Song 1528ab0e4800SYunlong Song restart: 1529ab0e4800SYunlong Song if (evt_num_known) { 1530ab0e4800SYunlong Song evt_list = zalloc(sizeof(char *) * evt_num); 1531ab0e4800SYunlong Song if (!evt_list) 1532ab0e4800SYunlong Song goto out_enomem; 1533ab0e4800SYunlong Song } 1534668b8788SArnaldo Carvalho de Melo 1535668b8788SArnaldo Carvalho de Melo for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 1536668b8788SArnaldo Carvalho de Melo for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 1537668b8788SArnaldo Carvalho de Melo /* skip invalid cache type */ 15380b668bc9SArnaldo Carvalho de Melo if (!perf_evsel__is_cache_op_valid(type, op)) 1539668b8788SArnaldo Carvalho de Melo continue; 1540668b8788SArnaldo Carvalho de Melo 1541668b8788SArnaldo Carvalho de Melo for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 15420b668bc9SArnaldo Carvalho de Melo __perf_evsel__hw_cache_type_op_res_name(type, op, i, 15430b668bc9SArnaldo Carvalho de Melo name, sizeof(name)); 1544947b4ad1SIngo Molnar if (event_glob != NULL && !strglobmatch(name, event_glob)) 1545668b8788SArnaldo Carvalho de Melo continue; 1546668b8788SArnaldo Carvalho de Melo 1547b41f1cecSNamhyung Kim if (!is_event_supported(PERF_TYPE_HW_CACHE, 1548b41f1cecSNamhyung Kim type | (op << 8) | (i << 16))) 1549b41f1cecSNamhyung Kim continue; 1550b41f1cecSNamhyung Kim 1551ab0e4800SYunlong Song if (!evt_num_known) { 1552ab0e4800SYunlong Song evt_num++; 1553ab0e4800SYunlong Song continue; 1554ab0e4800SYunlong Song } 1555ab0e4800SYunlong Song 1556ab0e4800SYunlong Song evt_list[evt_i] = strdup(name); 1557ab0e4800SYunlong Song if (evt_list[evt_i] == NULL) 1558ab0e4800SYunlong Song goto out_enomem; 1559ab0e4800SYunlong Song evt_i++; 1560668b8788SArnaldo Carvalho de Melo } 1561668b8788SArnaldo Carvalho de Melo } 1562668b8788SArnaldo Carvalho de Melo } 1563668b8788SArnaldo Carvalho de Melo 1564ab0e4800SYunlong Song if (!evt_num_known) { 1565ab0e4800SYunlong Song evt_num_known = true; 1566ab0e4800SYunlong Song goto restart; 1567ab0e4800SYunlong Song } 1568ab0e4800SYunlong Song qsort(evt_list, evt_num, sizeof(char *), cmp_string); 1569ab0e4800SYunlong Song evt_i = 0; 1570ab0e4800SYunlong Song while (evt_i < evt_num) { 1571ab0e4800SYunlong Song if (name_only) { 1572ab0e4800SYunlong Song printf("%s ", evt_list[evt_i++]); 1573ab0e4800SYunlong Song continue; 1574ab0e4800SYunlong Song } 1575ab0e4800SYunlong Song printf(" %-50s [%s]\n", evt_list[evt_i++], 1576ab0e4800SYunlong Song event_type_descriptors[PERF_TYPE_HW_CACHE]); 1577ab0e4800SYunlong Song } 1578ab0e4800SYunlong Song if (evt_num) 1579dc098b35SAndi Kleen printf("\n"); 1580ab0e4800SYunlong Song 1581ab0e4800SYunlong Song out_free: 1582ab0e4800SYunlong Song evt_num = evt_i; 1583ab0e4800SYunlong Song for (evt_i = 0; evt_i < evt_num; evt_i++) 1584ab0e4800SYunlong Song zfree(&evt_list[evt_i]); 1585ab0e4800SYunlong Song zfree(&evt_list); 1586ab0e4800SYunlong Song return evt_num; 1587ab0e4800SYunlong Song 1588ab0e4800SYunlong Song out_enomem: 1589ab0e4800SYunlong Song printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]); 1590ab0e4800SYunlong Song if (evt_list) 1591ab0e4800SYunlong Song goto out_free; 1592ab0e4800SYunlong Song return evt_num; 1593668b8788SArnaldo Carvalho de Melo } 1594668b8788SArnaldo Carvalho de Melo 1595705750f2SYunlong Song void print_symbol_events(const char *event_glob, unsigned type, 1596a3277d2dSFrederic Weisbecker struct event_symbol *syms, unsigned max, 1597a3277d2dSFrederic Weisbecker bool name_only) 159886470930SIngo Molnar { 1599ab0e4800SYunlong Song unsigned int i, evt_i = 0, evt_num = 0; 1600947b4ad1SIngo Molnar char name[MAX_NAME_LEN]; 1601ab0e4800SYunlong Song char **evt_list = NULL; 1602ab0e4800SYunlong Song bool evt_num_known = false; 1603ab0e4800SYunlong Song 1604ab0e4800SYunlong Song restart: 1605ab0e4800SYunlong Song if (evt_num_known) { 1606ab0e4800SYunlong Song evt_list = zalloc(sizeof(char *) * evt_num); 1607ab0e4800SYunlong Song if (!evt_list) 1608ab0e4800SYunlong Song goto out_enomem; 1609ab0e4800SYunlong Song syms -= max; 1610ab0e4800SYunlong Song } 161186470930SIngo Molnar 16121dc12760SJiri Olsa for (i = 0; i < max; i++, syms++) { 1613668b8788SArnaldo Carvalho de Melo 1614668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 1615668b8788SArnaldo Carvalho de Melo !(strglobmatch(syms->symbol, event_glob) || 1616668b8788SArnaldo Carvalho de Melo (syms->alias && strglobmatch(syms->alias, event_glob)))) 1617668b8788SArnaldo Carvalho de Melo continue; 161886470930SIngo Molnar 1619b41f1cecSNamhyung Kim if (!is_event_supported(type, i)) 1620b41f1cecSNamhyung Kim continue; 1621b41f1cecSNamhyung Kim 1622ab0e4800SYunlong Song if (!evt_num_known) { 1623ab0e4800SYunlong Song evt_num++; 1624a3277d2dSFrederic Weisbecker continue; 1625a3277d2dSFrederic Weisbecker } 1626a3277d2dSFrederic Weisbecker 1627ab0e4800SYunlong Song if (!name_only && strlen(syms->alias)) 1628947b4ad1SIngo Molnar snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 162974d5b588SJaswinder Singh Rajput else 1630947b4ad1SIngo Molnar strncpy(name, syms->symbol, MAX_NAME_LEN); 163186470930SIngo Molnar 1632ab0e4800SYunlong Song evt_list[evt_i] = strdup(name); 1633ab0e4800SYunlong Song if (evt_list[evt_i] == NULL) 1634ab0e4800SYunlong Song goto out_enomem; 1635ab0e4800SYunlong Song evt_i++; 163686470930SIngo Molnar } 163786470930SIngo Molnar 1638ab0e4800SYunlong Song if (!evt_num_known) { 1639ab0e4800SYunlong Song evt_num_known = true; 1640ab0e4800SYunlong Song goto restart; 1641ab0e4800SYunlong Song } 1642ab0e4800SYunlong Song qsort(evt_list, evt_num, sizeof(char *), cmp_string); 1643ab0e4800SYunlong Song evt_i = 0; 1644ab0e4800SYunlong Song while (evt_i < evt_num) { 1645ab0e4800SYunlong Song if (name_only) { 1646ab0e4800SYunlong Song printf("%s ", evt_list[evt_i++]); 1647ab0e4800SYunlong Song continue; 1648ab0e4800SYunlong Song } 1649ab0e4800SYunlong Song printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); 1650ab0e4800SYunlong Song } 1651ab0e4800SYunlong Song if (evt_num) 1652689d3018SMarti Raudsepp printf("\n"); 1653ab0e4800SYunlong Song 1654ab0e4800SYunlong Song out_free: 1655ab0e4800SYunlong Song evt_num = evt_i; 1656ab0e4800SYunlong Song for (evt_i = 0; evt_i < evt_num; evt_i++) 1657ab0e4800SYunlong Song zfree(&evt_list[evt_i]); 1658ab0e4800SYunlong Song zfree(&evt_list); 1659ab0e4800SYunlong Song return; 1660ab0e4800SYunlong Song 1661ab0e4800SYunlong Song out_enomem: 1662ab0e4800SYunlong Song printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); 1663ab0e4800SYunlong Song if (evt_list) 1664ab0e4800SYunlong Song goto out_free; 1665668b8788SArnaldo Carvalho de Melo } 16661dc12760SJiri Olsa 16671dc12760SJiri Olsa /* 16681dc12760SJiri Olsa * Print the help text for the event symbols: 16691dc12760SJiri Olsa */ 1670a3277d2dSFrederic Weisbecker void print_events(const char *event_glob, bool name_only) 16711dc12760SJiri Olsa { 16721dc12760SJiri Olsa print_symbol_events(event_glob, PERF_TYPE_HARDWARE, 1673a3277d2dSFrederic Weisbecker event_symbols_hw, PERF_COUNT_HW_MAX, name_only); 16741dc12760SJiri Olsa 16751dc12760SJiri Olsa print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, 1676a3277d2dSFrederic Weisbecker event_symbols_sw, PERF_COUNT_SW_MAX, name_only); 16771dc12760SJiri Olsa 1678a3277d2dSFrederic Weisbecker print_hwcache_events(event_glob, name_only); 167973c24cb8SJaswinder Singh Rajput 1680dc098b35SAndi Kleen print_pmu_events(event_glob, name_only); 1681dc098b35SAndi Kleen 1682668b8788SArnaldo Carvalho de Melo if (event_glob != NULL) 1683668b8788SArnaldo Carvalho de Melo return; 168473c24cb8SJaswinder Singh Rajput 1685a3277d2dSFrederic Weisbecker if (!name_only) { 1686947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 16875f537a26SJiri Olsa "rNNN", 16881cf4a063SArnaldo Carvalho de Melo event_type_descriptors[PERF_TYPE_RAW]); 16895f537a26SJiri Olsa printf(" %-50s [%s]\n", 16905f537a26SJiri Olsa "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 16915f537a26SJiri Olsa event_type_descriptors[PERF_TYPE_RAW]); 1692af3df2cfSBorislav Petkov printf(" (see 'man perf-list' on how to encode it)\n"); 1693689d3018SMarti Raudsepp printf("\n"); 169486470930SIngo Molnar 1695947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 16963741eb9fSJacob Shin "mem:<addr>[/len][:access]", 169741bdcb23SLiming Wang event_type_descriptors[PERF_TYPE_BREAKPOINT]); 16981b290d67SFrederic Weisbecker printf("\n"); 1699a3277d2dSFrederic Weisbecker } 17001b290d67SFrederic Weisbecker 1701a3277d2dSFrederic Weisbecker print_tracepoint_events(NULL, NULL, name_only); 170286470930SIngo Molnar } 17038f707d84SJiri Olsa 17046cee6cd3SArnaldo Carvalho de Melo int parse_events__is_hardcoded_term(struct parse_events_term *term) 17058f707d84SJiri Olsa { 170616fa7e82SJiri Olsa return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; 17078f707d84SJiri Olsa } 17088f707d84SJiri Olsa 17096cee6cd3SArnaldo Carvalho de Melo static int new_term(struct parse_events_term **_term, int type_val, 171016fa7e82SJiri Olsa int type_term, char *config, 1711cecf3a2eSJiri Olsa char *str, u64 num, int err_term, int err_val) 17128f707d84SJiri Olsa { 17136cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term; 17148f707d84SJiri Olsa 17158f707d84SJiri Olsa term = zalloc(sizeof(*term)); 17168f707d84SJiri Olsa if (!term) 17178f707d84SJiri Olsa return -ENOMEM; 17188f707d84SJiri Olsa 17198f707d84SJiri Olsa INIT_LIST_HEAD(&term->list); 172016fa7e82SJiri Olsa term->type_val = type_val; 172116fa7e82SJiri Olsa term->type_term = type_term; 17228f707d84SJiri Olsa term->config = config; 1723cecf3a2eSJiri Olsa term->err_term = err_term; 1724cecf3a2eSJiri Olsa term->err_val = err_val; 17258f707d84SJiri Olsa 172616fa7e82SJiri Olsa switch (type_val) { 17278f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_NUM: 17288f707d84SJiri Olsa term->val.num = num; 17298f707d84SJiri Olsa break; 17308f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_STR: 17318f707d84SJiri Olsa term->val.str = str; 17328f707d84SJiri Olsa break; 17338f707d84SJiri Olsa default: 17344be8be6bSAdrian Hunter free(term); 17358f707d84SJiri Olsa return -EINVAL; 17368f707d84SJiri Olsa } 17378f707d84SJiri Olsa 17388f707d84SJiri Olsa *_term = term; 17398f707d84SJiri Olsa return 0; 17408f707d84SJiri Olsa } 17418f707d84SJiri Olsa 17426cee6cd3SArnaldo Carvalho de Melo int parse_events_term__num(struct parse_events_term **term, 1743cecf3a2eSJiri Olsa int type_term, char *config, u64 num, 1744bb78ce7dSAdrian Hunter void *loc_term_, void *loc_val_) 174516fa7e82SJiri Olsa { 1746bb78ce7dSAdrian Hunter YYLTYPE *loc_term = loc_term_; 1747bb78ce7dSAdrian Hunter YYLTYPE *loc_val = loc_val_; 1748bb78ce7dSAdrian Hunter 174916fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, 1750cecf3a2eSJiri Olsa config, NULL, num, 1751cecf3a2eSJiri Olsa loc_term ? loc_term->first_column : 0, 1752cecf3a2eSJiri Olsa loc_val ? loc_val->first_column : 0); 175316fa7e82SJiri Olsa } 175416fa7e82SJiri Olsa 17556cee6cd3SArnaldo Carvalho de Melo int parse_events_term__str(struct parse_events_term **term, 1756cecf3a2eSJiri Olsa int type_term, char *config, char *str, 1757bb78ce7dSAdrian Hunter void *loc_term_, void *loc_val_) 175816fa7e82SJiri Olsa { 1759bb78ce7dSAdrian Hunter YYLTYPE *loc_term = loc_term_; 1760bb78ce7dSAdrian Hunter YYLTYPE *loc_val = loc_val_; 1761bb78ce7dSAdrian Hunter 176216fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, 1763cecf3a2eSJiri Olsa config, str, 0, 1764cecf3a2eSJiri Olsa loc_term ? loc_term->first_column : 0, 1765cecf3a2eSJiri Olsa loc_val ? loc_val->first_column : 0); 176616fa7e82SJiri Olsa } 176716fa7e82SJiri Olsa 17686cee6cd3SArnaldo Carvalho de Melo int parse_events_term__sym_hw(struct parse_events_term **term, 17691d33d6dcSJiri Olsa char *config, unsigned idx) 17701d33d6dcSJiri Olsa { 17711d33d6dcSJiri Olsa struct event_symbol *sym; 17721d33d6dcSJiri Olsa 17731d33d6dcSJiri Olsa BUG_ON(idx >= PERF_COUNT_HW_MAX); 17741d33d6dcSJiri Olsa sym = &event_symbols_hw[idx]; 17751d33d6dcSJiri Olsa 17761d33d6dcSJiri Olsa if (config) 17771d33d6dcSJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 17781d33d6dcSJiri Olsa PARSE_EVENTS__TERM_TYPE_USER, config, 1779cecf3a2eSJiri Olsa (char *) sym->symbol, 0, 0, 0); 17801d33d6dcSJiri Olsa else 17811d33d6dcSJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, 17821d33d6dcSJiri Olsa PARSE_EVENTS__TERM_TYPE_USER, 1783cecf3a2eSJiri Olsa (char *) "event", (char *) sym->symbol, 1784cecf3a2eSJiri Olsa 0, 0, 0); 17851d33d6dcSJiri Olsa } 17861d33d6dcSJiri Olsa 17876cee6cd3SArnaldo Carvalho de Melo int parse_events_term__clone(struct parse_events_term **new, 17886cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term) 1789a6146d50SZheng Yan { 1790a6146d50SZheng Yan return new_term(new, term->type_val, term->type_term, term->config, 1791cecf3a2eSJiri Olsa term->val.str, term->val.num, 1792cecf3a2eSJiri Olsa term->err_term, term->err_val); 1793a6146d50SZheng Yan } 1794a6146d50SZheng Yan 17958f707d84SJiri Olsa void parse_events__free_terms(struct list_head *terms) 17968f707d84SJiri Olsa { 17976cee6cd3SArnaldo Carvalho de Melo struct parse_events_term *term, *h; 17988f707d84SJiri Olsa 17998f707d84SJiri Olsa list_for_each_entry_safe(term, h, terms, list) 18008f707d84SJiri Olsa free(term); 18018f707d84SJiri Olsa } 1802b39b8393SJiri Olsa 1803b39b8393SJiri Olsa void parse_events_evlist_error(struct parse_events_evlist *data, 1804b39b8393SJiri Olsa int idx, const char *str) 1805b39b8393SJiri Olsa { 1806b39b8393SJiri Olsa struct parse_events_error *err = data->error; 1807b39b8393SJiri Olsa 1808a6ced2beSAdrian Hunter if (!err) 1809a6ced2beSAdrian Hunter return; 1810b39b8393SJiri Olsa err->idx = idx; 1811b39b8393SJiri Olsa err->str = strdup(str); 1812b39b8393SJiri Olsa WARN_ONCE(!err->str, "WARNING: failed to allocate error string"); 1813b39b8393SJiri Olsa } 1814