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 29b847cbdcSJiri Olsa int parse_events_parse(struct list_head *list, int *idx); 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 *hw_event_names[PERF_COUNT_HW_MAX] = { 6686470930SIngo Molnar "cycles", 6786470930SIngo Molnar "instructions", 6886470930SIngo Molnar "cache-references", 6986470930SIngo Molnar "cache-misses", 7086470930SIngo Molnar "branches", 7186470930SIngo Molnar "branch-misses", 7286470930SIngo Molnar "bus-cycles", 73d3d1e86dSIngo Molnar "stalled-cycles-frontend", 74d3d1e86dSIngo Molnar "stalled-cycles-backend", 75f1ac18afSStephane Eranian "ref-cycles", 7686470930SIngo Molnar }; 7786470930SIngo Molnar 78d3d1e86dSIngo Molnar static const char *sw_event_names[PERF_COUNT_SW_MAX] = { 79749141d9SIngo Molnar "cpu-clock", 80749141d9SIngo Molnar "task-clock", 8186470930SIngo Molnar "page-faults", 8286470930SIngo Molnar "context-switches", 8386470930SIngo Molnar "CPU-migrations", 8486470930SIngo Molnar "minor-faults", 8586470930SIngo Molnar "major-faults", 86f7d79860SAnton Blanchard "alignment-faults", 87f7d79860SAnton Blanchard "emulation-faults", 8886470930SIngo Molnar }; 8986470930SIngo Molnar 9086470930SIngo Molnar #define MAX_ALIASES 8 9186470930SIngo Molnar 920111919dSJiri Olsa static const char *hw_cache[PERF_COUNT_HW_CACHE_MAX][MAX_ALIASES] = { 939590b7baSAnton Blanchard { "L1-dcache", "l1-d", "l1d", "L1-data", }, 949590b7baSAnton Blanchard { "L1-icache", "l1-i", "l1i", "L1-instruction", }, 950111919dSJiri Olsa { "LLC", "L2", }, 96e5c59547SJaswinder Singh Rajput { "dTLB", "d-tlb", "Data-TLB", }, 97e5c59547SJaswinder Singh Rajput { "iTLB", "i-tlb", "Instruction-TLB", }, 98e5c59547SJaswinder Singh Rajput { "branch", "branches", "bpu", "btb", "bpc", }, 990111919dSJiri Olsa { "node", }, 10086470930SIngo Molnar }; 10186470930SIngo Molnar 1020111919dSJiri Olsa static const char *hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][MAX_ALIASES] = { 103e5c59547SJaswinder Singh Rajput { "load", "loads", "read", }, 104e5c59547SJaswinder Singh Rajput { "store", "stores", "write", }, 105e5c59547SJaswinder Singh Rajput { "prefetch", "prefetches", "speculative-read", "speculative-load", }, 10686470930SIngo Molnar }; 10786470930SIngo Molnar 1080111919dSJiri Olsa static const char *hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] 1090111919dSJiri Olsa [MAX_ALIASES] = { 110e5c59547SJaswinder Singh Rajput { "refs", "Reference", "ops", "access", }, 111e5c59547SJaswinder Singh Rajput { "misses", "miss", }, 11286470930SIngo Molnar }; 11386470930SIngo Molnar 11406813f6cSJaswinder Singh Rajput #define C(x) PERF_COUNT_HW_CACHE_##x 11506813f6cSJaswinder Singh Rajput #define CACHE_READ (1 << C(OP_READ)) 11606813f6cSJaswinder Singh Rajput #define CACHE_WRITE (1 << C(OP_WRITE)) 11706813f6cSJaswinder Singh Rajput #define CACHE_PREFETCH (1 << C(OP_PREFETCH)) 11806813f6cSJaswinder Singh Rajput #define COP(x) (1 << x) 11906813f6cSJaswinder Singh Rajput 12006813f6cSJaswinder Singh Rajput /* 12106813f6cSJaswinder Singh Rajput * cache operartion stat 12206813f6cSJaswinder Singh Rajput * L1I : Read and prefetch only 12306813f6cSJaswinder Singh Rajput * ITLB and BPU : Read-only 12406813f6cSJaswinder Singh Rajput */ 12506813f6cSJaswinder Singh Rajput static unsigned long hw_cache_stat[C(MAX)] = { 12606813f6cSJaswinder Singh Rajput [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 12706813f6cSJaswinder Singh Rajput [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), 12806813f6cSJaswinder Singh Rajput [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 12906813f6cSJaswinder Singh Rajput [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 13006813f6cSJaswinder Singh Rajput [C(ITLB)] = (CACHE_READ), 13106813f6cSJaswinder Singh Rajput [C(BPU)] = (CACHE_READ), 1320111919dSJiri Olsa [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 13306813f6cSJaswinder Singh Rajput }; 13406813f6cSJaswinder Singh Rajput 1356b58e7f1SUlrich Drepper #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 136f6bdafefSJason Baron while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 1376b58e7f1SUlrich Drepper if (sys_dirent.d_type == DT_DIR && \ 138f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".")) && \ 139f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".."))) 140f6bdafefSJason Baron 141ae07b63fSPeter Zijlstra static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 142ae07b63fSPeter Zijlstra { 143ae07b63fSPeter Zijlstra char evt_path[MAXPATHLEN]; 144ae07b63fSPeter Zijlstra int fd; 145ae07b63fSPeter Zijlstra 146ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path, 147ae07b63fSPeter Zijlstra sys_dir->d_name, evt_dir->d_name); 148ae07b63fSPeter Zijlstra fd = open(evt_path, O_RDONLY); 149ae07b63fSPeter Zijlstra if (fd < 0) 150ae07b63fSPeter Zijlstra return -EINVAL; 151ae07b63fSPeter Zijlstra close(fd); 152ae07b63fSPeter Zijlstra 153ae07b63fSPeter Zijlstra return 0; 154ae07b63fSPeter Zijlstra } 155ae07b63fSPeter Zijlstra 1566b58e7f1SUlrich Drepper #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ 157f6bdafefSJason Baron while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 1586b58e7f1SUlrich Drepper if (evt_dirent.d_type == DT_DIR && \ 159f6bdafefSJason Baron (strcmp(evt_dirent.d_name, ".")) && \ 160ae07b63fSPeter Zijlstra (strcmp(evt_dirent.d_name, "..")) && \ 161ae07b63fSPeter Zijlstra (!tp_event_has_id(&sys_dirent, &evt_dirent))) 162f6bdafefSJason Baron 163270bbbe8SLi Zefan #define MAX_EVENT_LENGTH 512 164f6bdafefSJason Baron 165f6bdafefSJason Baron 1661ef2ed10SFrederic Weisbecker struct tracepoint_path *tracepoint_id_to_path(u64 config) 167f6bdafefSJason Baron { 1681ef2ed10SFrederic Weisbecker struct tracepoint_path *path = NULL; 169f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 170f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 1718aa8a7c8SStephane Eranian char id_buf[24]; 172725b1368SEric Dumazet int fd; 173f6bdafefSJason Baron u64 id; 174f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 175725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 176f6bdafefSJason Baron 177ebf294bfSArnaldo Carvalho de Melo if (debugfs_valid_mountpoint(tracing_events_path)) 1781ef2ed10SFrederic Weisbecker return NULL; 179f6bdafefSJason Baron 180ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 181f6bdafefSJason Baron if (!sys_dir) 182725b1368SEric Dumazet return NULL; 183f6bdafefSJason Baron 1846b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 185725b1368SEric Dumazet 186ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 187725b1368SEric Dumazet sys_dirent.d_name); 188725b1368SEric Dumazet evt_dir = opendir(dir_path); 189725b1368SEric Dumazet if (!evt_dir) 1906b58e7f1SUlrich Drepper continue; 191725b1368SEric Dumazet 1926b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 193725b1368SEric Dumazet 194725b1368SEric Dumazet snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 195f6bdafefSJason Baron evt_dirent.d_name); 196725b1368SEric Dumazet fd = open(evt_path, O_RDONLY); 197f6bdafefSJason Baron if (fd < 0) 198f6bdafefSJason Baron continue; 199f6bdafefSJason Baron if (read(fd, id_buf, sizeof(id_buf)) < 0) { 200f6bdafefSJason Baron close(fd); 201f6bdafefSJason Baron continue; 202f6bdafefSJason Baron } 203f6bdafefSJason Baron close(fd); 204f6bdafefSJason Baron id = atoll(id_buf); 205f6bdafefSJason Baron if (id == config) { 206f6bdafefSJason Baron closedir(evt_dir); 207f6bdafefSJason Baron closedir(sys_dir); 20859b4caebSJulia Lawall path = zalloc(sizeof(*path)); 2091ef2ed10SFrederic Weisbecker path->system = malloc(MAX_EVENT_LENGTH); 2101ef2ed10SFrederic Weisbecker if (!path->system) { 2111ef2ed10SFrederic Weisbecker free(path); 2121ef2ed10SFrederic Weisbecker return NULL; 2131ef2ed10SFrederic Weisbecker } 2141ef2ed10SFrederic Weisbecker path->name = malloc(MAX_EVENT_LENGTH); 2151ef2ed10SFrederic Weisbecker if (!path->name) { 2161ef2ed10SFrederic Weisbecker free(path->system); 2171ef2ed10SFrederic Weisbecker free(path); 2181ef2ed10SFrederic Weisbecker return NULL; 2191ef2ed10SFrederic Weisbecker } 2201ef2ed10SFrederic Weisbecker strncpy(path->system, sys_dirent.d_name, 2211ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2221ef2ed10SFrederic Weisbecker strncpy(path->name, evt_dirent.d_name, 2231ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2241ef2ed10SFrederic Weisbecker return path; 225f6bdafefSJason Baron } 226f6bdafefSJason Baron } 227f6bdafefSJason Baron closedir(evt_dir); 228f6bdafefSJason Baron } 229f6bdafefSJason Baron 230f6bdafefSJason Baron closedir(sys_dir); 2311ef2ed10SFrederic Weisbecker return NULL; 2321ef2ed10SFrederic Weisbecker } 2331ef2ed10SFrederic Weisbecker 2341ef2ed10SFrederic Weisbecker #define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1) 2351ef2ed10SFrederic Weisbecker static const char *tracepoint_id_to_name(u64 config) 2361ef2ed10SFrederic Weisbecker { 2371ef2ed10SFrederic Weisbecker static char buf[TP_PATH_LEN]; 2381ef2ed10SFrederic Weisbecker struct tracepoint_path *path; 2391ef2ed10SFrederic Weisbecker 2401ef2ed10SFrederic Weisbecker path = tracepoint_id_to_path(config); 2411ef2ed10SFrederic Weisbecker if (path) { 2421ef2ed10SFrederic Weisbecker snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name); 2431ef2ed10SFrederic Weisbecker free(path->name); 2441ef2ed10SFrederic Weisbecker free(path->system); 2451ef2ed10SFrederic Weisbecker free(path); 2461ef2ed10SFrederic Weisbecker } else 2471ef2ed10SFrederic Weisbecker snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown"); 2481ef2ed10SFrederic Weisbecker 2491ef2ed10SFrederic Weisbecker return buf; 250f6bdafefSJason Baron } 251f6bdafefSJason Baron 25206813f6cSJaswinder Singh Rajput static int is_cache_op_valid(u8 cache_type, u8 cache_op) 25306813f6cSJaswinder Singh Rajput { 25406813f6cSJaswinder Singh Rajput if (hw_cache_stat[cache_type] & COP(cache_op)) 25506813f6cSJaswinder Singh Rajput return 1; /* valid */ 25606813f6cSJaswinder Singh Rajput else 25706813f6cSJaswinder Singh Rajput return 0; /* invalid */ 25806813f6cSJaswinder Singh Rajput } 25906813f6cSJaswinder Singh Rajput 260e5c59547SJaswinder Singh Rajput static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result) 261e5c59547SJaswinder Singh Rajput { 262e5c59547SJaswinder Singh Rajput static char name[50]; 263e5c59547SJaswinder Singh Rajput 264e5c59547SJaswinder Singh Rajput if (cache_result) { 265e5c59547SJaswinder Singh Rajput sprintf(name, "%s-%s-%s", hw_cache[cache_type][0], 266e5c59547SJaswinder Singh Rajput hw_cache_op[cache_op][0], 267e5c59547SJaswinder Singh Rajput hw_cache_result[cache_result][0]); 268e5c59547SJaswinder Singh Rajput } else { 269e5c59547SJaswinder Singh Rajput sprintf(name, "%s-%s", hw_cache[cache_type][0], 270e5c59547SJaswinder Singh Rajput hw_cache_op[cache_op][1]); 271e5c59547SJaswinder Singh Rajput } 272e5c59547SJaswinder Singh Rajput 273e5c59547SJaswinder Singh Rajput return name; 274e5c59547SJaswinder Singh Rajput } 275e5c59547SJaswinder Singh Rajput 2761424dc96SDavid Ahern const char *event_type(int type) 2771424dc96SDavid Ahern { 2781424dc96SDavid Ahern switch (type) { 2791424dc96SDavid Ahern case PERF_TYPE_HARDWARE: 2801424dc96SDavid Ahern return "hardware"; 2811424dc96SDavid Ahern 2821424dc96SDavid Ahern case PERF_TYPE_SOFTWARE: 2831424dc96SDavid Ahern return "software"; 2841424dc96SDavid Ahern 2851424dc96SDavid Ahern case PERF_TYPE_TRACEPOINT: 2861424dc96SDavid Ahern return "tracepoint"; 2871424dc96SDavid Ahern 2881424dc96SDavid Ahern case PERF_TYPE_HW_CACHE: 2891424dc96SDavid Ahern return "hardware-cache"; 2901424dc96SDavid Ahern 2911424dc96SDavid Ahern default: 2921424dc96SDavid Ahern break; 2931424dc96SDavid Ahern } 2941424dc96SDavid Ahern 2951424dc96SDavid Ahern return "unknown"; 2961424dc96SDavid Ahern } 2971424dc96SDavid Ahern 29869aad6f1SArnaldo Carvalho de Melo const char *event_name(struct perf_evsel *evsel) 29986470930SIngo Molnar { 30069aad6f1SArnaldo Carvalho de Melo u64 config = evsel->attr.config; 30169aad6f1SArnaldo Carvalho de Melo int type = evsel->attr.type; 3028f18aec5SPeter Zijlstra 303f0c55bcfSStephane Eranian if (evsel->name) 304f0c55bcfSStephane Eranian return evsel->name; 305f0c55bcfSStephane Eranian 3068f18aec5SPeter Zijlstra return __event_name(type, config); 3078f18aec5SPeter Zijlstra } 3088f18aec5SPeter Zijlstra 30983a0944fSIngo Molnar const char *__event_name(int type, u64 config) 3108f18aec5SPeter Zijlstra { 31186470930SIngo Molnar static char buf[32]; 31286470930SIngo Molnar 3138f18aec5SPeter Zijlstra if (type == PERF_TYPE_RAW) { 3149486aa38SArnaldo Carvalho de Melo sprintf(buf, "raw 0x%" PRIx64, config); 31586470930SIngo Molnar return buf; 31686470930SIngo Molnar } 31786470930SIngo Molnar 31886470930SIngo Molnar switch (type) { 31986470930SIngo Molnar case PERF_TYPE_HARDWARE: 3201fc570adSIngo Molnar if (config < PERF_COUNT_HW_MAX && hw_event_names[config]) 32186470930SIngo Molnar return hw_event_names[config]; 32286470930SIngo Molnar return "unknown-hardware"; 32386470930SIngo Molnar 32486470930SIngo Molnar case PERF_TYPE_HW_CACHE: { 3259cffa8d5SPaul Mackerras u8 cache_type, cache_op, cache_result; 32686470930SIngo Molnar 32786470930SIngo Molnar cache_type = (config >> 0) & 0xff; 32886470930SIngo Molnar if (cache_type > PERF_COUNT_HW_CACHE_MAX) 32986470930SIngo Molnar return "unknown-ext-hardware-cache-type"; 33086470930SIngo Molnar 33186470930SIngo Molnar cache_op = (config >> 8) & 0xff; 33286470930SIngo Molnar if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX) 33386470930SIngo Molnar return "unknown-ext-hardware-cache-op"; 33486470930SIngo Molnar 33586470930SIngo Molnar cache_result = (config >> 16) & 0xff; 33686470930SIngo Molnar if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX) 33786470930SIngo Molnar return "unknown-ext-hardware-cache-result"; 33886470930SIngo Molnar 33906813f6cSJaswinder Singh Rajput if (!is_cache_op_valid(cache_type, cache_op)) 34006813f6cSJaswinder Singh Rajput return "invalid-cache"; 34186470930SIngo Molnar 342e5c59547SJaswinder Singh Rajput return event_cache_name(cache_type, cache_op, cache_result); 34386470930SIngo Molnar } 34486470930SIngo Molnar 34586470930SIngo Molnar case PERF_TYPE_SOFTWARE: 3461fc570adSIngo Molnar if (config < PERF_COUNT_SW_MAX && sw_event_names[config]) 34786470930SIngo Molnar return sw_event_names[config]; 34886470930SIngo Molnar return "unknown-software"; 34986470930SIngo Molnar 350f6bdafefSJason Baron case PERF_TYPE_TRACEPOINT: 351f6bdafefSJason Baron return tracepoint_id_to_name(config); 352f6bdafefSJason Baron 35386470930SIngo Molnar default: 35486470930SIngo Molnar break; 35586470930SIngo Molnar } 35686470930SIngo Molnar 35786470930SIngo Molnar return "unknown"; 35886470930SIngo Molnar } 35986470930SIngo Molnar 360b847cbdcSJiri Olsa static int add_event(struct list_head **_list, int *idx, 36189812fc8SJiri Olsa struct perf_event_attr *attr, char *name) 36289812fc8SJiri Olsa { 36389812fc8SJiri Olsa struct perf_evsel *evsel; 364b847cbdcSJiri Olsa struct list_head *list = *_list; 365b847cbdcSJiri Olsa 366b847cbdcSJiri Olsa if (!list) { 367b847cbdcSJiri Olsa list = malloc(sizeof(*list)); 368b847cbdcSJiri Olsa if (!list) 369b847cbdcSJiri Olsa return -ENOMEM; 370b847cbdcSJiri Olsa INIT_LIST_HEAD(list); 371b847cbdcSJiri Olsa } 37289812fc8SJiri Olsa 37389812fc8SJiri Olsa event_attr_init(attr); 37489812fc8SJiri Olsa 37589812fc8SJiri Olsa evsel = perf_evsel__new(attr, (*idx)++); 376b847cbdcSJiri Olsa if (!evsel) { 377b847cbdcSJiri Olsa free(list); 37889812fc8SJiri Olsa return -ENOMEM; 379b847cbdcSJiri Olsa } 38089812fc8SJiri Olsa 38189812fc8SJiri Olsa evsel->name = strdup(name); 382b847cbdcSJiri Olsa list_add_tail(&evsel->node, list); 383b847cbdcSJiri Olsa *_list = list; 38489812fc8SJiri Olsa return 0; 38589812fc8SJiri Olsa } 38689812fc8SJiri Olsa 38789812fc8SJiri Olsa static int parse_aliases(char *str, const char *names[][MAX_ALIASES], int size) 38886470930SIngo Molnar { 38986470930SIngo Molnar int i, j; 39061c45981SPaul Mackerras int n, longest = -1; 39186470930SIngo Molnar 39286470930SIngo Molnar for (i = 0; i < size; i++) { 39361c45981SPaul Mackerras for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { 39461c45981SPaul Mackerras n = strlen(names[i][j]); 39589812fc8SJiri Olsa if (n > longest && !strncasecmp(str, names[i][j], n)) 39661c45981SPaul Mackerras longest = n; 39761c45981SPaul Mackerras } 39889812fc8SJiri Olsa if (longest > 0) 39986470930SIngo Molnar return i; 40086470930SIngo Molnar } 40186470930SIngo Molnar 4028953645fSIngo Molnar return -1; 40386470930SIngo Molnar } 40486470930SIngo Molnar 405b847cbdcSJiri Olsa int parse_events_add_cache(struct list_head **list, int *idx, 40689812fc8SJiri Olsa char *type, char *op_result1, char *op_result2) 40786470930SIngo Molnar { 40889812fc8SJiri Olsa struct perf_event_attr attr; 40989812fc8SJiri Olsa char name[MAX_NAME_LEN]; 41061c45981SPaul Mackerras int cache_type = -1, cache_op = -1, cache_result = -1; 41189812fc8SJiri Olsa char *op_result[2] = { op_result1, op_result2 }; 41289812fc8SJiri Olsa int i, n; 41386470930SIngo Molnar 41486470930SIngo Molnar /* 41586470930SIngo Molnar * No fallback - if we cannot get a clear cache type 41686470930SIngo Molnar * then bail out: 41786470930SIngo Molnar */ 41889812fc8SJiri Olsa cache_type = parse_aliases(type, hw_cache, 41989812fc8SJiri Olsa PERF_COUNT_HW_CACHE_MAX); 42086470930SIngo Molnar if (cache_type == -1) 42189812fc8SJiri Olsa return -EINVAL; 42286470930SIngo Molnar 42389812fc8SJiri Olsa n = snprintf(name, MAX_NAME_LEN, "%s", type); 42489812fc8SJiri Olsa 42589812fc8SJiri Olsa for (i = 0; (i < 2) && (op_result[i]); i++) { 42689812fc8SJiri Olsa char *str = op_result[i]; 42789812fc8SJiri Olsa 42889812fc8SJiri Olsa snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); 42961c45981SPaul Mackerras 43061c45981SPaul Mackerras if (cache_op == -1) { 43189812fc8SJiri Olsa cache_op = parse_aliases(str, hw_cache_op, 43261c45981SPaul Mackerras PERF_COUNT_HW_CACHE_OP_MAX); 43361c45981SPaul Mackerras if (cache_op >= 0) { 43461c45981SPaul Mackerras if (!is_cache_op_valid(cache_type, cache_op)) 43589812fc8SJiri Olsa return -EINVAL; 43661c45981SPaul Mackerras continue; 43761c45981SPaul Mackerras } 43861c45981SPaul Mackerras } 43961c45981SPaul Mackerras 44061c45981SPaul Mackerras if (cache_result == -1) { 44189812fc8SJiri Olsa cache_result = parse_aliases(str, hw_cache_result, 44261c45981SPaul Mackerras PERF_COUNT_HW_CACHE_RESULT_MAX); 44361c45981SPaul Mackerras if (cache_result >= 0) 44461c45981SPaul Mackerras continue; 44561c45981SPaul Mackerras } 44661c45981SPaul Mackerras } 44761c45981SPaul Mackerras 44886470930SIngo Molnar /* 44986470930SIngo Molnar * Fall back to reads: 45086470930SIngo Molnar */ 4518953645fSIngo Molnar if (cache_op == -1) 4528953645fSIngo Molnar cache_op = PERF_COUNT_HW_CACHE_OP_READ; 45386470930SIngo Molnar 45486470930SIngo Molnar /* 45586470930SIngo Molnar * Fall back to accesses: 45686470930SIngo Molnar */ 45786470930SIngo Molnar if (cache_result == -1) 45886470930SIngo Molnar cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 45986470930SIngo Molnar 46089812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 46189812fc8SJiri Olsa attr.config = cache_type | (cache_op << 8) | (cache_result << 16); 46289812fc8SJiri Olsa attr.type = PERF_TYPE_HW_CACHE; 46389812fc8SJiri Olsa return add_event(list, idx, &attr, name); 46486470930SIngo Molnar } 46586470930SIngo Molnar 466b847cbdcSJiri Olsa static int add_tracepoint(struct list_head **list, int *idx, 46789812fc8SJiri Olsa char *sys_name, char *evt_name) 468bcd3279fSFrederic Weisbecker { 46989812fc8SJiri Olsa struct perf_event_attr attr; 47089812fc8SJiri Olsa char name[MAX_NAME_LEN]; 471bcd3279fSFrederic Weisbecker char evt_path[MAXPATHLEN]; 472bcd3279fSFrederic Weisbecker char id_buf[4]; 473bcd3279fSFrederic Weisbecker u64 id; 474bcd3279fSFrederic Weisbecker int fd; 475bcd3279fSFrederic Weisbecker 476ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", tracing_events_path, 477bcd3279fSFrederic Weisbecker sys_name, evt_name); 478bcd3279fSFrederic Weisbecker 479bcd3279fSFrederic Weisbecker fd = open(evt_path, O_RDONLY); 480bcd3279fSFrederic Weisbecker if (fd < 0) 48189812fc8SJiri Olsa return -1; 482bcd3279fSFrederic Weisbecker 483bcd3279fSFrederic Weisbecker if (read(fd, id_buf, sizeof(id_buf)) < 0) { 484bcd3279fSFrederic Weisbecker close(fd); 48589812fc8SJiri Olsa return -1; 486bcd3279fSFrederic Weisbecker } 487bcd3279fSFrederic Weisbecker 488bcd3279fSFrederic Weisbecker close(fd); 489bcd3279fSFrederic Weisbecker id = atoll(id_buf); 490bcd3279fSFrederic Weisbecker 49189812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 49289812fc8SJiri Olsa attr.config = id; 49389812fc8SJiri Olsa attr.type = PERF_TYPE_TRACEPOINT; 49489812fc8SJiri Olsa attr.sample_type |= PERF_SAMPLE_RAW; 49589812fc8SJiri Olsa attr.sample_type |= PERF_SAMPLE_TIME; 49689812fc8SJiri Olsa attr.sample_type |= PERF_SAMPLE_CPU; 49789812fc8SJiri Olsa attr.sample_period = 1; 4985710fcadSStephane Eranian 49989812fc8SJiri Olsa snprintf(name, MAX_NAME_LEN, "%s:%s", sys_name, evt_name); 50089812fc8SJiri Olsa return add_event(list, idx, &attr, name); 501bcd3279fSFrederic Weisbecker } 502bcd3279fSFrederic Weisbecker 503b847cbdcSJiri Olsa static int add_tracepoint_multi(struct list_head **list, int *idx, 50489812fc8SJiri Olsa char *sys_name, char *evt_name) 505bcd3279fSFrederic Weisbecker { 506bcd3279fSFrederic Weisbecker char evt_path[MAXPATHLEN]; 507bcd3279fSFrederic Weisbecker struct dirent *evt_ent; 508bcd3279fSFrederic Weisbecker DIR *evt_dir; 50989812fc8SJiri Olsa int ret = 0; 510bcd3279fSFrederic Weisbecker 511ebf294bfSArnaldo Carvalho de Melo snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); 512bcd3279fSFrederic Weisbecker evt_dir = opendir(evt_path); 513bcd3279fSFrederic Weisbecker if (!evt_dir) { 514bcd3279fSFrederic Weisbecker perror("Can't open event dir"); 51589812fc8SJiri Olsa return -1; 516bcd3279fSFrederic Weisbecker } 517bcd3279fSFrederic Weisbecker 51889812fc8SJiri Olsa while (!ret && (evt_ent = readdir(evt_dir))) { 519bcd3279fSFrederic Weisbecker if (!strcmp(evt_ent->d_name, ".") 520bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "..") 521bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "enable") 522bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "filter")) 523bcd3279fSFrederic Weisbecker continue; 524bcd3279fSFrederic Weisbecker 52589812fc8SJiri Olsa if (!strglobmatch(evt_ent->d_name, evt_name)) 526fb1d2edfSMasami Hiramatsu continue; 527fb1d2edfSMasami Hiramatsu 52889812fc8SJiri Olsa ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name); 529bcd3279fSFrederic Weisbecker } 530bcd3279fSFrederic Weisbecker 53189812fc8SJiri Olsa return ret; 532bcd3279fSFrederic Weisbecker } 533bcd3279fSFrederic Weisbecker 534b847cbdcSJiri Olsa int parse_events_add_tracepoint(struct list_head **list, int *idx, 53589812fc8SJiri Olsa char *sys, char *event) 536f6bdafefSJason Baron { 53789812fc8SJiri Olsa int ret; 538f6bdafefSJason Baron 53989812fc8SJiri Olsa ret = debugfs_valid_mountpoint(tracing_events_path); 54089812fc8SJiri Olsa if (ret) 54189812fc8SJiri Olsa return ret; 542f6bdafefSJason Baron 54389812fc8SJiri Olsa return strpbrk(event, "*?") ? 54489812fc8SJiri Olsa add_tracepoint_multi(list, idx, sys, event) : 54589812fc8SJiri Olsa add_tracepoint(list, idx, sys, event); 5463a9f131fSFrederic Weisbecker } 5473a9f131fSFrederic Weisbecker 54889812fc8SJiri Olsa static int 54989812fc8SJiri Olsa parse_breakpoint_type(const char *type, struct perf_event_attr *attr) 5501b290d67SFrederic Weisbecker { 5511b290d67SFrederic Weisbecker int i; 5521b290d67SFrederic Weisbecker 5531b290d67SFrederic Weisbecker for (i = 0; i < 3; i++) { 55489812fc8SJiri Olsa if (!type || !type[i]) 5551b290d67SFrederic Weisbecker break; 5561b290d67SFrederic Weisbecker 5571b290d67SFrederic Weisbecker switch (type[i]) { 5581b290d67SFrederic Weisbecker case 'r': 5591b290d67SFrederic Weisbecker attr->bp_type |= HW_BREAKPOINT_R; 5601b290d67SFrederic Weisbecker break; 5611b290d67SFrederic Weisbecker case 'w': 5621b290d67SFrederic Weisbecker attr->bp_type |= HW_BREAKPOINT_W; 5631b290d67SFrederic Weisbecker break; 5641b290d67SFrederic Weisbecker case 'x': 5651b290d67SFrederic Weisbecker attr->bp_type |= HW_BREAKPOINT_X; 5661b290d67SFrederic Weisbecker break; 5671b290d67SFrederic Weisbecker default: 56889812fc8SJiri Olsa return -EINVAL; 5691b290d67SFrederic Weisbecker } 5701b290d67SFrederic Weisbecker } 57189812fc8SJiri Olsa 5721b290d67SFrederic Weisbecker if (!attr->bp_type) /* Default */ 5731b290d67SFrederic Weisbecker attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 5741b290d67SFrederic Weisbecker 57589812fc8SJiri Olsa return 0; 5761b290d67SFrederic Weisbecker } 5771b290d67SFrederic Weisbecker 578b847cbdcSJiri Olsa int parse_events_add_breakpoint(struct list_head **list, int *idx, 57989812fc8SJiri Olsa void *ptr, char *type) 5801b290d67SFrederic Weisbecker { 58189812fc8SJiri Olsa struct perf_event_attr attr; 58289812fc8SJiri Olsa char name[MAX_NAME_LEN]; 5831b290d67SFrederic Weisbecker 58489812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 5859fafd98fSJiri Olsa attr.bp_addr = (unsigned long) ptr; 5861b290d67SFrederic Weisbecker 58789812fc8SJiri Olsa if (parse_breakpoint_type(type, &attr)) 58889812fc8SJiri Olsa return -EINVAL; 5891b290d67SFrederic Weisbecker 590aa59a485SFrederic Weisbecker /* 591aa59a485SFrederic Weisbecker * We should find a nice way to override the access length 592aa59a485SFrederic Weisbecker * Provide some defaults for now 593aa59a485SFrederic Weisbecker */ 59489812fc8SJiri Olsa if (attr.bp_type == HW_BREAKPOINT_X) 59589812fc8SJiri Olsa attr.bp_len = sizeof(long); 596aa59a485SFrederic Weisbecker else 59789812fc8SJiri Olsa attr.bp_len = HW_BREAKPOINT_LEN_4; 598aa59a485SFrederic Weisbecker 59989812fc8SJiri Olsa attr.type = PERF_TYPE_BREAKPOINT; 6001b290d67SFrederic Weisbecker 60189812fc8SJiri Olsa snprintf(name, MAX_NAME_LEN, "mem:%p:%s", ptr, type ? type : "rw"); 60289812fc8SJiri Olsa return add_event(list, idx, &attr, name); 6031b290d67SFrederic Weisbecker } 6041b290d67SFrederic Weisbecker 6058f707d84SJiri Olsa static int config_term(struct perf_event_attr *attr, 6068f707d84SJiri Olsa struct parse_events__term *term) 6078f707d84SJiri Olsa { 60816fa7e82SJiri Olsa #define CHECK_TYPE_VAL(type) \ 60916fa7e82SJiri Olsa do { \ 61016fa7e82SJiri Olsa if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val) \ 61116fa7e82SJiri Olsa return -EINVAL; \ 61216fa7e82SJiri Olsa } while (0) 61316fa7e82SJiri Olsa 61416fa7e82SJiri Olsa switch (term->type_term) { 6158f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG: 61616fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 6178f707d84SJiri Olsa attr->config = term->val.num; 6188f707d84SJiri Olsa break; 6198f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG1: 62016fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 6218f707d84SJiri Olsa attr->config1 = term->val.num; 6228f707d84SJiri Olsa break; 6238f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_CONFIG2: 62416fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 6258f707d84SJiri Olsa attr->config2 = term->val.num; 6268f707d84SJiri Olsa break; 6278f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 62816fa7e82SJiri Olsa CHECK_TYPE_VAL(NUM); 6298f707d84SJiri Olsa attr->sample_period = term->val.num; 6308f707d84SJiri Olsa break; 6318f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: 6328f707d84SJiri Olsa /* 6338f707d84SJiri Olsa * TODO uncomment when the field is available 6348f707d84SJiri Olsa * attr->branch_sample_type = term->val.num; 6358f707d84SJiri Olsa */ 6368f707d84SJiri Olsa break; 6378f707d84SJiri Olsa default: 6388f707d84SJiri Olsa return -EINVAL; 6398f707d84SJiri Olsa } 64016fa7e82SJiri Olsa 6418f707d84SJiri Olsa return 0; 64216fa7e82SJiri Olsa #undef CHECK_TYPE_VAL 6438f707d84SJiri Olsa } 6448f707d84SJiri Olsa 6458f707d84SJiri Olsa static int config_attr(struct perf_event_attr *attr, 6468f707d84SJiri Olsa struct list_head *head, int fail) 6478f707d84SJiri Olsa { 6488f707d84SJiri Olsa struct parse_events__term *term; 6498f707d84SJiri Olsa 6508f707d84SJiri Olsa list_for_each_entry(term, head, list) 6518f707d84SJiri Olsa if (config_term(attr, term) && fail) 6528f707d84SJiri Olsa return -EINVAL; 6538f707d84SJiri Olsa 6548f707d84SJiri Olsa return 0; 6558f707d84SJiri Olsa } 6568f707d84SJiri Olsa 657b847cbdcSJiri Olsa int parse_events_add_numeric(struct list_head **list, int *idx, 6588f707d84SJiri Olsa unsigned long type, unsigned long config, 6598f707d84SJiri Olsa struct list_head *head_config) 66074d5b588SJaswinder Singh Rajput { 66189812fc8SJiri Olsa struct perf_event_attr attr; 66274d5b588SJaswinder Singh Rajput 66389812fc8SJiri Olsa memset(&attr, 0, sizeof(attr)); 66489812fc8SJiri Olsa attr.type = type; 66589812fc8SJiri Olsa attr.config = config; 6668f707d84SJiri Olsa 6678f707d84SJiri Olsa if (head_config && 6688f707d84SJiri Olsa config_attr(&attr, head_config, 1)) 6698f707d84SJiri Olsa return -EINVAL; 6708f707d84SJiri Olsa 67189812fc8SJiri Olsa return add_event(list, idx, &attr, 67289812fc8SJiri Olsa (char *) __event_name(type, config)); 673b908debdSIngo Molnar } 674b908debdSIngo Molnar 675b847cbdcSJiri Olsa int parse_events_add_pmu(struct list_head **list, int *idx, 6765f537a26SJiri Olsa char *name, struct list_head *head_config) 6775f537a26SJiri Olsa { 6785f537a26SJiri Olsa struct perf_event_attr attr; 6795f537a26SJiri Olsa struct perf_pmu *pmu; 6805f537a26SJiri Olsa 6815f537a26SJiri Olsa pmu = perf_pmu__find(name); 6825f537a26SJiri Olsa if (!pmu) 6835f537a26SJiri Olsa return -EINVAL; 6845f537a26SJiri Olsa 6855f537a26SJiri Olsa memset(&attr, 0, sizeof(attr)); 6865f537a26SJiri Olsa 6875f537a26SJiri Olsa /* 6885f537a26SJiri Olsa * Configure hardcoded terms first, no need to check 6895f537a26SJiri Olsa * return value when called with fail == 0 ;) 6905f537a26SJiri Olsa */ 6915f537a26SJiri Olsa config_attr(&attr, head_config, 0); 6925f537a26SJiri Olsa 6935f537a26SJiri Olsa if (perf_pmu__config(pmu, &attr, head_config)) 6945f537a26SJiri Olsa return -EINVAL; 6955f537a26SJiri Olsa 6965f537a26SJiri Olsa return add_event(list, idx, &attr, (char *) "pmu"); 6975f537a26SJiri Olsa } 6985f537a26SJiri Olsa 6995d7be90eSJiri Olsa void parse_events_update_lists(struct list_head *list_event, 7005d7be90eSJiri Olsa struct list_head *list_all) 7015d7be90eSJiri Olsa { 7025d7be90eSJiri Olsa /* 7035d7be90eSJiri Olsa * Called for single event definition. Update the 7045d7be90eSJiri Olsa * 'all event' list, and reinit the 'signle event' 7055d7be90eSJiri Olsa * list, for next event definition. 7065d7be90eSJiri Olsa */ 7075d7be90eSJiri Olsa list_splice_tail(list_event, list_all); 708b847cbdcSJiri Olsa free(list_event); 7095d7be90eSJiri Olsa } 7105d7be90eSJiri Olsa 71189812fc8SJiri Olsa int parse_events_modifier(struct list_head *list, char *str) 71261c45981SPaul Mackerras { 71389812fc8SJiri Olsa struct perf_evsel *evsel; 71499320cc8SJoerg Roedel int exclude = 0, exclude_GH = 0; 71599320cc8SJoerg Roedel int eu = 0, ek = 0, eh = 0, eH = 0, eG = 0, precise = 0; 71661c45981SPaul Mackerras 71789812fc8SJiri Olsa if (str == NULL) 71861c45981SPaul Mackerras return 0; 719ceb53fbfSIngo Molnar 72061c45981SPaul Mackerras while (*str) { 721ab608344SPeter Zijlstra if (*str == 'u') { 722ab608344SPeter Zijlstra if (!exclude) 723ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 72461c45981SPaul Mackerras eu = 0; 725ab608344SPeter Zijlstra } else if (*str == 'k') { 726ab608344SPeter Zijlstra if (!exclude) 727ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 72861c45981SPaul Mackerras ek = 0; 729ab608344SPeter Zijlstra } else if (*str == 'h') { 730ab608344SPeter Zijlstra if (!exclude) 731ab608344SPeter Zijlstra exclude = eu = ek = eh = 1; 73261c45981SPaul Mackerras eh = 0; 73399320cc8SJoerg Roedel } else if (*str == 'G') { 73499320cc8SJoerg Roedel if (!exclude_GH) 73599320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 73699320cc8SJoerg Roedel eG = 0; 73799320cc8SJoerg Roedel } else if (*str == 'H') { 73899320cc8SJoerg Roedel if (!exclude_GH) 73999320cc8SJoerg Roedel exclude_GH = eG = eH = 1; 74099320cc8SJoerg Roedel eH = 0; 741ab608344SPeter Zijlstra } else if (*str == 'p') { 742ab608344SPeter Zijlstra precise++; 743ab608344SPeter Zijlstra } else 74461c45981SPaul Mackerras break; 745ab608344SPeter Zijlstra 74661c45981SPaul Mackerras ++str; 74761c45981SPaul Mackerras } 74874d5b588SJaswinder Singh Rajput 74986470930SIngo Molnar /* 75089812fc8SJiri Olsa * precise ip: 75189812fc8SJiri Olsa * 75289812fc8SJiri Olsa * 0 - SAMPLE_IP can have arbitrary skid 75389812fc8SJiri Olsa * 1 - SAMPLE_IP must have constant skid 75489812fc8SJiri Olsa * 2 - SAMPLE_IP requested to have 0 skid 75589812fc8SJiri Olsa * 3 - SAMPLE_IP must have 0 skid 75689812fc8SJiri Olsa * 75789812fc8SJiri Olsa * See also PERF_RECORD_MISC_EXACT_IP 75886470930SIngo Molnar */ 75989812fc8SJiri Olsa if (precise > 3) 76089812fc8SJiri Olsa return -EINVAL; 76186470930SIngo Molnar 76289812fc8SJiri Olsa list_for_each_entry(evsel, list, node) { 76389812fc8SJiri Olsa evsel->attr.exclude_user = eu; 76489812fc8SJiri Olsa evsel->attr.exclude_kernel = ek; 76589812fc8SJiri Olsa evsel->attr.exclude_hv = eh; 76689812fc8SJiri Olsa evsel->attr.precise_ip = precise; 76789812fc8SJiri Olsa evsel->attr.exclude_host = eH; 76889812fc8SJiri Olsa evsel->attr.exclude_guest = eG; 769ceb53fbfSIngo Molnar } 77086470930SIngo Molnar 77189812fc8SJiri Olsa return 0; 77286470930SIngo Molnar } 77386470930SIngo Molnar 774f120f9d5SJiri Olsa int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) 77586470930SIngo Molnar { 77689812fc8SJiri Olsa LIST_HEAD(list); 7775d7be90eSJiri Olsa LIST_HEAD(list_tmp); 77889812fc8SJiri Olsa YY_BUFFER_STATE buffer; 77989812fc8SJiri Olsa int ret, idx = evlist->nr_entries; 78086470930SIngo Molnar 78189812fc8SJiri Olsa buffer = parse_events__scan_string(str); 78261c45981SPaul Mackerras 78382ba1f2fSJiri Olsa #ifdef PARSER_DEBUG 78482ba1f2fSJiri Olsa parse_events_debug = 1; 78582ba1f2fSJiri Olsa #endif 786b847cbdcSJiri Olsa ret = parse_events_parse(&list, &idx); 78786470930SIngo Molnar 78889812fc8SJiri Olsa parse_events__flush_buffer(buffer); 78989812fc8SJiri Olsa parse_events__delete_buffer(buffer); 790*08d2f762SJiri Olsa parse_events_lex_destroy(); 791f0c55bcfSStephane Eranian 79289812fc8SJiri Olsa if (!ret) { 79389812fc8SJiri Olsa int entries = idx - evlist->nr_entries; 79489812fc8SJiri Olsa perf_evlist__splice_list_tail(evlist, &list, entries); 79586470930SIngo Molnar return 0; 79686470930SIngo Molnar } 79786470930SIngo Molnar 7985d7be90eSJiri Olsa /* 7995d7be90eSJiri Olsa * There are 2 users - builtin-record and builtin-test objects. 8005d7be90eSJiri Olsa * Both call perf_evlist__delete in case of error, so we dont 8015d7be90eSJiri Olsa * need to bother. 8025d7be90eSJiri Olsa */ 80389812fc8SJiri Olsa fprintf(stderr, "invalid or unsupported event: '%s'\n", str); 80489812fc8SJiri Olsa fprintf(stderr, "Run 'perf list' for a list of valid events\n"); 80589812fc8SJiri Olsa return ret; 80689812fc8SJiri Olsa } 80789812fc8SJiri Olsa 808f120f9d5SJiri Olsa int parse_events_option(const struct option *opt, const char *str, 809f120f9d5SJiri Olsa int unset __used) 810f120f9d5SJiri Olsa { 811f120f9d5SJiri Olsa struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 812f120f9d5SJiri Olsa return parse_events(evlist, str, unset); 813f120f9d5SJiri Olsa } 814f120f9d5SJiri Olsa 815361c99a6SArnaldo Carvalho de Melo int parse_filter(const struct option *opt, const char *str, 816c171b552SLi Zefan int unset __used) 817c171b552SLi Zefan { 818361c99a6SArnaldo Carvalho de Melo struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 81969aad6f1SArnaldo Carvalho de Melo struct perf_evsel *last = NULL; 820c171b552SLi Zefan 821361c99a6SArnaldo Carvalho de Melo if (evlist->nr_entries > 0) 822361c99a6SArnaldo Carvalho de Melo last = list_entry(evlist->entries.prev, struct perf_evsel, node); 82369aad6f1SArnaldo Carvalho de Melo 82469aad6f1SArnaldo Carvalho de Melo if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { 825c171b552SLi Zefan fprintf(stderr, 826c171b552SLi Zefan "-F option should follow a -e tracepoint option\n"); 827c171b552SLi Zefan return -1; 828c171b552SLi Zefan } 829c171b552SLi Zefan 83069aad6f1SArnaldo Carvalho de Melo last->filter = strdup(str); 83169aad6f1SArnaldo Carvalho de Melo if (last->filter == NULL) { 832c171b552SLi Zefan fprintf(stderr, "not enough memory to hold filter string\n"); 833c171b552SLi Zefan return -1; 834c171b552SLi Zefan } 835c171b552SLi Zefan 836c171b552SLi Zefan return 0; 837c171b552SLi Zefan } 838c171b552SLi Zefan 83986470930SIngo Molnar static const char * const event_type_descriptors[] = { 84086470930SIngo Molnar "Hardware event", 84186470930SIngo Molnar "Software event", 84286470930SIngo Molnar "Tracepoint event", 84386470930SIngo Molnar "Hardware cache event", 84441bdcb23SLiming Wang "Raw hardware event descriptor", 84541bdcb23SLiming Wang "Hardware breakpoint", 84686470930SIngo Molnar }; 84786470930SIngo Molnar 84886470930SIngo Molnar /* 849f6bdafefSJason Baron * Print the events from <debugfs_mount_point>/tracing/events 850f6bdafefSJason Baron */ 851f6bdafefSJason Baron 852668b8788SArnaldo Carvalho de Melo void print_tracepoint_events(const char *subsys_glob, const char *event_glob) 853f6bdafefSJason Baron { 854f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 855f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 856f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 857725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 858f6bdafefSJason Baron 859ebf294bfSArnaldo Carvalho de Melo if (debugfs_valid_mountpoint(tracing_events_path)) 860f6bdafefSJason Baron return; 861f6bdafefSJason Baron 862ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 863f6bdafefSJason Baron if (!sys_dir) 864725b1368SEric Dumazet return; 865f6bdafefSJason Baron 8666b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 867668b8788SArnaldo Carvalho de Melo if (subsys_glob != NULL && 868668b8788SArnaldo Carvalho de Melo !strglobmatch(sys_dirent.d_name, subsys_glob)) 869668b8788SArnaldo Carvalho de Melo continue; 870725b1368SEric Dumazet 871ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 872725b1368SEric Dumazet sys_dirent.d_name); 873725b1368SEric Dumazet evt_dir = opendir(dir_path); 874725b1368SEric Dumazet if (!evt_dir) 8756b58e7f1SUlrich Drepper continue; 876725b1368SEric Dumazet 8776b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 878668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 879668b8788SArnaldo Carvalho de Melo !strglobmatch(evt_dirent.d_name, event_glob)) 880668b8788SArnaldo Carvalho de Melo continue; 881668b8788SArnaldo Carvalho de Melo 882f6bdafefSJason Baron snprintf(evt_path, MAXPATHLEN, "%s:%s", 883f6bdafefSJason Baron sys_dirent.d_name, evt_dirent.d_name); 884947b4ad1SIngo Molnar printf(" %-50s [%s]\n", evt_path, 88541bdcb23SLiming Wang event_type_descriptors[PERF_TYPE_TRACEPOINT]); 886f6bdafefSJason Baron } 887f6bdafefSJason Baron closedir(evt_dir); 888f6bdafefSJason Baron } 889f6bdafefSJason Baron closedir(sys_dir); 890f6bdafefSJason Baron } 891f6bdafefSJason Baron 892f6bdafefSJason Baron /* 89320c457b8SThomas Renninger * Check whether event is in <debugfs_mount_point>/tracing/events 89420c457b8SThomas Renninger */ 89520c457b8SThomas Renninger 89620c457b8SThomas Renninger int is_valid_tracepoint(const char *event_string) 89720c457b8SThomas Renninger { 89820c457b8SThomas Renninger DIR *sys_dir, *evt_dir; 89920c457b8SThomas Renninger struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 90020c457b8SThomas Renninger char evt_path[MAXPATHLEN]; 90120c457b8SThomas Renninger char dir_path[MAXPATHLEN]; 90220c457b8SThomas Renninger 903ebf294bfSArnaldo Carvalho de Melo if (debugfs_valid_mountpoint(tracing_events_path)) 90420c457b8SThomas Renninger return 0; 90520c457b8SThomas Renninger 906ebf294bfSArnaldo Carvalho de Melo sys_dir = opendir(tracing_events_path); 90720c457b8SThomas Renninger if (!sys_dir) 90820c457b8SThomas Renninger return 0; 90920c457b8SThomas Renninger 91020c457b8SThomas Renninger for_each_subsystem(sys_dir, sys_dirent, sys_next) { 91120c457b8SThomas Renninger 912ebf294bfSArnaldo Carvalho de Melo snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, 91320c457b8SThomas Renninger sys_dirent.d_name); 91420c457b8SThomas Renninger evt_dir = opendir(dir_path); 91520c457b8SThomas Renninger if (!evt_dir) 91620c457b8SThomas Renninger continue; 91720c457b8SThomas Renninger 91820c457b8SThomas Renninger for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 91920c457b8SThomas Renninger snprintf(evt_path, MAXPATHLEN, "%s:%s", 92020c457b8SThomas Renninger sys_dirent.d_name, evt_dirent.d_name); 92120c457b8SThomas Renninger if (!strcmp(evt_path, event_string)) { 92220c457b8SThomas Renninger closedir(evt_dir); 92320c457b8SThomas Renninger closedir(sys_dir); 92420c457b8SThomas Renninger return 1; 92520c457b8SThomas Renninger } 92620c457b8SThomas Renninger } 92720c457b8SThomas Renninger closedir(evt_dir); 92820c457b8SThomas Renninger } 92920c457b8SThomas Renninger closedir(sys_dir); 93020c457b8SThomas Renninger return 0; 93120c457b8SThomas Renninger } 93220c457b8SThomas Renninger 933668b8788SArnaldo Carvalho de Melo void print_events_type(u8 type) 934668b8788SArnaldo Carvalho de Melo { 935668b8788SArnaldo Carvalho de Melo struct event_symbol *syms = event_symbols; 936668b8788SArnaldo Carvalho de Melo unsigned int i; 937668b8788SArnaldo Carvalho de Melo char name[64]; 938668b8788SArnaldo Carvalho de Melo 939668b8788SArnaldo Carvalho de Melo for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 940668b8788SArnaldo Carvalho de Melo if (type != syms->type) 941668b8788SArnaldo Carvalho de Melo continue; 942668b8788SArnaldo Carvalho de Melo 943668b8788SArnaldo Carvalho de Melo if (strlen(syms->alias)) 944668b8788SArnaldo Carvalho de Melo snprintf(name, sizeof(name), "%s OR %s", 945668b8788SArnaldo Carvalho de Melo syms->symbol, syms->alias); 946668b8788SArnaldo Carvalho de Melo else 947668b8788SArnaldo Carvalho de Melo snprintf(name, sizeof(name), "%s", syms->symbol); 948668b8788SArnaldo Carvalho de Melo 949947b4ad1SIngo Molnar printf(" %-50s [%s]\n", name, 950668b8788SArnaldo Carvalho de Melo event_type_descriptors[type]); 951668b8788SArnaldo Carvalho de Melo } 952668b8788SArnaldo Carvalho de Melo } 953668b8788SArnaldo Carvalho de Melo 954668b8788SArnaldo Carvalho de Melo int print_hwcache_events(const char *event_glob) 955668b8788SArnaldo Carvalho de Melo { 956668b8788SArnaldo Carvalho de Melo unsigned int type, op, i, printed = 0; 957668b8788SArnaldo Carvalho de Melo 958668b8788SArnaldo Carvalho de Melo for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 959668b8788SArnaldo Carvalho de Melo for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 960668b8788SArnaldo Carvalho de Melo /* skip invalid cache type */ 961668b8788SArnaldo Carvalho de Melo if (!is_cache_op_valid(type, op)) 962668b8788SArnaldo Carvalho de Melo continue; 963668b8788SArnaldo Carvalho de Melo 964668b8788SArnaldo Carvalho de Melo for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 965668b8788SArnaldo Carvalho de Melo char *name = event_cache_name(type, op, i); 966668b8788SArnaldo Carvalho de Melo 967947b4ad1SIngo Molnar if (event_glob != NULL && !strglobmatch(name, event_glob)) 968668b8788SArnaldo Carvalho de Melo continue; 969668b8788SArnaldo Carvalho de Melo 970947b4ad1SIngo Molnar printf(" %-50s [%s]\n", name, 971668b8788SArnaldo Carvalho de Melo event_type_descriptors[PERF_TYPE_HW_CACHE]); 972668b8788SArnaldo Carvalho de Melo ++printed; 973668b8788SArnaldo Carvalho de Melo } 974668b8788SArnaldo Carvalho de Melo } 975668b8788SArnaldo Carvalho de Melo } 976668b8788SArnaldo Carvalho de Melo 977668b8788SArnaldo Carvalho de Melo return printed; 978668b8788SArnaldo Carvalho de Melo } 979668b8788SArnaldo Carvalho de Melo 98020c457b8SThomas Renninger /* 98186470930SIngo Molnar * Print the help text for the event symbols: 98286470930SIngo Molnar */ 983668b8788SArnaldo Carvalho de Melo void print_events(const char *event_glob) 98486470930SIngo Molnar { 985668b8788SArnaldo Carvalho de Melo unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; 986947b4ad1SIngo Molnar struct event_symbol *syms = event_symbols; 987947b4ad1SIngo Molnar char name[MAX_NAME_LEN]; 98886470930SIngo Molnar 989689d3018SMarti Raudsepp printf("\n"); 990689d3018SMarti Raudsepp printf("List of pre-defined events (to be used in -e):\n"); 99186470930SIngo Molnar 99286470930SIngo Molnar for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 99341bdcb23SLiming Wang type = syms->type; 99486470930SIngo Molnar 995668b8788SArnaldo Carvalho de Melo if (type != prev_type && printed) { 996689d3018SMarti Raudsepp printf("\n"); 997668b8788SArnaldo Carvalho de Melo printed = 0; 998668b8788SArnaldo Carvalho de Melo ntypes_printed++; 999668b8788SArnaldo Carvalho de Melo } 1000668b8788SArnaldo Carvalho de Melo 1001668b8788SArnaldo Carvalho de Melo if (event_glob != NULL && 1002668b8788SArnaldo Carvalho de Melo !(strglobmatch(syms->symbol, event_glob) || 1003668b8788SArnaldo Carvalho de Melo (syms->alias && strglobmatch(syms->alias, event_glob)))) 1004668b8788SArnaldo Carvalho de Melo continue; 100586470930SIngo Molnar 100674d5b588SJaswinder Singh Rajput if (strlen(syms->alias)) 1007947b4ad1SIngo Molnar snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 100874d5b588SJaswinder Singh Rajput else 1009947b4ad1SIngo Molnar strncpy(name, syms->symbol, MAX_NAME_LEN); 1010947b4ad1SIngo Molnar printf(" %-50s [%s]\n", name, 101186470930SIngo Molnar event_type_descriptors[type]); 101286470930SIngo Molnar 101386470930SIngo Molnar prev_type = type; 1014668b8788SArnaldo Carvalho de Melo ++printed; 101586470930SIngo Molnar } 101686470930SIngo Molnar 1017668b8788SArnaldo Carvalho de Melo if (ntypes_printed) { 1018668b8788SArnaldo Carvalho de Melo printed = 0; 1019689d3018SMarti Raudsepp printf("\n"); 1020668b8788SArnaldo Carvalho de Melo } 1021668b8788SArnaldo Carvalho de Melo print_hwcache_events(event_glob); 102273c24cb8SJaswinder Singh Rajput 1023668b8788SArnaldo Carvalho de Melo if (event_glob != NULL) 1024668b8788SArnaldo Carvalho de Melo return; 102573c24cb8SJaswinder Singh Rajput 1026689d3018SMarti Raudsepp printf("\n"); 1027947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 10285f537a26SJiri Olsa "rNNN", 10291cf4a063SArnaldo Carvalho de Melo event_type_descriptors[PERF_TYPE_RAW]); 10305f537a26SJiri Olsa printf(" %-50s [%s]\n", 10315f537a26SJiri Olsa "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 10325f537a26SJiri Olsa event_type_descriptors[PERF_TYPE_RAW]); 10335f537a26SJiri Olsa printf(" (see 'perf list --help' on how to encode it)\n"); 1034689d3018SMarti Raudsepp printf("\n"); 103586470930SIngo Molnar 1036947b4ad1SIngo Molnar printf(" %-50s [%s]\n", 103741bdcb23SLiming Wang "mem:<addr>[:access]", 103841bdcb23SLiming Wang event_type_descriptors[PERF_TYPE_BREAKPOINT]); 10391b290d67SFrederic Weisbecker printf("\n"); 10401b290d67SFrederic Weisbecker 1041668b8788SArnaldo Carvalho de Melo print_tracepoint_events(NULL, NULL); 104286470930SIngo Molnar } 10438f707d84SJiri Olsa 10448f707d84SJiri Olsa int parse_events__is_hardcoded_term(struct parse_events__term *term) 10458f707d84SJiri Olsa { 104616fa7e82SJiri Olsa return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; 10478f707d84SJiri Olsa } 10488f707d84SJiri Olsa 104916fa7e82SJiri Olsa static int new_term(struct parse_events__term **_term, int type_val, 105016fa7e82SJiri Olsa int type_term, char *config, 105116fa7e82SJiri Olsa char *str, long num) 10528f707d84SJiri Olsa { 10538f707d84SJiri Olsa struct parse_events__term *term; 10548f707d84SJiri Olsa 10558f707d84SJiri Olsa term = zalloc(sizeof(*term)); 10568f707d84SJiri Olsa if (!term) 10578f707d84SJiri Olsa return -ENOMEM; 10588f707d84SJiri Olsa 10598f707d84SJiri Olsa INIT_LIST_HEAD(&term->list); 106016fa7e82SJiri Olsa term->type_val = type_val; 106116fa7e82SJiri Olsa term->type_term = type_term; 10628f707d84SJiri Olsa term->config = config; 10638f707d84SJiri Olsa 106416fa7e82SJiri Olsa switch (type_val) { 10658f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_NUM: 10668f707d84SJiri Olsa term->val.num = num; 10678f707d84SJiri Olsa break; 10688f707d84SJiri Olsa case PARSE_EVENTS__TERM_TYPE_STR: 10698f707d84SJiri Olsa term->val.str = str; 10708f707d84SJiri Olsa break; 10718f707d84SJiri Olsa default: 10728f707d84SJiri Olsa return -EINVAL; 10738f707d84SJiri Olsa } 10748f707d84SJiri Olsa 10758f707d84SJiri Olsa *_term = term; 10768f707d84SJiri Olsa return 0; 10778f707d84SJiri Olsa } 10788f707d84SJiri Olsa 107916fa7e82SJiri Olsa int parse_events__term_num(struct parse_events__term **term, 108016fa7e82SJiri Olsa int type_term, char *config, long num) 108116fa7e82SJiri Olsa { 108216fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, 108316fa7e82SJiri Olsa config, NULL, num); 108416fa7e82SJiri Olsa } 108516fa7e82SJiri Olsa 108616fa7e82SJiri Olsa int parse_events__term_str(struct parse_events__term **term, 108716fa7e82SJiri Olsa int type_term, char *config, char *str) 108816fa7e82SJiri Olsa { 108916fa7e82SJiri Olsa return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, 109016fa7e82SJiri Olsa config, str, 0); 109116fa7e82SJiri Olsa } 109216fa7e82SJiri Olsa 10938f707d84SJiri Olsa void parse_events__free_terms(struct list_head *terms) 10948f707d84SJiri Olsa { 10958f707d84SJiri Olsa struct parse_events__term *term, *h; 10968f707d84SJiri Olsa 10978f707d84SJiri Olsa list_for_each_entry_safe(term, h, terms, list) 10988f707d84SJiri Olsa free(term); 10998f707d84SJiri Olsa 11008f707d84SJiri Olsa free(terms); 11018f707d84SJiri Olsa } 1102