11b290d67SFrederic Weisbecker #include "../../../include/linux/hw_breakpoint.h" 286470930SIngo Molnar #include "util.h" 36b58e7f1SUlrich Drepper #include "../perf.h" 4361c99a6SArnaldo Carvalho de Melo #include "evlist.h" 569aad6f1SArnaldo Carvalho de Melo #include "evsel.h" 686470930SIngo Molnar #include "parse-options.h" 786470930SIngo Molnar #include "parse-events.h" 886470930SIngo Molnar #include "exec_cmd.h" 986470930SIngo Molnar #include "string.h" 105aab621bSArnaldo Carvalho de Melo #include "symbol.h" 115beeded1SJason Baron #include "cache.h" 128755a8f2SArjan van de Ven #include "header.h" 13549104f2SClark Williams #include "debugfs.h" 1489812fc8SJiri Olsa #include "parse-events-flex.h" 155f537a26SJiri Olsa #include "pmu.h" 1689812fc8SJiri Olsa 1789812fc8SJiri Olsa #define MAX_NAME_LEN 100 1886470930SIngo Molnar 1986470930SIngo Molnar struct event_symbol { 209cffa8d5SPaul Mackerras u8 type; 219cffa8d5SPaul Mackerras u64 config; 2283a0944fSIngo Molnar const char *symbol; 2383a0944fSIngo Molnar const char *alias; 2486470930SIngo Molnar }; 2586470930SIngo Molnar 2682ba1f2fSJiri Olsa #ifdef PARSER_DEBUG 2782ba1f2fSJiri Olsa extern int parse_events_debug; 2882ba1f2fSJiri Olsa #endif 29*46010ab2SJiri Olsa int parse_events_parse(void *data); 30bcd3279fSFrederic Weisbecker 3151e26842SJaswinder Singh Rajput #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x 3251e26842SJaswinder Singh Rajput #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 3386470930SIngo Molnar 3486470930SIngo Molnar static struct event_symbol event_symbols[] = { 3574d5b588SJaswinder Singh Rajput { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, 36129c04cbSIngo Molnar { CHW(STALLED_CYCLES_FRONTEND), "stalled-cycles-frontend", "idle-cycles-frontend" }, 37129c04cbSIngo Molnar { CHW(STALLED_CYCLES_BACKEND), "stalled-cycles-backend", "idle-cycles-backend" }, 3874d5b588SJaswinder Singh Rajput { CHW(INSTRUCTIONS), "instructions", "" }, 3974d5b588SJaswinder Singh Rajput { CHW(CACHE_REFERENCES), "cache-references", "" }, 4074d5b588SJaswinder Singh Rajput { CHW(CACHE_MISSES), "cache-misses", "" }, 4174d5b588SJaswinder Singh Rajput { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, 4274d5b588SJaswinder Singh Rajput { CHW(BRANCH_MISSES), "branch-misses", "" }, 4374d5b588SJaswinder Singh Rajput { CHW(BUS_CYCLES), "bus-cycles", "" }, 44f1ac18afSStephane Eranian { CHW(REF_CPU_CYCLES), "ref-cycles", "" }, 4586470930SIngo Molnar 4674d5b588SJaswinder Singh Rajput { CSW(CPU_CLOCK), "cpu-clock", "" }, 4774d5b588SJaswinder Singh Rajput { CSW(TASK_CLOCK), "task-clock", "" }, 48c0c22dbfSJaswinder Singh Rajput { CSW(PAGE_FAULTS), "page-faults", "faults" }, 4974d5b588SJaswinder Singh Rajput { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, 5074d5b588SJaswinder Singh Rajput { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, 5174d5b588SJaswinder Singh Rajput { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, 5274d5b588SJaswinder Singh Rajput { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 53f7d79860SAnton Blanchard { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" }, 54f7d79860SAnton Blanchard { CSW(EMULATION_FAULTS), "emulation-faults", "" }, 5586470930SIngo Molnar }; 5686470930SIngo Molnar 57cdd6c482SIngo Molnar #define __PERF_EVENT_FIELD(config, name) \ 58cdd6c482SIngo Molnar ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 5986470930SIngo Molnar 60cdd6c482SIngo Molnar #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 61cdd6c482SIngo Molnar #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 62cdd6c482SIngo Molnar #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 63cdd6c482SIngo Molnar #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 6486470930SIngo Molnar 65d3d1e86dSIngo Molnar static const char *sw_event_names[PERF_COUNT_SW_MAX] = { 66749141d9SIngo Molnar "cpu-clock", 67749141d9SIngo Molnar "task-clock", 6886470930SIngo Molnar "page-faults", 6986470930SIngo Molnar "context-switches", 7086470930SIngo Molnar "CPU-migrations", 7186470930SIngo Molnar "minor-faults", 7286470930SIngo Molnar "major-faults", 73f7d79860SAnton Blanchard "alignment-faults", 74f7d79860SAnton Blanchard "emulation-faults", 7586470930SIngo Molnar }; 7686470930SIngo Molnar 7786470930SIngo Molnar #define MAX_ALIASES 8 7886470930SIngo Molnar 790111919dSJiri Olsa static const char *hw_cache[PERF_COUNT_HW_CACHE_MAX][MAX_ALIASES] = { 809590b7baSAnton Blanchard { "L1-dcache", "l1-d", "l1d", "L1-data", }, 819590b7baSAnton Blanchard { "L1-icache", "l1-i", "l1i", "L1-instruction", }, 820111919dSJiri Olsa { "LLC", "L2", }, 83e5c59547SJaswinder Singh Rajput { "dTLB", "d-tlb", "Data-TLB", }, 84e5c59547SJaswinder Singh Rajput { "iTLB", "i-tlb", "Instruction-TLB", }, 85e5c59547SJaswinder Singh Rajput { "branch", "branches", "bpu", "btb", "bpc", }, 860111919dSJiri Olsa { "node", }, 8786470930SIngo Molnar }; 8886470930SIngo Molnar 890111919dSJiri Olsa static const char *hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][MAX_ALIASES] = { 90e5c59547SJaswinder Singh Rajput { "load", "loads", "read", }, 91e5c59547SJaswinder Singh Rajput { "store", "stores", "write", }, 92e5c59547SJaswinder Singh Rajput { "prefetch", "prefetches", "speculative-read", "speculative-load", }, 9386470930SIngo Molnar }; 9486470930SIngo Molnar 950111919dSJiri Olsa static const char *hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] 960111919dSJiri Olsa [MAX_ALIASES] = { 97e5c59547SJaswinder Singh Rajput { "refs", "Reference", "ops", "access", }, 98e5c59547SJaswinder Singh Rajput { "misses", "miss", }, 9986470930SIngo Molnar }; 10086470930SIngo Molnar 10106813f6cSJaswinder Singh Rajput #define C(x) PERF_COUNT_HW_CACHE_##x 10206813f6cSJaswinder Singh Rajput #define CACHE_READ (1 << C(OP_READ)) 10306813f6cSJaswinder Singh Rajput #define CACHE_WRITE (1 << C(OP_WRITE)) 10406813f6cSJaswinder Singh Rajput #define CACHE_PREFETCH (1 << C(OP_PREFETCH)) 10506813f6cSJaswinder Singh Rajput #define COP(x) (1 << x) 10606813f6cSJaswinder Singh Rajput 10706813f6cSJaswinder Singh Rajput /* 10806813f6cSJaswinder Singh Rajput * cache operartion stat 10906813f6cSJaswinder Singh Rajput * L1I : Read and prefetch only 11006813f6cSJaswinder Singh Rajput * ITLB and BPU : Read-only 11106813f6cSJaswinder Singh Rajput */ 11206813f6cSJaswinder Singh Rajput static unsigned long hw_cache_stat[C(MAX)] = { 11306813f6cSJaswinder Singh Rajput [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 11406813f6cSJaswinder Singh Rajput [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), 11506813f6cSJaswinder Singh Rajput [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 11606813f6cSJaswinder Singh Rajput [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 11706813f6cSJaswinder Singh Rajput [C(ITLB)] = (CACHE_READ), 11806813f6cSJaswinder Singh Rajput [C(BPU)] = (CACHE_READ), 1190111919dSJiri Olsa [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 12006813f6cSJaswinder Singh Rajput }; 12106813f6cSJaswinder Singh Rajput 1226b58e7f1SUlrich Drepper #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 123f6bdafefSJason Baron while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 1246b58e7f1SUlrich Drepper if (sys_dirent.d_type == DT_DIR && \ 125f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".")) && \ 126f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".."))) 127f6bdafefSJason Baron 128ae07b63fSPeter Zijlstra static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 129ae07b63fSPeter Zijlstra { 130ae07b63fSPeter Zijlstra char evt_path[MAXPATHLEN]; 131ae07b63fSPeter Zijlstra int fd; 132ae07b63fSPeter Zijlstra 133ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path, 134ae07b63fSPeter Zijlstra sys_dir->d_name, evt_dir->d_name); 135ae07b63fSPeter Zijlstra fd = open(evt_path, O_RDONLY); 136ae07b63fSPeter Zijlstra if (fd < 0) 137ae07b63fSPeter Zijlstra return -EINVAL; 138ae07b63fSPeter Zijlstra close(fd); 139ae07b63fSPeter Zijlstra 140ae07b63fSPeter Zijlstra return 0; 141ae07b63fSPeter Zijlstra } 142ae07b63fSPeter Zijlstra 1436b58e7f1SUlrich Drepper #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ 144f6bdafefSJason Baron while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 1456b58e7f1SUlrich Drepper if (evt_dirent.d_type == DT_DIR && \ 146f6bdafefSJason Baron (strcmp(evt_dirent.d_name, ".")) && \ 147ae07b63fSPeter Zijlstra (strcmp(evt_dirent.d_name, "..")) && \ 148ae07b63fSPeter Zijlstra (!tp_event_has_id(&sys_dirent, &evt_dirent))) 149f6bdafefSJason Baron 150270bbbe8SLi Zefan #define MAX_EVENT_LENGTH 512 151f6bdafefSJason Baron 152f6bdafefSJason Baron 1531ef2ed10SFrederic Weisbecker struct tracepoint_path *tracepoint_id_to_path(u64 config) 154f6bdafefSJason Baron { 1551ef2ed10SFrederic Weisbecker struct tracepoint_path *path = NULL; 156f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 157f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1588aa8a7c8SStephane Eranian char id_buf[24]; 159725b1368SEric Dumazet int fd; 160f6bdafefSJason Baron u64 id; 161f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 162725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 163f6bdafefSJason Baron 164ebf294bfSArnaldo Carvalho de Melo if (debugfs_valid_mountpoint(tracing_events_path)) 1651ef2ed10SFrederic Weisbecker return NULL; 166f6bdafefSJason Baron 167ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 168f6bdafefSJason Baron if (!sys_dir) 169725b1368SEric Dumazet return NULL; 170f6bdafefSJason Baron 1716b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 172725b1368SEric Dumazet 173ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 174725b1368SEric Dumazet sys_dirent.d_name); 175725b1368SEric Dumazet evt_dir = opendir(dir_path); 176725b1368SEric Dumazet if (!evt_dir) 1776b58e7f1SUlrich Drepper continue; 178725b1368SEric Dumazet 1796b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 180725b1368SEric Dumazet 181725b1368SEric Dumazet snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 182f6bdafefSJason Baron evt_dirent.d_name); 183725b1368SEric Dumazet fd = open(evt_path, O_RDONLY); 184f6bdafefSJason Baron if (fd < 0) 185f6bdafefSJason Baron continue; 186f6bdafefSJason Baron if (read(fd, id_buf, sizeof(id_buf)) < 0) { 187f6bdafefSJason Baron close(fd); 188f6bdafefSJason Baron continue; 189f6bdafefSJason Baron } 190f6bdafefSJason Baron close(fd); 191f6bdafefSJason Baron id = atoll(id_buf); 192f6bdafefSJason Baron if (id == config) { 193f6bdafefSJason Baron closedir(evt_dir); 194f6bdafefSJason Baron closedir(sys_dir); 19559b4caebSJulia Lawall path = zalloc(sizeof(*path)); 1961ef2ed10SFrederic Weisbecker path->system = malloc(MAX_EVENT_LENGTH); 1971ef2ed10SFrederic Weisbecker if (!path->system) { 1981ef2ed10SFrederic Weisbecker free(path); 1991ef2ed10SFrederic Weisbecker return NULL; 2001ef2ed10SFrederic Weisbecker } 2011ef2ed10SFrederic Weisbecker path->name = malloc(MAX_EVENT_LENGTH); 2021ef2ed10SFrederic Weisbecker if (!path->name) { 2031ef2ed10SFrederic Weisbecker free(path->system); 2041ef2ed10SFrederic Weisbecker free(path); 2051ef2ed10SFrederic Weisbecker return NULL; 2061ef2ed10SFrederic Weisbecker } 2071ef2ed10SFrederic Weisbecker strncpy(path->system, sys_dirent.d_name, 2081ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2091ef2ed10SFrederic Weisbecker strncpy(path->name, evt_dirent.d_name, 2101ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2111ef2ed10SFrederic Weisbecker return path; 212f6bdafefSJason Baron } 213f6bdafefSJason Baron } 214f6bdafefSJason Baron closedir(evt_dir); 215f6bdafefSJason Baron } 216f6bdafefSJason Baron 217f6bdafefSJason Baron closedir(sys_dir); 2181ef2ed10SFrederic Weisbecker return NULL; 2191ef2ed10SFrederic Weisbecker } 2201ef2ed10SFrederic Weisbecker 2211ef2ed10SFrederic Weisbecker #define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1) 2221ef2ed10SFrederic Weisbecker static const char *tracepoint_id_to_name(u64 config) 2231ef2ed10SFrederic Weisbecker { 2241ef2ed10SFrederic Weisbecker static char buf[TP_PATH_LEN]; 2251ef2ed10SFrederic Weisbecker struct tracepoint_path *path; 2261ef2ed10SFrederic Weisbecker 2271ef2ed10SFrederic Weisbecker path = tracepoint_id_to_path(config); 2281ef2ed10SFrederic Weisbecker if (path) { 2291ef2ed10SFrederic Weisbecker snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name); 2301ef2ed10SFrederic Weisbecker free(path->name); 2311ef2ed10SFrederic Weisbecker free(path->system); 2321ef2ed10SFrederic Weisbecker free(path); 2331ef2ed10SFrederic Weisbecker } else 2341ef2ed10SFrederic Weisbecker snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown"); 2351ef2ed10SFrederic Weisbecker 2361ef2ed10SFrederic Weisbecker return buf; 237f6bdafefSJason Baron } 238f6bdafefSJason Baron 23906813f6cSJaswinder Singh Rajput static int is_cache_op_valid(u8 cache_type, u8 cache_op) 24006813f6cSJaswinder Singh Rajput { 24106813f6cSJaswinder Singh Rajput if (hw_cache_stat[cache_type] & COP(cache_op)) 24206813f6cSJaswinder Singh Rajput return 1; /* valid */ 24306813f6cSJaswinder Singh Rajput else 24406813f6cSJaswinder Singh Rajput return 0; /* invalid */ 24506813f6cSJaswinder Singh Rajput } 24606813f6cSJaswinder Singh Rajput 247e5c59547SJaswinder Singh Rajput static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result) 248e5c59547SJaswinder Singh Rajput { 249e5c59547SJaswinder Singh Rajput static char name[50]; 250e5c59547SJaswinder Singh Rajput 251e5c59547SJaswinder Singh Rajput if (cache_result) { 252e5c59547SJaswinder Singh Rajput sprintf(name, "%s-%s-%s", hw_cache[cache_type][0], 253e5c59547SJaswinder Singh Rajput hw_cache_op[cache_op][0], 254e5c59547SJaswinder Singh Rajput hw_cache_result[cache_result][0]); 255e5c59547SJaswinder Singh Rajput } else { 256e5c59547SJaswinder Singh Rajput sprintf(name, "%s-%s", hw_cache[cache_type][0], 257e5c59547SJaswinder Singh Rajput hw_cache_op[cache_op][1]); 258e5c59547SJaswinder Singh Rajput } 259e5c59547SJaswinder Singh Rajput 260e5c59547SJaswinder Singh Rajput return name; 261e5c59547SJaswinder Singh Rajput } 262e5c59547SJaswinder Singh Rajput 2631424dc96SDavid Ahern const char *event_type(int type) 2641424dc96SDavid Ahern { 2651424dc96SDavid Ahern switch (type) { 2661424dc96SDavid Ahern case PERF_TYPE_HARDWARE: 2671424dc96SDavid Ahern return "hardware"; 2681424dc96SDavid Ahern 2691424dc96SDavid Ahern case PERF_TYPE_SOFTWARE: 2701424dc96SDavid Ahern return "software"; 2711424dc96SDavid Ahern 2721424dc96SDavid Ahern case PERF_TYPE_TRACEPOINT: 2731424dc96SDavid Ahern return "tracepoint"; 2741424dc96SDavid Ahern 2751424dc96SDavid Ahern case PERF_TYPE_HW_CACHE: 2761424dc96SDavid Ahern return "hardware-cache"; 2771424dc96SDavid Ahern 2781424dc96SDavid Ahern default: 2791424dc96SDavid Ahern break; 2801424dc96SDavid Ahern } 2811424dc96SDavid Ahern 2821424dc96SDavid Ahern return "unknown"; 2831424dc96SDavid Ahern } 2841424dc96SDavid Ahern 28569aad6f1SArnaldo Carvalho de Melo const char *event_name(struct perf_evsel *evsel) 28686470930SIngo Molnar { 28769aad6f1SArnaldo Carvalho de Melo u64 config = evsel->attr.config; 28869aad6f1SArnaldo Carvalho de Melo int type = evsel->attr.type; 2898f18aec5SPeter Zijlstra 290c410431cSArnaldo Carvalho de Melo if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE) { 291c410431cSArnaldo Carvalho de Melo /* 292c410431cSArnaldo Carvalho de Melo * XXX minimal fix, see comment on perf_evsen__name, this static buffer 293c410431cSArnaldo Carvalho de Melo * will go away together with event_name in the next devel cycle. 294c410431cSArnaldo Carvalho de Melo */ 295c410431cSArnaldo Carvalho de Melo static char bf[128]; 296c410431cSArnaldo Carvalho de Melo perf_evsel__name(evsel, bf, sizeof(bf)); 297c410431cSArnaldo Carvalho de Melo return bf; 298c410431cSArnaldo Carvalho de Melo } 299c410431cSArnaldo Carvalho de Melo 300f0c55bcfSStephane Eranian if (evsel->name) 301f0c55bcfSStephane Eranian return evsel->name; 302f0c55bcfSStephane Eranian 3038f18aec5SPeter Zijlstra return __event_name(type, config); 3048f18aec5SPeter Zijlstra } 3058f18aec5SPeter Zijlstra 30683a0944fSIngo Molnar const char *__event_name(int type, u64 config) 3078f18aec5SPeter Zijlstra { 30886470930SIngo Molnar static char buf[32]; 30986470930SIngo Molnar 3108f18aec5SPeter Zijlstra if (type == PERF_TYPE_RAW) { 3119486aa38SArnaldo Carvalho de Melo sprintf(buf, "raw 0x%" PRIx64, config); 31286470930SIngo Molnar return buf; 31386470930SIngo Molnar } 31486470930SIngo Molnar 31586470930SIngo Molnar switch (type) { 31686470930SIngo Molnar case PERF_TYPE_HARDWARE: 317c410431cSArnaldo Carvalho de Melo return __perf_evsel__hw_name(config); 31886470930SIngo Molnar 31986470930SIngo Molnar case PERF_TYPE_HW_CACHE: { 3209cffa8d5SPaul Mackerras u8 cache_type, cache_op, cache_result; 32186470930SIngo Molnar 32286470930SIngo Molnar cache_type = (config >> 0) & 0xff; 32386470930SIngo Molnar if (cache_type > PERF_COUNT_HW_CACHE_MAX) 32486470930SIngo Molnar return "unknown-ext-hardware-cache-type"; 32586470930SIngo Molnar 32686470930SIngo Molnar cache_op = (config >> 8) & 0xff; 32786470930SIngo Molnar if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX) 32886470930SIngo Molnar return "unknown-ext-hardware-cache-op"; 32986470930SIngo Molnar 33086470930SIngo Molnar cache_result = (config >> 16) & 0xff; 33186470930SIngo Molnar if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX) 33286470930SIngo Molnar return "unknown-ext-hardware-cache-result"; 33386470930SIngo Molnar 33406813f6cSJaswinder Singh Rajput if (!is_cache_op_valid(cache_type, cache_op)) 33506813f6cSJaswinder Singh Rajput return "invalid-cache"; 33686470930SIngo Molnar 337e5c59547SJaswinder Singh Rajput return event_cache_name(cache_type, cache_op, cache_result); 33886470930SIngo Molnar } 33986470930SIngo Molnar 34086470930SIngo Molnar case PERF_TYPE_SOFTWARE: 3411fc570adSIngo Molnar if (config < PERF_COUNT_SW_MAX && sw_event_names[config]) 34286470930SIngo Molnar return sw_event_names[config]; 34386470930SIngo Molnar return "unknown-software"; 34486470930SIngo Molnar 345f6bdafefSJason Baron case PERF_TYPE_TRACEPOINT: 346f6bdafefSJason Baron return tracepoint_id_to_name(config); 347f6bdafefSJason Baron 34886470930SIngo Molnar default: 34986470930SIngo Molnar break; 35086470930SIngo Molnar } 35186470930SIngo Molnar 35286470930SIngo Molnar return "unknown"; 35386470930SIngo Molnar } 35486470930SIngo Molnar 355b847cbdcSJiri Olsa static int add_event(struct list_head **_list, int *idx, 35689812fc8SJiri Olsa struct perf_event_attr *attr, char *name) 35789812fc8SJiri Olsa { 35889812fc8SJiri Olsa struct perf_evsel *evsel; 359b847cbdcSJiri Olsa struct list_head *list = *_list; 360b847cbdcSJiri Olsa 361b847cbdcSJiri Olsa if (!list) { 362b847cbdcSJiri Olsa list = malloc(sizeof(*list)); 363b847cbdcSJiri Olsa if (!list) 364b847cbdcSJiri Olsa return -ENOMEM; 365b847cbdcSJiri Olsa INIT_LIST_HEAD(list); 366b847cbdcSJiri Olsa } 36789812fc8SJiri Olsa 36889812fc8SJiri Olsa event_attr_init(attr); 36989812fc8SJiri Olsa 37089812fc8SJiri Olsa evsel = perf_evsel__new(attr, (*idx)++); 371b847cbdcSJiri Olsa if (!evsel) { 372b847cbdcSJiri Olsa free(list); 37389812fc8SJiri Olsa return -ENOMEM; 374b847cbdcSJiri Olsa } 37589812fc8SJiri Olsa 37689812fc8SJiri Olsa evsel->name = strdup(name); 377b847cbdcSJiri Olsa list_add_tail(&evsel->node, list); 378b847cbdcSJiri Olsa *_list = list; 37989812fc8SJiri Olsa return 0; 38089812fc8SJiri Olsa } 38189812fc8SJiri Olsa 38289812fc8SJiri Olsa static int parse_aliases(char *str, const char *names[][MAX_ALIASES], int size) 38386470930SIngo Molnar { 38486470930SIngo Molnar int i, j; 38561c45981SPaul Mackerras int n, longest = -1; 38686470930SIngo Molnar 38786470930SIngo Molnar for (i = 0; i < size; i++) { 38861c45981SPaul Mackerras for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { 38961c45981SPaul Mackerras n = strlen(names[i][j]); 39089812fc8SJiri Olsa if (n > longest && !strncasecmp(str, names[i][j], n)) 39161c45981SPaul Mackerras longest = n; 39261c45981SPaul Mackerras } 39389812fc8SJiri Olsa if (longest > 0) 39486470930SIngo Molnar return i; 39586470930SIngo Molnar } 39686470930SIngo Molnar 3978953645fSIngo Molnar return -1; 39886470930SIngo Molnar } 39986470930SIngo Molnar 400b847cbdcSJiri Olsa int parse_events_add_cache(struct list_head **list, int *idx, 40189812fc8SJiri Olsa char *type, char *op_result1, char *op_result2) 40286470930SIngo Molnar { 40389812fc8SJiri Olsa struct perf_event_attr attr; 40489812fc8SJiri Olsa char name[MAX_NAME_LEN]; 40561c45981SPaul Mackerras int cache_type = -1, cache_op = -1, cache_result = -1; 40689812fc8SJiri Olsa char *op_result[2] = { op_result1, op_result2 }; 40789812fc8SJiri Olsa int i, n; 40886470930SIngo Molnar 40986470930SIngo Molnar /* 41086470930SIngo Molnar * No fallback - if we cannot get a clear cache type 41186470930SIngo Molnar * then bail out: 41286470930SIngo Molnar */ 41389812fc8SJiri Olsa cache_type = parse_aliases(type, hw_cache, 41489812fc8SJiri Olsa PERF_COUNT_HW_CACHE_MAX); 41586470930SIngo Molnar if (cache_type == -1) 41689812fc8SJiri Olsa return -EINVAL; 41786470930SIngo Molnar 41889812fc8SJiri Olsa n = snprintf(name, MAX_NAME_LEN, "%s", type); 41989812fc8SJiri Olsa 42089812fc8SJiri Olsa for (i = 0; (i < 2) && (op_result[i]); i++) { 42189812fc8SJiri Olsa char *str = op_result[i]; 42289812fc8SJiri Olsa 42389812fc8SJiri Olsa snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); 42461c45981SPaul Mackerras 42561c45981SPaul Mackerras if (cache_op == -1) { 42689812fc8SJiri Olsa cache_op = parse_aliases(str, hw_cache_op, 42761c45981SPaul Mackerras PERF_COUNT_HW_CACHE_OP_MAX); 42861c45981SPaul Mackerras if (cache_op >= 0) { 42961c45981SPaul Mackerras if (!is_cache_op_valid(cache_type, cache_op)) 43089812fc8SJiri Olsa return -EINVAL; 43161c45981SPaul Mackerras continue; 43261c45981SPaul Mackerras } 43361c45981SPaul Mackerras } 43461c45981SPaul Mackerras 43561c45981SPaul Mackerras if (cache_result == -1) { 43689812fc8SJiri Olsa cache_result = parse_aliases(str, hw_cache_result, 43761c45981SPaul Mackerras PERF_COUNT_HW_CACHE_RESULT_MAX); 43861c45981SPaul Mackerras if (cache_result >= 0) 43961c45981SPaul Mackerras continue; 44061c45981SPaul Mackerras } 44161c45981SPaul Mackerras } 44261c45981SPaul Mackerras 44386470930SIngo Molnar /* 44486470930SIngo Molnar * Fall back to reads: 44586470930SIngo Molnar */ 4468953645fSIngo Molnar if (cache_op == -1) 4478953645fSIngo Molnar cache_op = PERF_COUNT_HW_CACHE_OP_READ; 44886470930SIngo Molnar 44986470930SIngo Molnar /* 45086470930SIngo Molnar * Fall back to accesses: 45186470930SIngo Molnar */ 45286470930SIngo Molnar if (cache_result == -1) 45386470930SIngo Molnar cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 45486470930SIngo Molnar 45589812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 45689812fc8SJiri Olsa attr.config = cache_type | (cache_op << 8) | (cache_result << 16); 45789812fc8SJiri Olsa attr.type = PERF_TYPE_HW_CACHE; 45889812fc8SJiri Olsa return add_event(list, idx, &attr, name); 45986470930SIngo Molnar } 46086470930SIngo Molnar 461b847cbdcSJiri Olsa static int add_tracepoint(struct list_head **list, int *idx, 46289812fc8SJiri Olsa char *sys_name, char *evt_name) 463bcd3279fSFrederic Weisbecker { 46489812fc8SJiri Olsa struct perf_event_attr attr; 46589812fc8SJiri Olsa char name[MAX_NAME_LEN]; 466bcd3279fSFrederic Weisbecker char evt_path[MAXPATHLEN]; 467bcd3279fSFrederic Weisbecker char id_buf[4]; 468bcd3279fSFrederic Weisbecker u64 id; 469bcd3279fSFrederic Weisbecker int fd; 470bcd3279fSFrederic Weisbecker 471ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path, 472bcd3279fSFrederic Weisbecker sys_name, evt_name); 473bcd3279fSFrederic Weisbecker 474bcd3279fSFrederic Weisbecker fd = open(evt_path, O_RDONLY); 475bcd3279fSFrederic Weisbecker if (fd < 0) 47689812fc8SJiri Olsa return -1; 477bcd3279fSFrederic Weisbecker 478bcd3279fSFrederic Weisbecker if (read(fd, id_buf, sizeof(id_buf)) < 0) { 479bcd3279fSFrederic Weisbecker close(fd); 48089812fc8SJiri Olsa return -1; 481bcd3279fSFrederic Weisbecker } 482bcd3279fSFrederic Weisbecker 483bcd3279fSFrederic Weisbecker close(fd); 484bcd3279fSFrederic Weisbecker id = atoll(id_buf); 485bcd3279fSFrederic Weisbecker 48689812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 48789812fc8SJiri Olsa attr.config = id; 48889812fc8SJiri Olsa attr.type = PERF_TYPE_TRACEPOINT; 48989812fc8SJiri Olsa attr.sample_type |= PERF_SAMPLE_RAW; 49089812fc8SJiri Olsa attr.sample_type |= PERF_SAMPLE_TIME; 49189812fc8SJiri Olsa attr.sample_type |= PERF_SAMPLE_CPU; 49289812fc8SJiri Olsa attr.sample_period = 1; 4935710fcadSStephane Eranian 49489812fc8SJiri Olsa snprintf(name, MAX_NAME_LEN, "%s:%s", sys_name, evt_name); 49589812fc8SJiri Olsa return add_event(list, idx, &attr, name); 496bcd3279fSFrederic Weisbecker } 497bcd3279fSFrederic Weisbecker 498b847cbdcSJiri Olsa static int add_tracepoint_multi(struct list_head **list, int *idx, 49989812fc8SJiri Olsa char *sys_name, char *evt_name) 500bcd3279fSFrederic Weisbecker { 501bcd3279fSFrederic Weisbecker char evt_path[MAXPATHLEN]; 502bcd3279fSFrederic Weisbecker struct dirent *evt_ent; 503bcd3279fSFrederic Weisbecker DIR *evt_dir; 50489812fc8SJiri Olsa int ret = 0; 505bcd3279fSFrederic Weisbecker 506ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); 507bcd3279fSFrederic Weisbecker evt_dir = opendir(evt_path); 508bcd3279fSFrederic Weisbecker if (!evt_dir) { 509bcd3279fSFrederic Weisbecker perror("Can't open event dir"); 51089812fc8SJiri Olsa return -1; 511bcd3279fSFrederic Weisbecker } 512bcd3279fSFrederic Weisbecker 51389812fc8SJiri Olsa while (!ret && (evt_ent = readdir(evt_dir))) { 514bcd3279fSFrederic Weisbecker if (!strcmp(evt_ent->d_name, ".") 515bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "..") 516bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "enable") 517bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "filter")) 518bcd3279fSFrederic Weisbecker continue; 519bcd3279fSFrederic Weisbecker 52089812fc8SJiri Olsa if (!strglobmatch(evt_ent->d_name, evt_name)) 521fb1d2edfSMasami Hiramatsu continue; 522fb1d2edfSMasami Hiramatsu 52389812fc8SJiri Olsa ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name); 524bcd3279fSFrederic Weisbecker } 525bcd3279fSFrederic Weisbecker 52689812fc8SJiri Olsa return ret; 527bcd3279fSFrederic Weisbecker } 528bcd3279fSFrederic Weisbecker 529b847cbdcSJiri Olsa int parse_events_add_tracepoint(struct list_head **list, int *idx, 53089812fc8SJiri Olsa char *sys, char *event) 531f6bdafefSJason Baron { 53289812fc8SJiri Olsa int ret; 533f6bdafefSJason Baron 53489812fc8SJiri Olsa ret = debugfs_valid_mountpoint(tracing_events_path); 53589812fc8SJiri Olsa if (ret) 53689812fc8SJiri Olsa return ret; 537f6bdafefSJason Baron 53889812fc8SJiri Olsa return strpbrk(event, "*?") ? 53989812fc8SJiri Olsa add_tracepoint_multi(list, idx, sys, event) : 54089812fc8SJiri Olsa add_tracepoint(list, idx, sys, event); 5413a9f131fSFrederic Weisbecker } 5423a9f131fSFrederic Weisbecker 54389812fc8SJiri Olsa static int 54489812fc8SJiri Olsa parse_breakpoint_type(const char *type, struct perf_event_attr *attr) 5451b290d67SFrederic Weisbecker { 5461b290d67SFrederic Weisbecker int i; 5471b290d67SFrederic Weisbecker 5481b290d67SFrederic Weisbecker for (i = 0; i < 3; i++) { 54989812fc8SJiri Olsa if (!type || !type[i]) 5501b290d67SFrederic Weisbecker break; 5511b290d67SFrederic Weisbecker 5521b290d67SFrederic Weisbecker switch (type[i]) { 5531b290d67SFrederic Weisbecker case 'r': 5541b290d67SFrederic Weisbecker attr->bp_type |= HW_BREAKPOINT_R; 5551b290d67SFrederic Weisbecker break; 5561b290d67SFrederic Weisbecker case 'w': 5571b290d67SFrederic Weisbecker attr->bp_type |= HW_BREAKPOINT_W; 5581b290d67SFrederic Weisbecker break; 5591b290d67SFrederic Weisbecker case 'x': 5601b290d67SFrederic Weisbecker attr->bp_type |= HW_BREAKPOINT_X; 5611b290d67SFrederic Weisbecker break; 5621b290d67SFrederic Weisbecker default: 56389812fc8SJiri Olsa return -EINVAL; 5641b290d67SFrederic Weisbecker } 5651b290d67SFrederic Weisbecker } 56689812fc8SJiri Olsa 5671b290d67SFrederic Weisbecker if (!attr->bp_type) /* Default */ 5681b290d67SFrederic Weisbecker attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 5691b290d67SFrederic Weisbecker 57089812fc8SJiri Olsa return 0; 5711b290d67SFrederic Weisbecker } 5721b290d67SFrederic Weisbecker 573b847cbdcSJiri Olsa int parse_events_add_breakpoint(struct list_head **list, int *idx, 57489812fc8SJiri Olsa void *ptr, char *type) 5751b290d67SFrederic Weisbecker { 57689812fc8SJiri Olsa struct perf_event_attr attr; 57789812fc8SJiri Olsa char name[MAX_NAME_LEN]; 5781b290d67SFrederic Weisbecker 57989812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 5809fafd98fSJiri Olsa attr.bp_addr = (unsigned long) ptr; 5811b290d67SFrederic Weisbecker 58289812fc8SJiri Olsa if (parse_breakpoint_type(type, &attr)) 58389812fc8SJiri Olsa return -EINVAL; 5841b290d67SFrederic Weisbecker 585aa59a485SFrederic Weisbecker /* 586aa59a485SFrederic Weisbecker * We should find a nice way to override the access length 587aa59a485SFrederic Weisbecker * Provide some defaults for now 588aa59a485SFrederic Weisbecker */ 58989812fc8SJiri Olsa if (attr.bp_type == HW_BREAKPOINT_X) 59089812fc8SJiri Olsa attr.bp_len = sizeof(long); 591aa59a485SFrederic Weisbecker else 59289812fc8SJiri Olsa attr.bp_len = HW_BREAKPOINT_LEN_4; 593aa59a485SFrederic Weisbecker 59489812fc8SJiri Olsa attr.type = PERF_TYPE_BREAKPOINT; 5951b290d67SFrederic Weisbecker 59689812fc8SJiri Olsa snprintf(name, MAX_NAME_LEN, "mem:%p:%s", ptr, type ? type : "rw"); 59789812fc8SJiri Olsa return add_event(list, idx, &attr, name); 5981b290d67SFrederic Weisbecker } 5991b290d67SFrederic Weisbecker 6008f707d84SJiri Olsa static int config_term(struct perf_event_attr *attr, 6018f707d84SJiri Olsa struct parse_events__term *term) 6028f707d84SJiri Olsa { 60316fa7e82SJiri Olsa #define CHECK_TYPE_VAL(type) \ 60416fa7e82SJiri Olsa do { \ 60516fa7e82SJiri Olsa if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val) \ 60616fa7e82SJiri Olsa return -EINVAL; \ 60716fa7e82SJiri Olsa } while (0) 60816fa7e82SJiri Olsa 60916fa7e82SJiri Olsa switch (term->type_term) { 6108f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG: 61116fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 6128f707d84SJiri Olsa attr->config = term->val.num; 6138f707d84SJiri Olsa break; 6148f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG1: 61516fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 6168f707d84SJiri Olsa attr->config1 = term->val.num; 6178f707d84SJiri Olsa break; 6188f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG2: 61916fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 6208f707d84SJiri Olsa attr->config2 = term->val.num; 6218f707d84SJiri Olsa break; 6228f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 62316fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 6248f707d84SJiri Olsa attr->sample_period = term->val.num; 6258f707d84SJiri Olsa break; 6268f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: 6278f707d84SJiri Olsa /* 6288f707d84SJiri Olsa * TODO uncomment when the field is available 6298f707d84SJiri Olsa * attr->branch_sample_type = term->val.num; 6308f707d84SJiri Olsa */ 6318f707d84SJiri Olsa break; 6326b5fc39bSJiri Olsa case PARSE_EVENTS__TERM_TYPE_NAME: 6336b5fc39bSJiri Olsa CHECK_TYPE_VAL(STR); 6346b5fc39bSJiri Olsa break; 6358f707d84SJiri Olsa default: 6368f707d84SJiri Olsa return -EINVAL; 6378f707d84SJiri Olsa } 63816fa7e82SJiri Olsa 6398f707d84SJiri Olsa return 0; 64016fa7e82SJiri Olsa #undef CHECK_TYPE_VAL 6418f707d84SJiri Olsa } 6428f707d84SJiri Olsa 6438f707d84SJiri Olsa static int config_attr(struct perf_event_attr *attr, 6448f707d84SJiri Olsa struct list_head *head, int fail) 6458f707d84SJiri Olsa { 6468f707d84SJiri Olsa struct parse_events__term *term; 6478f707d84SJiri Olsa 6488f707d84SJiri Olsa list_for_each_entry(term, head, list) 6498f707d84SJiri Olsa if (config_term(attr, term) && fail) 6508f707d84SJiri Olsa return -EINVAL; 6518f707d84SJiri Olsa 6528f707d84SJiri Olsa return 0; 6538f707d84SJiri Olsa } 6548f707d84SJiri Olsa 655b847cbdcSJiri Olsa int parse_events_add_numeric(struct list_head **list, int *idx, 6568f707d84SJiri Olsa unsigned long type, unsigned long config, 6578f707d84SJiri Olsa struct list_head *head_config) 65874d5b588SJaswinder Singh Rajput { 65989812fc8SJiri Olsa struct perf_event_attr attr; 66074d5b588SJaswinder Singh Rajput 66189812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 66289812fc8SJiri Olsa attr.type = type; 66389812fc8SJiri Olsa attr.config = config; 6648f707d84SJiri Olsa 6658f707d84SJiri Olsa if (head_config && 6668f707d84SJiri Olsa config_attr(&attr, head_config, 1)) 6678f707d84SJiri Olsa return -EINVAL; 6688f707d84SJiri Olsa 66989812fc8SJiri Olsa return add_event(list, idx, &attr, 67089812fc8SJiri Olsa (char *) __event_name(type, config)); 671b908debdSIngo Molnar } 672b908debdSIngo Molnar 6736b5fc39bSJiri Olsa static int parse_events__is_name_term(struct parse_events__term *term) 6746b5fc39bSJiri Olsa { 6756b5fc39bSJiri Olsa return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; 6766b5fc39bSJiri Olsa } 6776b5fc39bSJiri Olsa 6786b5fc39bSJiri Olsa static char *pmu_event_name(struct perf_event_attr *attr, 6796b5fc39bSJiri Olsa struct list_head *head_terms) 6806b5fc39bSJiri Olsa { 6816b5fc39bSJiri Olsa struct parse_events__term *term; 6826b5fc39bSJiri Olsa 6836b5fc39bSJiri Olsa list_for_each_entry(term, head_terms, list) 6846b5fc39bSJiri Olsa if (parse_events__is_name_term(term)) 6856b5fc39bSJiri Olsa return term->val.str; 6866b5fc39bSJiri Olsa 6876b5fc39bSJiri Olsa return (char *) __event_name(PERF_TYPE_RAW, attr->config); 6886b5fc39bSJiri Olsa } 6896b5fc39bSJiri Olsa 690b847cbdcSJiri Olsa int parse_events_add_pmu(struct list_head **list, int *idx, 6915f537a26SJiri Olsa char *name, struct list_head *head_config) 6925f537a26SJiri Olsa { 6935f537a26SJiri Olsa struct perf_event_attr attr; 6945f537a26SJiri Olsa struct perf_pmu *pmu; 6955f537a26SJiri Olsa 6965f537a26SJiri Olsa pmu = perf_pmu__find(name); 6975f537a26SJiri Olsa if (!pmu) 6985f537a26SJiri Olsa return -EINVAL; 6995f537a26SJiri Olsa 7005f537a26SJiri Olsa memset(&attr, 0, sizeof(attr)); 7015f537a26SJiri Olsa 7025f537a26SJiri Olsa /* 7035f537a26SJiri Olsa * Configure hardcoded terms first, no need to check 7045f537a26SJiri Olsa * return value when called with fail == 0 ;) 7055f537a26SJiri Olsa */ 7065f537a26SJiri Olsa config_attr(&attr, head_config, 0); 7075f537a26SJiri Olsa 7085f537a26SJiri Olsa if (perf_pmu__config(pmu, &attr, head_config)) 7095f537a26SJiri Olsa return -EINVAL; 7105f537a26SJiri Olsa 7116b5fc39bSJiri Olsa return add_event(list, idx, &attr, 7126b5fc39bSJiri Olsa pmu_event_name(&attr, head_config)); 7135f537a26SJiri Olsa } 7145f537a26SJiri Olsa 7155d7be90eSJiri Olsa void parse_events_update_lists(struct list_head *list_event, 7165d7be90eSJiri Olsa struct list_head *list_all) 7175d7be90eSJiri Olsa { 7185d7be90eSJiri Olsa /* 7195d7be90eSJiri Olsa * Called for single event definition. Update the 7205d7be90eSJiri Olsa * 'all event' list, and reinit the 'signle event' 7215d7be90eSJiri Olsa * list, for next event definition. 7225d7be90eSJiri Olsa */ 7235d7be90eSJiri Olsa list_splice_tail(list_event, list_all); 724b847cbdcSJiri Olsa free(list_event); 7255d7be90eSJiri Olsa } 7265d7be90eSJiri Olsa 72789812fc8SJiri Olsa int parse_events_modifier(struct list_head *list, char *str) 72861c45981SPaul Mackerras { 72989812fc8SJiri Olsa struct perf_evsel *evsel; 73099320cc8SJoerg Roedel int exclude = 0, exclude_GH = 0; 73199320cc8SJoerg Roedel int eu = 0, ek = 0, eh = 0, eH = 0, eG = 0, precise = 0; 73261c45981SPaul Mackerras 73389812fc8SJiri Olsa if (str == NULL) 73461c45981SPaul Mackerras return 0; 735ceb53fbfSIngo Molnar 73661c45981SPaul Mackerras while (*str) { 737ab608344SPeter Zijlstra if (*str == 'u') { 738ab608344SPeter Zijlstra if (!exclude) 739ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 74061c45981SPaul Mackerras eu = 0; 741ab608344SPeter Zijlstra } else if (*str == 'k') { 742ab608344SPeter Zijlstra if (!exclude) 743ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 74461c45981SPaul Mackerras ek = 0; 745ab608344SPeter Zijlstra } else if (*str == 'h') { 746ab608344SPeter Zijlstra if (!exclude) 747ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 74861c45981SPaul Mackerras eh = 0; 74999320cc8SJoerg Roedel } else if (*str == 'G') { 75099320cc8SJoerg Roedel if (!exclude_GH) 75199320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 75299320cc8SJoerg Roedel eG = 0; 75399320cc8SJoerg Roedel } else if (*str == 'H') { 75499320cc8SJoerg Roedel if (!exclude_GH) 75599320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 75699320cc8SJoerg Roedel eH = 0; 757ab608344SPeter Zijlstra } else if (*str == 'p') { 758ab608344SPeter Zijlstra precise++; 759ab608344SPeter Zijlstra } else 76061c45981SPaul Mackerras break; 761ab608344SPeter Zijlstra 76261c45981SPaul Mackerras ++str; 76361c45981SPaul Mackerras } 76474d5b588SJaswinder Singh Rajput 76586470930SIngo Molnar /* 76689812fc8SJiri Olsa * precise ip: 76789812fc8SJiri Olsa * 76889812fc8SJiri Olsa * 0 - SAMPLE_IP can have arbitrary skid 76989812fc8SJiri Olsa * 1 - SAMPLE_IP must have constant skid 77089812fc8SJiri Olsa * 2 - SAMPLE_IP requested to have 0 skid 77189812fc8SJiri Olsa * 3 - SAMPLE_IP must have 0 skid 77289812fc8SJiri Olsa * 77389812fc8SJiri Olsa * See also PERF_RECORD_MISC_EXACT_IP 77486470930SIngo Molnar */ 77589812fc8SJiri Olsa if (precise > 3) 77689812fc8SJiri Olsa return -EINVAL; 77786470930SIngo Molnar 77889812fc8SJiri Olsa list_for_each_entry(evsel, list, node) { 77989812fc8SJiri Olsa evsel->attr.exclude_user = eu; 78089812fc8SJiri Olsa evsel->attr.exclude_kernel = ek; 78189812fc8SJiri Olsa evsel->attr.exclude_hv = eh; 78289812fc8SJiri Olsa evsel->attr.precise_ip = precise; 78389812fc8SJiri Olsa evsel->attr.exclude_host = eH; 78489812fc8SJiri Olsa evsel->attr.exclude_guest = eG; 785ceb53fbfSIngo Molnar } 78686470930SIngo Molnar 78789812fc8SJiri Olsa return 0; 78886470930SIngo Molnar } 78986470930SIngo Molnar 790f120f9d5SJiri Olsa int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) 79186470930SIngo Molnar { 792*46010ab2SJiri Olsa struct parse_events_data__events data = { 793*46010ab2SJiri Olsa .list = LIST_HEAD_INIT(data.list), 794*46010ab2SJiri Olsa .idx = evlist->nr_entries, 795*46010ab2SJiri Olsa }; 79689812fc8SJiri Olsa YY_BUFFER_STATE buffer; 797*46010ab2SJiri Olsa int ret; 79886470930SIngo Molnar 79989812fc8SJiri Olsa buffer = parse_events__scan_string(str); 80061c45981SPaul Mackerras 80182ba1f2fSJiri Olsa #ifdef PARSER_DEBUG 80282ba1f2fSJiri Olsa parse_events_debug = 1; 80382ba1f2fSJiri Olsa #endif 804*46010ab2SJiri Olsa ret = parse_events_parse(&data); 80586470930SIngo Molnar 80689812fc8SJiri Olsa parse_events__flush_buffer(buffer); 80789812fc8SJiri Olsa parse_events__delete_buffer(buffer); 80808d2f762SJiri Olsa parse_events_lex_destroy(); 809f0c55bcfSStephane Eranian 81089812fc8SJiri Olsa if (!ret) { 811*46010ab2SJiri Olsa int entries = data.idx - evlist->nr_entries; 812*46010ab2SJiri Olsa perf_evlist__splice_list_tail(evlist, &data.list, entries); 81386470930SIngo Molnar return 0; 81486470930SIngo Molnar } 81586470930SIngo Molnar 8165d7be90eSJiri Olsa /* 8175d7be90eSJiri Olsa * There are 2 users - builtin-record and builtin-test objects. 8185d7be90eSJiri Olsa * Both call perf_evlist__delete in case of error, so we dont 8195d7be90eSJiri Olsa * need to bother. 8205d7be90eSJiri Olsa */ 82189812fc8SJiri Olsa fprintf(stderr, "invalid or unsupported event: '%s'\n", str); 82289812fc8SJiri Olsa fprintf(stderr, "Run 'perf list' for a list of valid events\n"); 82389812fc8SJiri Olsa return ret; 82489812fc8SJiri Olsa } 82589812fc8SJiri Olsa 826f120f9d5SJiri Olsa int parse_events_option(const struct option *opt, const char *str, 827f120f9d5SJiri Olsa int unset __used) 828f120f9d5SJiri Olsa { 829f120f9d5SJiri Olsa struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 830f120f9d5SJiri Olsa return parse_events(evlist, str, unset); 831f120f9d5SJiri Olsa } 832f120f9d5SJiri Olsa 833361c99a6SArnaldo Carvalho de Melo int parse_filter(const struct option *opt, const char *str, 834c171b552SLi Zefan int unset __used) 835c171b552SLi Zefan { 836361c99a6SArnaldo Carvalho de Melo struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 83769aad6f1SArnaldo Carvalho de Melo struct perf_evsel *last = NULL; 838c171b552SLi Zefan 839361c99a6SArnaldo Carvalho de Melo if (evlist->nr_entries > 0) 840361c99a6SArnaldo Carvalho de Melo last = list_entry(evlist->entries.prev, struct perf_evsel, node); 84169aad6f1SArnaldo Carvalho de Melo 84269aad6f1SArnaldo Carvalho de Melo if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { 843c171b552SLi Zefan fprintf(stderr, 844c171b552SLi Zefan "-F option should follow a -e tracepoint option\n"); 845c171b552SLi Zefan return -1; 846c171b552SLi Zefan } 847c171b552SLi Zefan 84869aad6f1SArnaldo Carvalho de Melo last->filter = strdup(str); 84969aad6f1SArnaldo Carvalho de Melo if (last->filter == NULL) { 850c171b552SLi Zefan fprintf(stderr, "not enough memory to hold filter string\n"); 851c171b552SLi Zefan return -1; 852c171b552SLi Zefan } 853c171b552SLi Zefan 854c171b552SLi Zefan return 0; 855c171b552SLi Zefan } 856c171b552SLi Zefan 85786470930SIngo Molnar static const char * const event_type_descriptors[] = { 85886470930SIngo Molnar "Hardware event", 85986470930SIngo Molnar "Software event", 86086470930SIngo Molnar "Tracepoint event", 86186470930SIngo Molnar "Hardware cache event", 86241bdcb23SLiming Wang "Raw hardware event descriptor", 86341bdcb23SLiming Wang "Hardware breakpoint", 86486470930SIngo Molnar }; 86586470930SIngo Molnar 86686470930SIngo Molnar /* 867f6bdafefSJason Baron * Print the events from <debugfs_mount_point>/tracing/events 868f6bdafefSJason Baron */ 869f6bdafefSJason Baron 870668b8788SArnaldo Carvalho de Melo void print_tracepoint_events(const char *subsys_glob, const char *event_glob) 871f6bdafefSJason Baron { 872f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 873f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 874f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 875725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 876f6bdafefSJason Baron 877ebf294bfSArnaldo Carvalho de Melo if (debugfs_valid_mountpoint(tracing_events_path)) 878f6bdafefSJason Baron return; 879f6bdafefSJason Baron 880ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 881f6bdafefSJason Baron if (!sys_dir) 882725b1368SEric Dumazet return; 883f6bdafefSJason Baron 8846b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 885668b8788SArnaldo Carvalho de Melo if (subsys_glob != NULL && 886668b8788SArnaldo Carvalho de Melo !strglobmatch(sys_dirent.d_name, subsys_glob)) 887668b8788SArnaldo Carvalho de Melo continue; 888725b1368SEric Dumazet 889ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 890725b1368SEric Dumazet sys_dirent.d_name); 891725b1368SEric Dumazet evt_dir = opendir(dir_path); 892725b1368SEric Dumazet if (!evt_dir) 8936b58e7f1SUlrich Drepper continue; 894725b1368SEric Dumazet 8956b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 896668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 897668b8788SArnaldo Carvalho de Melo !strglobmatch(evt_dirent.d_name, event_glob)) 898668b8788SArnaldo Carvalho de Melo continue; 899668b8788SArnaldo Carvalho de Melo 900f6bdafefSJason Baron snprintf(evt_path, MAXPATHLEN, "%s:%s", 901f6bdafefSJason Baron sys_dirent.d_name, evt_dirent.d_name); 902947b4ad1SIngo Molnar printf(" %-50s [%s]\n", evt_path, 90341bdcb23SLiming Wang event_type_descriptors[PERF_TYPE_TRACEPOINT]); 904f6bdafefSJason Baron } 905f6bdafefSJason Baron closedir(evt_dir); 906f6bdafefSJason Baron } 907f6bdafefSJason Baron closedir(sys_dir); 908f6bdafefSJason Baron } 909f6bdafefSJason Baron 910f6bdafefSJason Baron /* 91120c457b8SThomas Renninger * Check whether event is in <debugfs_mount_point>/tracing/events 91220c457b8SThomas Renninger */ 91320c457b8SThomas Renninger 91420c457b8SThomas Renninger int is_valid_tracepoint(const char *event_string) 91520c457b8SThomas Renninger { 91620c457b8SThomas Renninger DIR *sys_dir, *evt_dir; 91720c457b8SThomas Renninger struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 91820c457b8SThomas Renninger char evt_path[MAXPATHLEN]; 91920c457b8SThomas Renninger char dir_path[MAXPATHLEN]; 92020c457b8SThomas Renninger 921ebf294bfSArnaldo Carvalho de Melo if (debugfs_valid_mountpoint(tracing_events_path)) 92220c457b8SThomas Renninger return 0; 92320c457b8SThomas Renninger 924ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 92520c457b8SThomas Renninger if (!sys_dir) 92620c457b8SThomas Renninger return 0; 92720c457b8SThomas Renninger 92820c457b8SThomas Renninger for_each_subsystem(sys_dir, sys_dirent, sys_next) { 92920c457b8SThomas Renninger 930ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 93120c457b8SThomas Renninger sys_dirent.d_name); 93220c457b8SThomas Renninger evt_dir = opendir(dir_path); 93320c457b8SThomas Renninger if (!evt_dir) 93420c457b8SThomas Renninger continue; 93520c457b8SThomas Renninger 93620c457b8SThomas Renninger for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 93720c457b8SThomas Renninger snprintf(evt_path, MAXPATHLEN, "%s:%s", 93820c457b8SThomas Renninger sys_dirent.d_name, evt_dirent.d_name); 93920c457b8SThomas Renninger if (!strcmp(evt_path, event_string)) { 94020c457b8SThomas Renninger closedir(evt_dir); 94120c457b8SThomas Renninger closedir(sys_dir); 94220c457b8SThomas Renninger return 1; 94320c457b8SThomas Renninger } 94420c457b8SThomas Renninger } 94520c457b8SThomas Renninger closedir(evt_dir); 94620c457b8SThomas Renninger } 94720c457b8SThomas Renninger closedir(sys_dir); 94820c457b8SThomas Renninger return 0; 94920c457b8SThomas Renninger } 95020c457b8SThomas Renninger 951668b8788SArnaldo Carvalho de Melo void print_events_type(u8 type) 952668b8788SArnaldo Carvalho de Melo { 953668b8788SArnaldo Carvalho de Melo struct event_symbol *syms = event_symbols; 954668b8788SArnaldo Carvalho de Melo unsigned int i; 955668b8788SArnaldo Carvalho de Melo char name[64]; 956668b8788SArnaldo Carvalho de Melo 957668b8788SArnaldo Carvalho de Melo for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 958668b8788SArnaldo Carvalho de Melo if (type != syms->type) 959668b8788SArnaldo Carvalho de Melo continue; 960668b8788SArnaldo Carvalho de Melo 961668b8788SArnaldo Carvalho de Melo if (strlen(syms->alias)) 962668b8788SArnaldo Carvalho de Melo snprintf(name, sizeof(name), "%s OR %s", 963668b8788SArnaldo Carvalho de Melo syms->symbol, syms->alias); 964668b8788SArnaldo Carvalho de Melo else 965668b8788SArnaldo Carvalho de Melo snprintf(name, sizeof(name), "%s", syms->symbol); 966668b8788SArnaldo Carvalho de Melo 967947b4ad1SIngo Molnar printf(" %-50s [%s]\n", name, 968668b8788SArnaldo Carvalho de Melo event_type_descriptors[type]); 969668b8788SArnaldo Carvalho de Melo } 970668b8788SArnaldo Carvalho de Melo } 971668b8788SArnaldo Carvalho de Melo 972668b8788SArnaldo Carvalho de Melo int print_hwcache_events(const char *event_glob) 973668b8788SArnaldo Carvalho de Melo { 974668b8788SArnaldo Carvalho de Melo unsigned int type, op, i, printed = 0; 975668b8788SArnaldo Carvalho de Melo 976668b8788SArnaldo Carvalho de Melo for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 977668b8788SArnaldo Carvalho de Melo for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 978668b8788SArnaldo Carvalho de Melo /* skip invalid cache type */ 979668b8788SArnaldo Carvalho de Melo if (!is_cache_op_valid(type, op)) 980668b8788SArnaldo Carvalho de Melo continue; 981668b8788SArnaldo Carvalho de Melo 982668b8788SArnaldo Carvalho de Melo for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 983668b8788SArnaldo Carvalho de Melo char *name = event_cache_name(type, op, i); 984668b8788SArnaldo Carvalho de Melo 985947b4ad1SIngo Molnar if (event_glob != NULL && !strglobmatch(name, event_glob)) 986668b8788SArnaldo Carvalho de Melo continue; 987668b8788SArnaldo Carvalho de Melo 988947b4ad1SIngo Molnar printf(" %-50s [%s]\n", name, 989668b8788SArnaldo Carvalho de Melo event_type_descriptors[PERF_TYPE_HW_CACHE]); 990668b8788SArnaldo Carvalho de Melo ++printed; 991668b8788SArnaldo Carvalho de Melo } 992668b8788SArnaldo Carvalho de Melo } 993668b8788SArnaldo Carvalho de Melo } 994668b8788SArnaldo Carvalho de Melo 995668b8788SArnaldo Carvalho de Melo return printed; 996668b8788SArnaldo Carvalho de Melo } 997668b8788SArnaldo Carvalho de Melo 99820c457b8SThomas Renninger /* 99986470930SIngo Molnar * Print the help text for the event symbols: 100086470930SIngo Molnar */ 1001668b8788SArnaldo Carvalho de Melo void print_events(const char *event_glob) 100286470930SIngo Molnar { 1003668b8788SArnaldo Carvalho de Melo unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; 1004947b4ad1SIngo Molnar struct event_symbol *syms = event_symbols; 1005947b4ad1SIngo Molnar char name[MAX_NAME_LEN]; 100686470930SIngo Molnar 1007689d3018SMarti Raudsepp printf("\n"); 1008689d3018SMarti Raudsepp printf("List of pre-defined events (to be used in -e):\n"); 100986470930SIngo Molnar 101086470930SIngo Molnar for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 101141bdcb23SLiming Wang type = syms->type; 101286470930SIngo Molnar 1013668b8788SArnaldo Carvalho de Melo if (type != prev_type && printed) { 1014689d3018SMarti Raudsepp printf("\n"); 1015668b8788SArnaldo Carvalho de Melo printed = 0; 1016668b8788SArnaldo Carvalho de Melo ntypes_printed++; 1017668b8788SArnaldo Carvalho de Melo } 1018668b8788SArnaldo Carvalho de Melo 1019668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 1020668b8788SArnaldo Carvalho de Melo !(strglobmatch(syms->symbol, event_glob) || 1021668b8788SArnaldo Carvalho de Melo (syms->alias && strglobmatch(syms->alias, event_glob)))) 1022668b8788SArnaldo Carvalho de Melo continue; 102386470930SIngo Molnar 102474d5b588SJaswinder Singh Rajput if (strlen(syms->alias)) 1025947b4ad1SIngo Molnar snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 102674d5b588SJaswinder Singh Rajput else 1027947b4ad1SIngo Molnar strncpy(name, syms->symbol, MAX_NAME_LEN); 1028947b4ad1SIngo Molnar printf(" %-50s [%s]\n", name, 102986470930SIngo Molnar event_type_descriptors[type]); 103086470930SIngo Molnar 103186470930SIngo Molnar prev_type = type; 1032668b8788SArnaldo Carvalho de Melo ++printed; 103386470930SIngo Molnar } 103486470930SIngo Molnar 1035668b8788SArnaldo Carvalho de Melo if (ntypes_printed) { 1036668b8788SArnaldo Carvalho de Melo printed = 0; 1037689d3018SMarti Raudsepp printf("\n"); 1038668b8788SArnaldo Carvalho de Melo } 1039668b8788SArnaldo Carvalho de Melo print_hwcache_events(event_glob); 104073c24cb8SJaswinder Singh Rajput 1041668b8788SArnaldo Carvalho de Melo if (event_glob != NULL) 1042668b8788SArnaldo Carvalho de Melo return; 104373c24cb8SJaswinder Singh Rajput 1044689d3018SMarti Raudsepp printf("\n"); 1045947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 10465f537a26SJiri Olsa "rNNN", 10471cf4a063SArnaldo Carvalho de Melo event_type_descriptors[PERF_TYPE_RAW]); 10485f537a26SJiri Olsa printf(" %-50s [%s]\n", 10495f537a26SJiri Olsa "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 10505f537a26SJiri Olsa event_type_descriptors[PERF_TYPE_RAW]); 10515f537a26SJiri Olsa printf(" (see 'perf list --help' on how to encode it)\n"); 1052689d3018SMarti Raudsepp printf("\n"); 105386470930SIngo Molnar 1054947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 105541bdcb23SLiming Wang "mem:<addr>[:access]", 105641bdcb23SLiming Wang event_type_descriptors[PERF_TYPE_BREAKPOINT]); 10571b290d67SFrederic Weisbecker printf("\n"); 10581b290d67SFrederic Weisbecker 1059668b8788SArnaldo Carvalho de Melo print_tracepoint_events(NULL, NULL); 106086470930SIngo Molnar } 10618f707d84SJiri Olsa 10628f707d84SJiri Olsa int parse_events__is_hardcoded_term(struct parse_events__term *term) 10638f707d84SJiri Olsa { 106416fa7e82SJiri Olsa return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; 10658f707d84SJiri Olsa } 10668f707d84SJiri Olsa 106716fa7e82SJiri Olsa static int new_term(struct parse_events__term **_term, int type_val, 106816fa7e82SJiri Olsa int type_term, char *config, 106916fa7e82SJiri Olsa char *str, long num) 10708f707d84SJiri Olsa { 10718f707d84SJiri Olsa struct parse_events__term *term; 10728f707d84SJiri Olsa 10738f707d84SJiri Olsa term = zalloc(sizeof(*term)); 10748f707d84SJiri Olsa if (!term) 10758f707d84SJiri Olsa return -ENOMEM; 10768f707d84SJiri Olsa 10778f707d84SJiri Olsa INIT_LIST_HEAD(&term->list); 107816fa7e82SJiri Olsa term->type_val = type_val; 107916fa7e82SJiri Olsa term->type_term = type_term; 10808f707d84SJiri Olsa term->config = config; 10818f707d84SJiri Olsa 108216fa7e82SJiri Olsa switch (type_val) { 10838f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_NUM: 10848f707d84SJiri Olsa term->val.num = num; 10858f707d84SJiri Olsa break; 10868f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_STR: 10878f707d84SJiri Olsa term->val.str = str; 10888f707d84SJiri Olsa break; 10898f707d84SJiri Olsa default: 10908f707d84SJiri Olsa return -EINVAL; 10918f707d84SJiri Olsa } 10928f707d84SJiri Olsa 10938f707d84SJiri Olsa *_term = term; 10948f707d84SJiri Olsa return 0; 10958f707d84SJiri Olsa } 10968f707d84SJiri Olsa 109716fa7e82SJiri Olsa int parse_events__term_num(struct parse_events__term **term, 109816fa7e82SJiri Olsa int type_term, char *config, long num) 109916fa7e82SJiri Olsa { 110016fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, 110116fa7e82SJiri Olsa config, NULL, num); 110216fa7e82SJiri Olsa } 110316fa7e82SJiri Olsa 110416fa7e82SJiri Olsa int parse_events__term_str(struct parse_events__term **term, 110516fa7e82SJiri Olsa int type_term, char *config, char *str) 110616fa7e82SJiri Olsa { 110716fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, 110816fa7e82SJiri Olsa config, str, 0); 110916fa7e82SJiri Olsa } 111016fa7e82SJiri Olsa 11118f707d84SJiri Olsa void parse_events__free_terms(struct list_head *terms) 11128f707d84SJiri Olsa { 11138f707d84SJiri Olsa struct parse_events__term *term, *h; 11148f707d84SJiri Olsa 11158f707d84SJiri Olsa list_for_each_entry_safe(term, h, terms, list) 11168f707d84SJiri Olsa free(term); 11178f707d84SJiri Olsa 11188f707d84SJiri Olsa free(terms); 11198f707d84SJiri Olsa } 1120