186470930SIngo Molnar 286470930SIngo Molnar #include "util.h" 36b58e7f1SUlrich Drepper #include "../perf.h" 486470930SIngo Molnar #include "parse-options.h" 586470930SIngo Molnar #include "parse-events.h" 686470930SIngo Molnar #include "exec_cmd.h" 786470930SIngo Molnar #include "string.h" 85beeded1SJason Baron #include "cache.h" 98755a8f2SArjan van de Ven #include "header.h" 10*549104f2SClark Williams #include "debugfs.h" 1186470930SIngo Molnar 1286470930SIngo Molnar int nr_counters; 1386470930SIngo Molnar 14cdd6c482SIngo Molnar struct perf_event_attr attrs[MAX_COUNTERS]; 15c171b552SLi Zefan char *filters[MAX_COUNTERS]; 1686470930SIngo Molnar 1786470930SIngo Molnar struct event_symbol { 189cffa8d5SPaul Mackerras u8 type; 199cffa8d5SPaul Mackerras u64 config; 2083a0944fSIngo Molnar const char *symbol; 2183a0944fSIngo Molnar const char *alias; 2286470930SIngo Molnar }; 2386470930SIngo Molnar 24bcd3279fSFrederic Weisbecker enum event_result { 25bcd3279fSFrederic Weisbecker EVT_FAILED, 26bcd3279fSFrederic Weisbecker EVT_HANDLED, 27bcd3279fSFrederic Weisbecker EVT_HANDLED_ALL 28bcd3279fSFrederic Weisbecker }; 29bcd3279fSFrederic Weisbecker 305beeded1SJason Baron char debugfs_path[MAXPATHLEN]; 315beeded1SJason Baron 3251e26842SJaswinder Singh Rajput #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x 3351e26842SJaswinder Singh Rajput #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 3486470930SIngo Molnar 3586470930SIngo Molnar static struct event_symbol event_symbols[] = { 3674d5b588SJaswinder Singh Rajput { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, 3774d5b588SJaswinder Singh Rajput { CHW(INSTRUCTIONS), "instructions", "" }, 3874d5b588SJaswinder Singh Rajput { CHW(CACHE_REFERENCES), "cache-references", "" }, 3974d5b588SJaswinder Singh Rajput { CHW(CACHE_MISSES), "cache-misses", "" }, 4074d5b588SJaswinder Singh Rajput { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, 4174d5b588SJaswinder Singh Rajput { CHW(BRANCH_MISSES), "branch-misses", "" }, 4274d5b588SJaswinder Singh Rajput { CHW(BUS_CYCLES), "bus-cycles", "" }, 4386470930SIngo Molnar 4474d5b588SJaswinder Singh Rajput { CSW(CPU_CLOCK), "cpu-clock", "" }, 4574d5b588SJaswinder Singh Rajput { CSW(TASK_CLOCK), "task-clock", "" }, 46c0c22dbfSJaswinder Singh Rajput { CSW(PAGE_FAULTS), "page-faults", "faults" }, 4774d5b588SJaswinder Singh Rajput { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, 4874d5b588SJaswinder Singh Rajput { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, 4974d5b588SJaswinder Singh Rajput { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, 5074d5b588SJaswinder Singh Rajput { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 5186470930SIngo Molnar }; 5286470930SIngo Molnar 53cdd6c482SIngo Molnar #define __PERF_EVENT_FIELD(config, name) \ 54cdd6c482SIngo Molnar ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 5586470930SIngo Molnar 56cdd6c482SIngo Molnar #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 57cdd6c482SIngo Molnar #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 58cdd6c482SIngo Molnar #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 59cdd6c482SIngo Molnar #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 6086470930SIngo Molnar 6183a0944fSIngo Molnar static const char *hw_event_names[] = { 6286470930SIngo Molnar "cycles", 6386470930SIngo Molnar "instructions", 6486470930SIngo Molnar "cache-references", 6586470930SIngo Molnar "cache-misses", 6686470930SIngo Molnar "branches", 6786470930SIngo Molnar "branch-misses", 6886470930SIngo Molnar "bus-cycles", 6986470930SIngo Molnar }; 7086470930SIngo Molnar 7183a0944fSIngo Molnar static const char *sw_event_names[] = { 7244175b6fSIngo Molnar "cpu-clock-msecs", 7344175b6fSIngo Molnar "task-clock-msecs", 7486470930SIngo Molnar "page-faults", 7586470930SIngo Molnar "context-switches", 7686470930SIngo Molnar "CPU-migrations", 7786470930SIngo Molnar "minor-faults", 7886470930SIngo Molnar "major-faults", 7986470930SIngo Molnar }; 8086470930SIngo Molnar 8186470930SIngo Molnar #define MAX_ALIASES 8 8286470930SIngo Molnar 8383a0944fSIngo Molnar static const char *hw_cache[][MAX_ALIASES] = { 849590b7baSAnton Blanchard { "L1-dcache", "l1-d", "l1d", "L1-data", }, 859590b7baSAnton Blanchard { "L1-icache", "l1-i", "l1i", "L1-instruction", }, 86e5c59547SJaswinder Singh Rajput { "LLC", "L2" }, 87e5c59547SJaswinder Singh Rajput { "dTLB", "d-tlb", "Data-TLB", }, 88e5c59547SJaswinder Singh Rajput { "iTLB", "i-tlb", "Instruction-TLB", }, 89e5c59547SJaswinder Singh Rajput { "branch", "branches", "bpu", "btb", "bpc", }, 9086470930SIngo Molnar }; 9186470930SIngo Molnar 9283a0944fSIngo Molnar static const char *hw_cache_op[][MAX_ALIASES] = { 93e5c59547SJaswinder Singh Rajput { "load", "loads", "read", }, 94e5c59547SJaswinder Singh Rajput { "store", "stores", "write", }, 95e5c59547SJaswinder Singh Rajput { "prefetch", "prefetches", "speculative-read", "speculative-load", }, 9686470930SIngo Molnar }; 9786470930SIngo Molnar 9883a0944fSIngo Molnar static const char *hw_cache_result[][MAX_ALIASES] = { 99e5c59547SJaswinder Singh Rajput { "refs", "Reference", "ops", "access", }, 100e5c59547SJaswinder Singh Rajput { "misses", "miss", }, 10186470930SIngo Molnar }; 10286470930SIngo Molnar 10306813f6cSJaswinder Singh Rajput #define C(x) PERF_COUNT_HW_CACHE_##x 10406813f6cSJaswinder Singh Rajput #define CACHE_READ (1 << C(OP_READ)) 10506813f6cSJaswinder Singh Rajput #define CACHE_WRITE (1 << C(OP_WRITE)) 10606813f6cSJaswinder Singh Rajput #define CACHE_PREFETCH (1 << C(OP_PREFETCH)) 10706813f6cSJaswinder Singh Rajput #define COP(x) (1 << x) 10806813f6cSJaswinder Singh Rajput 10906813f6cSJaswinder Singh Rajput /* 11006813f6cSJaswinder Singh Rajput * cache operartion stat 11106813f6cSJaswinder Singh Rajput * L1I : Read and prefetch only 11206813f6cSJaswinder Singh Rajput * ITLB and BPU : Read-only 11306813f6cSJaswinder Singh Rajput */ 11406813f6cSJaswinder Singh Rajput static unsigned long hw_cache_stat[C(MAX)] = { 11506813f6cSJaswinder Singh Rajput [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 11606813f6cSJaswinder Singh Rajput [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), 11706813f6cSJaswinder Singh Rajput [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 11806813f6cSJaswinder Singh Rajput [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), 11906813f6cSJaswinder Singh Rajput [C(ITLB)] = (CACHE_READ), 12006813f6cSJaswinder Singh Rajput [C(BPU)] = (CACHE_READ), 12106813f6cSJaswinder Singh Rajput }; 12206813f6cSJaswinder Singh Rajput 1236b58e7f1SUlrich Drepper #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 124f6bdafefSJason Baron while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 1256b58e7f1SUlrich Drepper if (sys_dirent.d_type == DT_DIR && \ 126f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".")) && \ 127f6bdafefSJason Baron (strcmp(sys_dirent.d_name, ".."))) 128f6bdafefSJason Baron 129ae07b63fSPeter Zijlstra static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) 130ae07b63fSPeter Zijlstra { 131ae07b63fSPeter Zijlstra char evt_path[MAXPATHLEN]; 132ae07b63fSPeter Zijlstra int fd; 133ae07b63fSPeter Zijlstra 134ae07b63fSPeter Zijlstra snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path, 135ae07b63fSPeter Zijlstra sys_dir->d_name, evt_dir->d_name); 136ae07b63fSPeter Zijlstra fd = open(evt_path, O_RDONLY); 137ae07b63fSPeter Zijlstra if (fd < 0) 138ae07b63fSPeter Zijlstra return -EINVAL; 139ae07b63fSPeter Zijlstra close(fd); 140ae07b63fSPeter Zijlstra 141ae07b63fSPeter Zijlstra return 0; 142ae07b63fSPeter Zijlstra } 143ae07b63fSPeter Zijlstra 1446b58e7f1SUlrich Drepper #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ 145f6bdafefSJason Baron while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 1466b58e7f1SUlrich Drepper if (evt_dirent.d_type == DT_DIR && \ 147f6bdafefSJason Baron (strcmp(evt_dirent.d_name, ".")) && \ 148ae07b63fSPeter Zijlstra (strcmp(evt_dirent.d_name, "..")) && \ 149ae07b63fSPeter Zijlstra (!tp_event_has_id(&sys_dirent, &evt_dirent))) 150f6bdafefSJason Baron 151270bbbe8SLi Zefan #define MAX_EVENT_LENGTH 512 152f6bdafefSJason Baron 153f6bdafefSJason Baron 1541ef2ed10SFrederic Weisbecker struct tracepoint_path *tracepoint_id_to_path(u64 config) 155f6bdafefSJason Baron { 1561ef2ed10SFrederic Weisbecker struct tracepoint_path *path = NULL; 157f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 158f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 159f6bdafefSJason Baron char id_buf[4]; 160725b1368SEric Dumazet int fd; 161f6bdafefSJason Baron u64 id; 162f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 163725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 164f6bdafefSJason Baron 165*549104f2SClark Williams if (debugfs_valid_mountpoint(debugfs_path)) 1661ef2ed10SFrederic Weisbecker return NULL; 167f6bdafefSJason Baron 1685beeded1SJason Baron sys_dir = opendir(debugfs_path); 169f6bdafefSJason Baron if (!sys_dir) 170725b1368SEric Dumazet return NULL; 171f6bdafefSJason Baron 1726b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 173725b1368SEric Dumazet 174725b1368SEric Dumazet snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path, 175725b1368SEric Dumazet sys_dirent.d_name); 176725b1368SEric Dumazet evt_dir = opendir(dir_path); 177725b1368SEric Dumazet if (!evt_dir) 1786b58e7f1SUlrich Drepper continue; 179725b1368SEric Dumazet 1806b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 181725b1368SEric Dumazet 182725b1368SEric Dumazet snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, 183f6bdafefSJason Baron evt_dirent.d_name); 184725b1368SEric Dumazet fd = open(evt_path, O_RDONLY); 185f6bdafefSJason Baron if (fd < 0) 186f6bdafefSJason Baron continue; 187f6bdafefSJason Baron if (read(fd, id_buf, sizeof(id_buf)) < 0) { 188f6bdafefSJason Baron close(fd); 189f6bdafefSJason Baron continue; 190f6bdafefSJason Baron } 191f6bdafefSJason Baron close(fd); 192f6bdafefSJason Baron id = atoll(id_buf); 193f6bdafefSJason Baron if (id == config) { 194f6bdafefSJason Baron closedir(evt_dir); 195f6bdafefSJason Baron closedir(sys_dir); 1961ef2ed10SFrederic Weisbecker path = calloc(1, sizeof(path)); 1971ef2ed10SFrederic Weisbecker path->system = malloc(MAX_EVENT_LENGTH); 1981ef2ed10SFrederic Weisbecker if (!path->system) { 1991ef2ed10SFrederic Weisbecker free(path); 2001ef2ed10SFrederic Weisbecker return NULL; 2011ef2ed10SFrederic Weisbecker } 2021ef2ed10SFrederic Weisbecker path->name = malloc(MAX_EVENT_LENGTH); 2031ef2ed10SFrederic Weisbecker if (!path->name) { 2041ef2ed10SFrederic Weisbecker free(path->system); 2051ef2ed10SFrederic Weisbecker free(path); 2061ef2ed10SFrederic Weisbecker return NULL; 2071ef2ed10SFrederic Weisbecker } 2081ef2ed10SFrederic Weisbecker strncpy(path->system, sys_dirent.d_name, 2091ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2101ef2ed10SFrederic Weisbecker strncpy(path->name, evt_dirent.d_name, 2111ef2ed10SFrederic Weisbecker MAX_EVENT_LENGTH); 2121ef2ed10SFrederic Weisbecker return path; 213f6bdafefSJason Baron } 214f6bdafefSJason Baron } 215f6bdafefSJason Baron closedir(evt_dir); 216f6bdafefSJason Baron } 217f6bdafefSJason Baron 218f6bdafefSJason Baron closedir(sys_dir); 2191ef2ed10SFrederic Weisbecker return NULL; 2201ef2ed10SFrederic Weisbecker } 2211ef2ed10SFrederic Weisbecker 2221ef2ed10SFrederic Weisbecker #define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1) 2231ef2ed10SFrederic Weisbecker static const char *tracepoint_id_to_name(u64 config) 2241ef2ed10SFrederic Weisbecker { 2251ef2ed10SFrederic Weisbecker static char buf[TP_PATH_LEN]; 2261ef2ed10SFrederic Weisbecker struct tracepoint_path *path; 2271ef2ed10SFrederic Weisbecker 2281ef2ed10SFrederic Weisbecker path = tracepoint_id_to_path(config); 2291ef2ed10SFrederic Weisbecker if (path) { 2301ef2ed10SFrederic Weisbecker snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name); 2311ef2ed10SFrederic Weisbecker free(path->name); 2321ef2ed10SFrederic Weisbecker free(path->system); 2331ef2ed10SFrederic Weisbecker free(path); 2341ef2ed10SFrederic Weisbecker } else 2351ef2ed10SFrederic Weisbecker snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown"); 2361ef2ed10SFrederic Weisbecker 2371ef2ed10SFrederic Weisbecker return buf; 238f6bdafefSJason Baron } 239f6bdafefSJason Baron 24006813f6cSJaswinder Singh Rajput static int is_cache_op_valid(u8 cache_type, u8 cache_op) 24106813f6cSJaswinder Singh Rajput { 24206813f6cSJaswinder Singh Rajput if (hw_cache_stat[cache_type] & COP(cache_op)) 24306813f6cSJaswinder Singh Rajput return 1; /* valid */ 24406813f6cSJaswinder Singh Rajput else 24506813f6cSJaswinder Singh Rajput return 0; /* invalid */ 24606813f6cSJaswinder Singh Rajput } 24706813f6cSJaswinder Singh Rajput 248e5c59547SJaswinder Singh Rajput static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result) 249e5c59547SJaswinder Singh Rajput { 250e5c59547SJaswinder Singh Rajput static char name[50]; 251e5c59547SJaswinder Singh Rajput 252e5c59547SJaswinder Singh Rajput if (cache_result) { 253e5c59547SJaswinder Singh Rajput sprintf(name, "%s-%s-%s", hw_cache[cache_type][0], 254e5c59547SJaswinder Singh Rajput hw_cache_op[cache_op][0], 255e5c59547SJaswinder Singh Rajput hw_cache_result[cache_result][0]); 256e5c59547SJaswinder Singh Rajput } else { 257e5c59547SJaswinder Singh Rajput sprintf(name, "%s-%s", hw_cache[cache_type][0], 258e5c59547SJaswinder Singh Rajput hw_cache_op[cache_op][1]); 259e5c59547SJaswinder Singh Rajput } 260e5c59547SJaswinder Singh Rajput 261e5c59547SJaswinder Singh Rajput return name; 262e5c59547SJaswinder Singh Rajput } 263e5c59547SJaswinder Singh Rajput 26483a0944fSIngo Molnar const char *event_name(int counter) 26586470930SIngo Molnar { 2669cffa8d5SPaul Mackerras u64 config = attrs[counter].config; 26786470930SIngo Molnar int type = attrs[counter].type; 2688f18aec5SPeter Zijlstra 2698f18aec5SPeter Zijlstra return __event_name(type, config); 2708f18aec5SPeter Zijlstra } 2718f18aec5SPeter Zijlstra 27283a0944fSIngo Molnar const char *__event_name(int type, u64 config) 2738f18aec5SPeter Zijlstra { 27486470930SIngo Molnar static char buf[32]; 27586470930SIngo Molnar 2768f18aec5SPeter Zijlstra if (type == PERF_TYPE_RAW) { 27786470930SIngo Molnar sprintf(buf, "raw 0x%llx", config); 27886470930SIngo Molnar return buf; 27986470930SIngo Molnar } 28086470930SIngo Molnar 28186470930SIngo Molnar switch (type) { 28286470930SIngo Molnar case PERF_TYPE_HARDWARE: 283f4dbfa8fSPeter Zijlstra if (config < PERF_COUNT_HW_MAX) 28486470930SIngo Molnar return hw_event_names[config]; 28586470930SIngo Molnar return "unknown-hardware"; 28686470930SIngo Molnar 28786470930SIngo Molnar case PERF_TYPE_HW_CACHE: { 2889cffa8d5SPaul Mackerras u8 cache_type, cache_op, cache_result; 28986470930SIngo Molnar 29086470930SIngo Molnar cache_type = (config >> 0) & 0xff; 29186470930SIngo Molnar if (cache_type > PERF_COUNT_HW_CACHE_MAX) 29286470930SIngo Molnar return "unknown-ext-hardware-cache-type"; 29386470930SIngo Molnar 29486470930SIngo Molnar cache_op = (config >> 8) & 0xff; 29586470930SIngo Molnar if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX) 29686470930SIngo Molnar return "unknown-ext-hardware-cache-op"; 29786470930SIngo Molnar 29886470930SIngo Molnar cache_result = (config >> 16) & 0xff; 29986470930SIngo Molnar if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX) 30086470930SIngo Molnar return "unknown-ext-hardware-cache-result"; 30186470930SIngo Molnar 30206813f6cSJaswinder Singh Rajput if (!is_cache_op_valid(cache_type, cache_op)) 30306813f6cSJaswinder Singh Rajput return "invalid-cache"; 30486470930SIngo Molnar 305e5c59547SJaswinder Singh Rajput return event_cache_name(cache_type, cache_op, cache_result); 30686470930SIngo Molnar } 30786470930SIngo Molnar 30886470930SIngo Molnar case PERF_TYPE_SOFTWARE: 309f4dbfa8fSPeter Zijlstra if (config < PERF_COUNT_SW_MAX) 31086470930SIngo Molnar return sw_event_names[config]; 31186470930SIngo Molnar return "unknown-software"; 31286470930SIngo Molnar 313f6bdafefSJason Baron case PERF_TYPE_TRACEPOINT: 314f6bdafefSJason Baron return tracepoint_id_to_name(config); 315f6bdafefSJason Baron 31686470930SIngo Molnar default: 31786470930SIngo Molnar break; 31886470930SIngo Molnar } 31986470930SIngo Molnar 32086470930SIngo Molnar return "unknown"; 32186470930SIngo Molnar } 32286470930SIngo Molnar 32383a0944fSIngo Molnar static int parse_aliases(const char **str, const char *names[][MAX_ALIASES], int size) 32486470930SIngo Molnar { 32586470930SIngo Molnar int i, j; 32661c45981SPaul Mackerras int n, longest = -1; 32786470930SIngo Molnar 32886470930SIngo Molnar for (i = 0; i < size; i++) { 32961c45981SPaul Mackerras for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { 33061c45981SPaul Mackerras n = strlen(names[i][j]); 33161c45981SPaul Mackerras if (n > longest && !strncasecmp(*str, names[i][j], n)) 33261c45981SPaul Mackerras longest = n; 33361c45981SPaul Mackerras } 33461c45981SPaul Mackerras if (longest > 0) { 33561c45981SPaul Mackerras *str += longest; 33686470930SIngo Molnar return i; 33786470930SIngo Molnar } 33886470930SIngo Molnar } 33986470930SIngo Molnar 3408953645fSIngo Molnar return -1; 34186470930SIngo Molnar } 34286470930SIngo Molnar 343bcd3279fSFrederic Weisbecker static enum event_result 344cdd6c482SIngo Molnar parse_generic_hw_event(const char **str, struct perf_event_attr *attr) 34586470930SIngo Molnar { 34661c45981SPaul Mackerras const char *s = *str; 34761c45981SPaul Mackerras int cache_type = -1, cache_op = -1, cache_result = -1; 34886470930SIngo Molnar 34961c45981SPaul Mackerras cache_type = parse_aliases(&s, hw_cache, PERF_COUNT_HW_CACHE_MAX); 35086470930SIngo Molnar /* 35186470930SIngo Molnar * No fallback - if we cannot get a clear cache type 35286470930SIngo Molnar * then bail out: 35386470930SIngo Molnar */ 35486470930SIngo Molnar if (cache_type == -1) 355bcd3279fSFrederic Weisbecker return EVT_FAILED; 35686470930SIngo Molnar 35761c45981SPaul Mackerras while ((cache_op == -1 || cache_result == -1) && *s == '-') { 35861c45981SPaul Mackerras ++s; 35961c45981SPaul Mackerras 36061c45981SPaul Mackerras if (cache_op == -1) { 36161c45981SPaul Mackerras cache_op = parse_aliases(&s, hw_cache_op, 36261c45981SPaul Mackerras PERF_COUNT_HW_CACHE_OP_MAX); 36361c45981SPaul Mackerras if (cache_op >= 0) { 36461c45981SPaul Mackerras if (!is_cache_op_valid(cache_type, cache_op)) 36561c45981SPaul Mackerras return 0; 36661c45981SPaul Mackerras continue; 36761c45981SPaul Mackerras } 36861c45981SPaul Mackerras } 36961c45981SPaul Mackerras 37061c45981SPaul Mackerras if (cache_result == -1) { 37161c45981SPaul Mackerras cache_result = parse_aliases(&s, hw_cache_result, 37261c45981SPaul Mackerras PERF_COUNT_HW_CACHE_RESULT_MAX); 37361c45981SPaul Mackerras if (cache_result >= 0) 37461c45981SPaul Mackerras continue; 37561c45981SPaul Mackerras } 37661c45981SPaul Mackerras 37761c45981SPaul Mackerras /* 37861c45981SPaul Mackerras * Can't parse this as a cache op or result, so back up 37961c45981SPaul Mackerras * to the '-'. 38061c45981SPaul Mackerras */ 38161c45981SPaul Mackerras --s; 38261c45981SPaul Mackerras break; 38361c45981SPaul Mackerras } 38461c45981SPaul Mackerras 38586470930SIngo Molnar /* 38686470930SIngo Molnar * Fall back to reads: 38786470930SIngo Molnar */ 3888953645fSIngo Molnar if (cache_op == -1) 3898953645fSIngo Molnar cache_op = PERF_COUNT_HW_CACHE_OP_READ; 39086470930SIngo Molnar 39186470930SIngo Molnar /* 39286470930SIngo Molnar * Fall back to accesses: 39386470930SIngo Molnar */ 39486470930SIngo Molnar if (cache_result == -1) 39586470930SIngo Molnar cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 39686470930SIngo Molnar 39786470930SIngo Molnar attr->config = cache_type | (cache_op << 8) | (cache_result << 16); 39886470930SIngo Molnar attr->type = PERF_TYPE_HW_CACHE; 39986470930SIngo Molnar 40061c45981SPaul Mackerras *str = s; 401bcd3279fSFrederic Weisbecker return EVT_HANDLED; 40286470930SIngo Molnar } 40386470930SIngo Molnar 404bcd3279fSFrederic Weisbecker static enum event_result 405bcd3279fSFrederic Weisbecker parse_single_tracepoint_event(char *sys_name, 406bcd3279fSFrederic Weisbecker const char *evt_name, 407bcd3279fSFrederic Weisbecker unsigned int evt_length, 408bcd3279fSFrederic Weisbecker char *flags, 409cdd6c482SIngo Molnar struct perf_event_attr *attr, 410bcd3279fSFrederic Weisbecker const char **strp) 411bcd3279fSFrederic Weisbecker { 412bcd3279fSFrederic Weisbecker char evt_path[MAXPATHLEN]; 413bcd3279fSFrederic Weisbecker char id_buf[4]; 414bcd3279fSFrederic Weisbecker u64 id; 415bcd3279fSFrederic Weisbecker int fd; 416bcd3279fSFrederic Weisbecker 417bcd3279fSFrederic Weisbecker if (flags) { 4181281a49bSLi Zefan if (!strncmp(flags, "record", strlen(flags))) { 419bcd3279fSFrederic Weisbecker attr->sample_type |= PERF_SAMPLE_RAW; 4201281a49bSLi Zefan attr->sample_type |= PERF_SAMPLE_TIME; 4211281a49bSLi Zefan attr->sample_type |= PERF_SAMPLE_CPU; 4221281a49bSLi Zefan } 423bcd3279fSFrederic Weisbecker } 424bcd3279fSFrederic Weisbecker 425bcd3279fSFrederic Weisbecker snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path, 426bcd3279fSFrederic Weisbecker sys_name, evt_name); 427bcd3279fSFrederic Weisbecker 428bcd3279fSFrederic Weisbecker fd = open(evt_path, O_RDONLY); 429bcd3279fSFrederic Weisbecker if (fd < 0) 430bcd3279fSFrederic Weisbecker return EVT_FAILED; 431bcd3279fSFrederic Weisbecker 432bcd3279fSFrederic Weisbecker if (read(fd, id_buf, sizeof(id_buf)) < 0) { 433bcd3279fSFrederic Weisbecker close(fd); 434bcd3279fSFrederic Weisbecker return EVT_FAILED; 435bcd3279fSFrederic Weisbecker } 436bcd3279fSFrederic Weisbecker 437bcd3279fSFrederic Weisbecker close(fd); 438bcd3279fSFrederic Weisbecker id = atoll(id_buf); 439bcd3279fSFrederic Weisbecker attr->config = id; 440bcd3279fSFrederic Weisbecker attr->type = PERF_TYPE_TRACEPOINT; 441bcd3279fSFrederic Weisbecker *strp = evt_name + evt_length; 442bcd3279fSFrederic Weisbecker 443bcd3279fSFrederic Weisbecker return EVT_HANDLED; 444bcd3279fSFrederic Weisbecker } 445bcd3279fSFrederic Weisbecker 446bcd3279fSFrederic Weisbecker /* sys + ':' + event + ':' + flags*/ 447bcd3279fSFrederic Weisbecker #define MAX_EVOPT_LEN (MAX_EVENT_LENGTH * 2 + 2 + 128) 448bcd3279fSFrederic Weisbecker static enum event_result 449bcd3279fSFrederic Weisbecker parse_subsystem_tracepoint_event(char *sys_name, char *flags) 450bcd3279fSFrederic Weisbecker { 451bcd3279fSFrederic Weisbecker char evt_path[MAXPATHLEN]; 452bcd3279fSFrederic Weisbecker struct dirent *evt_ent; 453bcd3279fSFrederic Weisbecker DIR *evt_dir; 454bcd3279fSFrederic Weisbecker 455bcd3279fSFrederic Weisbecker snprintf(evt_path, MAXPATHLEN, "%s/%s", debugfs_path, sys_name); 456bcd3279fSFrederic Weisbecker evt_dir = opendir(evt_path); 457bcd3279fSFrederic Weisbecker 458bcd3279fSFrederic Weisbecker if (!evt_dir) { 459bcd3279fSFrederic Weisbecker perror("Can't open event dir"); 460bcd3279fSFrederic Weisbecker return EVT_FAILED; 461bcd3279fSFrederic Weisbecker } 462bcd3279fSFrederic Weisbecker 463bcd3279fSFrederic Weisbecker while ((evt_ent = readdir(evt_dir))) { 464bcd3279fSFrederic Weisbecker char event_opt[MAX_EVOPT_LEN + 1]; 465bcd3279fSFrederic Weisbecker int len; 466bcd3279fSFrederic Weisbecker unsigned int rem = MAX_EVOPT_LEN; 467bcd3279fSFrederic Weisbecker 468bcd3279fSFrederic Weisbecker if (!strcmp(evt_ent->d_name, ".") 469bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "..") 470bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "enable") 471bcd3279fSFrederic Weisbecker || !strcmp(evt_ent->d_name, "filter")) 472bcd3279fSFrederic Weisbecker continue; 473bcd3279fSFrederic Weisbecker 474bcd3279fSFrederic Weisbecker len = snprintf(event_opt, MAX_EVOPT_LEN, "%s:%s", sys_name, 475bcd3279fSFrederic Weisbecker evt_ent->d_name); 476bcd3279fSFrederic Weisbecker if (len < 0) 477bcd3279fSFrederic Weisbecker return EVT_FAILED; 478bcd3279fSFrederic Weisbecker 479bcd3279fSFrederic Weisbecker rem -= len; 480bcd3279fSFrederic Weisbecker if (flags) { 481bcd3279fSFrederic Weisbecker if (rem < strlen(flags) + 1) 482bcd3279fSFrederic Weisbecker return EVT_FAILED; 483bcd3279fSFrederic Weisbecker 484bcd3279fSFrederic Weisbecker strcat(event_opt, ":"); 485bcd3279fSFrederic Weisbecker strcat(event_opt, flags); 486bcd3279fSFrederic Weisbecker } 487bcd3279fSFrederic Weisbecker 488bcd3279fSFrederic Weisbecker if (parse_events(NULL, event_opt, 0)) 489bcd3279fSFrederic Weisbecker return EVT_FAILED; 490bcd3279fSFrederic Weisbecker } 491bcd3279fSFrederic Weisbecker 492bcd3279fSFrederic Weisbecker return EVT_HANDLED_ALL; 493bcd3279fSFrederic Weisbecker } 494bcd3279fSFrederic Weisbecker 495bcd3279fSFrederic Weisbecker 496bcd3279fSFrederic Weisbecker static enum event_result parse_tracepoint_event(const char **strp, 497cdd6c482SIngo Molnar struct perf_event_attr *attr) 498f6bdafefSJason Baron { 499f6bdafefSJason Baron const char *evt_name; 5003a9f131fSFrederic Weisbecker char *flags; 501f6bdafefSJason Baron char sys_name[MAX_EVENT_LENGTH]; 502f6bdafefSJason Baron unsigned int sys_length, evt_length; 503f6bdafefSJason Baron 504*549104f2SClark Williams if (debugfs_valid_mountpoint(debugfs_path)) 505f6bdafefSJason Baron return 0; 506f6bdafefSJason Baron 507f6bdafefSJason Baron evt_name = strchr(*strp, ':'); 508f6bdafefSJason Baron if (!evt_name) 509bcd3279fSFrederic Weisbecker return EVT_FAILED; 510f6bdafefSJason Baron 511f6bdafefSJason Baron sys_length = evt_name - *strp; 512f6bdafefSJason Baron if (sys_length >= MAX_EVENT_LENGTH) 513f6bdafefSJason Baron return 0; 514f6bdafefSJason Baron 515f6bdafefSJason Baron strncpy(sys_name, *strp, sys_length); 516f6bdafefSJason Baron sys_name[sys_length] = '\0'; 517f6bdafefSJason Baron evt_name = evt_name + 1; 5183a9f131fSFrederic Weisbecker 5193a9f131fSFrederic Weisbecker flags = strchr(evt_name, ':'); 5203a9f131fSFrederic Weisbecker if (flags) { 5211fc35b29SIngo Molnar /* split it out: */ 5221fc35b29SIngo Molnar evt_name = strndup(evt_name, flags - evt_name); 5233a9f131fSFrederic Weisbecker flags++; 5243a9f131fSFrederic Weisbecker } 5253a9f131fSFrederic Weisbecker 526f6bdafefSJason Baron evt_length = strlen(evt_name); 527f6bdafefSJason Baron if (evt_length >= MAX_EVENT_LENGTH) 528bcd3279fSFrederic Weisbecker return EVT_FAILED; 529f6bdafefSJason Baron 530bcd3279fSFrederic Weisbecker if (!strcmp(evt_name, "*")) { 531f6bdafefSJason Baron *strp = evt_name + evt_length; 532bcd3279fSFrederic Weisbecker return parse_subsystem_tracepoint_event(sys_name, flags); 533bcd3279fSFrederic Weisbecker } else 534bcd3279fSFrederic Weisbecker return parse_single_tracepoint_event(sys_name, evt_name, 535bcd3279fSFrederic Weisbecker evt_length, flags, 536bcd3279fSFrederic Weisbecker attr, strp); 537f6bdafefSJason Baron } 538f6bdafefSJason Baron 53974d5b588SJaswinder Singh Rajput static int check_events(const char *str, unsigned int i) 54074d5b588SJaswinder Singh Rajput { 54161c45981SPaul Mackerras int n; 54274d5b588SJaswinder Singh Rajput 54361c45981SPaul Mackerras n = strlen(event_symbols[i].symbol); 54461c45981SPaul Mackerras if (!strncmp(str, event_symbols[i].symbol, n)) 54561c45981SPaul Mackerras return n; 54661c45981SPaul Mackerras 54761c45981SPaul Mackerras n = strlen(event_symbols[i].alias); 54861c45981SPaul Mackerras if (n) 54961c45981SPaul Mackerras if (!strncmp(str, event_symbols[i].alias, n)) 55061c45981SPaul Mackerras return n; 55161c45981SPaul Mackerras return 0; 55261c45981SPaul Mackerras } 55361c45981SPaul Mackerras 554bcd3279fSFrederic Weisbecker static enum event_result 555cdd6c482SIngo Molnar parse_symbolic_event(const char **strp, struct perf_event_attr *attr) 55661c45981SPaul Mackerras { 55761c45981SPaul Mackerras const char *str = *strp; 55861c45981SPaul Mackerras unsigned int i; 55961c45981SPaul Mackerras int n; 56061c45981SPaul Mackerras 56161c45981SPaul Mackerras for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { 56261c45981SPaul Mackerras n = check_events(str, i); 56361c45981SPaul Mackerras if (n > 0) { 56461c45981SPaul Mackerras attr->type = event_symbols[i].type; 56561c45981SPaul Mackerras attr->config = event_symbols[i].config; 56661c45981SPaul Mackerras *strp = str + n; 567bcd3279fSFrederic Weisbecker return EVT_HANDLED; 56861c45981SPaul Mackerras } 56961c45981SPaul Mackerras } 570bcd3279fSFrederic Weisbecker return EVT_FAILED; 57161c45981SPaul Mackerras } 57261c45981SPaul Mackerras 573bcd3279fSFrederic Weisbecker static enum event_result 574cdd6c482SIngo Molnar parse_raw_event(const char **strp, struct perf_event_attr *attr) 57561c45981SPaul Mackerras { 57661c45981SPaul Mackerras const char *str = *strp; 57761c45981SPaul Mackerras u64 config; 57861c45981SPaul Mackerras int n; 57961c45981SPaul Mackerras 58061c45981SPaul Mackerras if (*str != 'r') 581bcd3279fSFrederic Weisbecker return EVT_FAILED; 58261c45981SPaul Mackerras n = hex2u64(str + 1, &config); 58361c45981SPaul Mackerras if (n > 0) { 58461c45981SPaul Mackerras *strp = str + n + 1; 58561c45981SPaul Mackerras attr->type = PERF_TYPE_RAW; 58661c45981SPaul Mackerras attr->config = config; 587bcd3279fSFrederic Weisbecker return EVT_HANDLED; 58861c45981SPaul Mackerras } 589bcd3279fSFrederic Weisbecker return EVT_FAILED; 59061c45981SPaul Mackerras } 59161c45981SPaul Mackerras 592bcd3279fSFrederic Weisbecker static enum event_result 593cdd6c482SIngo Molnar parse_numeric_event(const char **strp, struct perf_event_attr *attr) 59461c45981SPaul Mackerras { 59561c45981SPaul Mackerras const char *str = *strp; 59661c45981SPaul Mackerras char *endp; 59761c45981SPaul Mackerras unsigned long type; 59861c45981SPaul Mackerras u64 config; 59961c45981SPaul Mackerras 60061c45981SPaul Mackerras type = strtoul(str, &endp, 0); 60161c45981SPaul Mackerras if (endp > str && type < PERF_TYPE_MAX && *endp == ':') { 60261c45981SPaul Mackerras str = endp + 1; 60361c45981SPaul Mackerras config = strtoul(str, &endp, 0); 60461c45981SPaul Mackerras if (endp > str) { 60561c45981SPaul Mackerras attr->type = type; 60661c45981SPaul Mackerras attr->config = config; 60761c45981SPaul Mackerras *strp = endp; 608bcd3279fSFrederic Weisbecker return EVT_HANDLED; 60961c45981SPaul Mackerras } 61061c45981SPaul Mackerras } 611bcd3279fSFrederic Weisbecker return EVT_FAILED; 61261c45981SPaul Mackerras } 61361c45981SPaul Mackerras 614bcd3279fSFrederic Weisbecker static enum event_result 615cdd6c482SIngo Molnar parse_event_modifier(const char **strp, struct perf_event_attr *attr) 61661c45981SPaul Mackerras { 61761c45981SPaul Mackerras const char *str = *strp; 61861c45981SPaul Mackerras int eu = 1, ek = 1, eh = 1; 61961c45981SPaul Mackerras 62061c45981SPaul Mackerras if (*str++ != ':') 62161c45981SPaul Mackerras return 0; 62261c45981SPaul Mackerras while (*str) { 62361c45981SPaul Mackerras if (*str == 'u') 62461c45981SPaul Mackerras eu = 0; 62561c45981SPaul Mackerras else if (*str == 'k') 62661c45981SPaul Mackerras ek = 0; 62761c45981SPaul Mackerras else if (*str == 'h') 62861c45981SPaul Mackerras eh = 0; 62961c45981SPaul Mackerras else 63061c45981SPaul Mackerras break; 63161c45981SPaul Mackerras ++str; 63261c45981SPaul Mackerras } 63361c45981SPaul Mackerras if (str >= *strp + 2) { 63461c45981SPaul Mackerras *strp = str; 63561c45981SPaul Mackerras attr->exclude_user = eu; 63661c45981SPaul Mackerras attr->exclude_kernel = ek; 63761c45981SPaul Mackerras attr->exclude_hv = eh; 63861c45981SPaul Mackerras return 1; 63961c45981SPaul Mackerras } 64074d5b588SJaswinder Singh Rajput return 0; 64174d5b588SJaswinder Singh Rajput } 64274d5b588SJaswinder Singh Rajput 64386470930SIngo Molnar /* 64486470930SIngo Molnar * Each event can have multiple symbolic names. 64586470930SIngo Molnar * Symbolic names are (almost) exactly matched. 64686470930SIngo Molnar */ 647bcd3279fSFrederic Weisbecker static enum event_result 648cdd6c482SIngo Molnar parse_event_symbols(const char **str, struct perf_event_attr *attr) 64986470930SIngo Molnar { 650bcd3279fSFrederic Weisbecker enum event_result ret; 65186470930SIngo Molnar 652bcd3279fSFrederic Weisbecker ret = parse_tracepoint_event(str, attr); 653bcd3279fSFrederic Weisbecker if (ret != EVT_FAILED) 654bcd3279fSFrederic Weisbecker goto modifier; 655bcd3279fSFrederic Weisbecker 656bcd3279fSFrederic Weisbecker ret = parse_raw_event(str, attr); 657bcd3279fSFrederic Weisbecker if (ret != EVT_FAILED) 658bcd3279fSFrederic Weisbecker goto modifier; 659bcd3279fSFrederic Weisbecker 660bcd3279fSFrederic Weisbecker ret = parse_numeric_event(str, attr); 661bcd3279fSFrederic Weisbecker if (ret != EVT_FAILED) 662bcd3279fSFrederic Weisbecker goto modifier; 663bcd3279fSFrederic Weisbecker 664bcd3279fSFrederic Weisbecker ret = parse_symbolic_event(str, attr); 665bcd3279fSFrederic Weisbecker if (ret != EVT_FAILED) 666bcd3279fSFrederic Weisbecker goto modifier; 667bcd3279fSFrederic Weisbecker 668bcd3279fSFrederic Weisbecker ret = parse_generic_hw_event(str, attr); 669bcd3279fSFrederic Weisbecker if (ret != EVT_FAILED) 670bcd3279fSFrederic Weisbecker goto modifier; 671bcd3279fSFrederic Weisbecker 67285df6f68SMarti Raudsepp fprintf(stderr, "invalid or unsupported event: '%s'\n", *str); 67385df6f68SMarti Raudsepp fprintf(stderr, "Run 'perf list' for a list of valid events\n"); 674bcd3279fSFrederic Weisbecker return EVT_FAILED; 675bcd3279fSFrederic Weisbecker 676bcd3279fSFrederic Weisbecker modifier: 67761c45981SPaul Mackerras parse_event_modifier(str, attr); 67886470930SIngo Molnar 679bcd3279fSFrederic Weisbecker return ret; 68086470930SIngo Molnar } 68186470930SIngo Molnar 6828755a8f2SArjan van de Ven static void store_event_type(const char *orgname) 6838755a8f2SArjan van de Ven { 6848755a8f2SArjan van de Ven char filename[PATH_MAX], *c; 6858755a8f2SArjan van de Ven FILE *file; 6868755a8f2SArjan van de Ven int id; 6878755a8f2SArjan van de Ven 68863c9e01eSAshwin Chaugule sprintf(filename, "%s/", debugfs_path); 68963c9e01eSAshwin Chaugule strncat(filename, orgname, strlen(orgname)); 69063c9e01eSAshwin Chaugule strcat(filename, "/id"); 69163c9e01eSAshwin Chaugule 6928755a8f2SArjan van de Ven c = strchr(filename, ':'); 6938755a8f2SArjan van de Ven if (c) 6948755a8f2SArjan van de Ven *c = '/'; 6958755a8f2SArjan van de Ven 6968755a8f2SArjan van de Ven file = fopen(filename, "r"); 6978755a8f2SArjan van de Ven if (!file) 6988755a8f2SArjan van de Ven return; 6998755a8f2SArjan van de Ven if (fscanf(file, "%i", &id) < 1) 7008755a8f2SArjan van de Ven die("cannot store event ID"); 7018755a8f2SArjan van de Ven fclose(file); 7028755a8f2SArjan van de Ven perf_header__push_event(id, orgname); 7038755a8f2SArjan van de Ven } 7048755a8f2SArjan van de Ven 705f37a291cSIngo Molnar int parse_events(const struct option *opt __used, const char *str, int unset __used) 70686470930SIngo Molnar { 707cdd6c482SIngo Molnar struct perf_event_attr attr; 708bcd3279fSFrederic Weisbecker enum event_result ret; 70986470930SIngo Molnar 7108755a8f2SArjan van de Ven if (strchr(str, ':')) 7118755a8f2SArjan van de Ven store_event_type(str); 7128755a8f2SArjan van de Ven 71361c45981SPaul Mackerras for (;;) { 71486470930SIngo Molnar if (nr_counters == MAX_COUNTERS) 71586470930SIngo Molnar return -1; 71686470930SIngo Molnar 71761c45981SPaul Mackerras memset(&attr, 0, sizeof(attr)); 718bcd3279fSFrederic Weisbecker ret = parse_event_symbols(&str, &attr); 719bcd3279fSFrederic Weisbecker if (ret == EVT_FAILED) 72061c45981SPaul Mackerras return -1; 72161c45981SPaul Mackerras 72261c45981SPaul Mackerras if (!(*str == 0 || *str == ',' || isspace(*str))) 72361c45981SPaul Mackerras return -1; 72486470930SIngo Molnar 725bcd3279fSFrederic Weisbecker if (ret != EVT_HANDLED_ALL) { 72686470930SIngo Molnar attrs[nr_counters] = attr; 72786470930SIngo Molnar nr_counters++; 728bcd3279fSFrederic Weisbecker } 72986470930SIngo Molnar 73061c45981SPaul Mackerras if (*str == 0) 73161c45981SPaul Mackerras break; 73261c45981SPaul Mackerras if (*str == ',') 73361c45981SPaul Mackerras ++str; 73461c45981SPaul Mackerras while (isspace(*str)) 73561c45981SPaul Mackerras ++str; 73686470930SIngo Molnar } 73786470930SIngo Molnar 73886470930SIngo Molnar return 0; 73986470930SIngo Molnar } 74086470930SIngo Molnar 741c171b552SLi Zefan int parse_filter(const struct option *opt __used, const char *str, 742c171b552SLi Zefan int unset __used) 743c171b552SLi Zefan { 744c171b552SLi Zefan int i = nr_counters - 1; 745c171b552SLi Zefan int len = strlen(str); 746c171b552SLi Zefan 747c171b552SLi Zefan if (i < 0 || attrs[i].type != PERF_TYPE_TRACEPOINT) { 748c171b552SLi Zefan fprintf(stderr, 749c171b552SLi Zefan "-F option should follow a -e tracepoint option\n"); 750c171b552SLi Zefan return -1; 751c171b552SLi Zefan } 752c171b552SLi Zefan 753c171b552SLi Zefan filters[i] = malloc(len + 1); 754c171b552SLi Zefan if (!filters[i]) { 755c171b552SLi Zefan fprintf(stderr, "not enough memory to hold filter string\n"); 756c171b552SLi Zefan return -1; 757c171b552SLi Zefan } 758c171b552SLi Zefan strcpy(filters[i], str); 759c171b552SLi Zefan 760c171b552SLi Zefan return 0; 761c171b552SLi Zefan } 762c171b552SLi Zefan 76386470930SIngo Molnar static const char * const event_type_descriptors[] = { 76486470930SIngo Molnar "", 76586470930SIngo Molnar "Hardware event", 76686470930SIngo Molnar "Software event", 76786470930SIngo Molnar "Tracepoint event", 76886470930SIngo Molnar "Hardware cache event", 76986470930SIngo Molnar }; 77086470930SIngo Molnar 77186470930SIngo Molnar /* 772f6bdafefSJason Baron * Print the events from <debugfs_mount_point>/tracing/events 773f6bdafefSJason Baron */ 774f6bdafefSJason Baron 775f6bdafefSJason Baron static void print_tracepoint_events(void) 776f6bdafefSJason Baron { 777f6bdafefSJason Baron DIR *sys_dir, *evt_dir; 778f6bdafefSJason Baron struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 779f6bdafefSJason Baron char evt_path[MAXPATHLEN]; 780725b1368SEric Dumazet char dir_path[MAXPATHLEN]; 781f6bdafefSJason Baron 782*549104f2SClark Williams if (debugfs_valid_mountpoint(debugfs_path)) 783f6bdafefSJason Baron return; 784f6bdafefSJason Baron 7855beeded1SJason Baron sys_dir = opendir(debugfs_path); 786f6bdafefSJason Baron if (!sys_dir) 787725b1368SEric Dumazet return; 788f6bdafefSJason Baron 7896b58e7f1SUlrich Drepper for_each_subsystem(sys_dir, sys_dirent, sys_next) { 790725b1368SEric Dumazet 791725b1368SEric Dumazet snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path, 792725b1368SEric Dumazet sys_dirent.d_name); 793725b1368SEric Dumazet evt_dir = opendir(dir_path); 794725b1368SEric Dumazet if (!evt_dir) 7956b58e7f1SUlrich Drepper continue; 796725b1368SEric Dumazet 7976b58e7f1SUlrich Drepper for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { 798f6bdafefSJason Baron snprintf(evt_path, MAXPATHLEN, "%s:%s", 799f6bdafefSJason Baron sys_dirent.d_name, evt_dirent.d_name); 800689d3018SMarti Raudsepp printf(" %-42s [%s]\n", evt_path, 801f6bdafefSJason Baron event_type_descriptors[PERF_TYPE_TRACEPOINT+1]); 802f6bdafefSJason Baron } 803f6bdafefSJason Baron closedir(evt_dir); 804f6bdafefSJason Baron } 805f6bdafefSJason Baron closedir(sys_dir); 806f6bdafefSJason Baron } 807f6bdafefSJason Baron 808f6bdafefSJason Baron /* 80986470930SIngo Molnar * Print the help text for the event symbols: 81086470930SIngo Molnar */ 81186470930SIngo Molnar void print_events(void) 81286470930SIngo Molnar { 81386470930SIngo Molnar struct event_symbol *syms = event_symbols; 81473c24cb8SJaswinder Singh Rajput unsigned int i, type, op, prev_type = -1; 81574d5b588SJaswinder Singh Rajput char name[40]; 81686470930SIngo Molnar 817689d3018SMarti Raudsepp printf("\n"); 818689d3018SMarti Raudsepp printf("List of pre-defined events (to be used in -e):\n"); 81986470930SIngo Molnar 82086470930SIngo Molnar for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 82186470930SIngo Molnar type = syms->type + 1; 82223cdb5d5SRoel Kluin if (type >= ARRAY_SIZE(event_type_descriptors)) 82386470930SIngo Molnar type = 0; 82486470930SIngo Molnar 82586470930SIngo Molnar if (type != prev_type) 826689d3018SMarti Raudsepp printf("\n"); 82786470930SIngo Molnar 82874d5b588SJaswinder Singh Rajput if (strlen(syms->alias)) 82974d5b588SJaswinder Singh Rajput sprintf(name, "%s OR %s", syms->symbol, syms->alias); 83074d5b588SJaswinder Singh Rajput else 83174d5b588SJaswinder Singh Rajput strcpy(name, syms->symbol); 832689d3018SMarti Raudsepp printf(" %-42s [%s]\n", name, 83386470930SIngo Molnar event_type_descriptors[type]); 83486470930SIngo Molnar 83586470930SIngo Molnar prev_type = type; 83686470930SIngo Molnar } 83786470930SIngo Molnar 838689d3018SMarti Raudsepp printf("\n"); 83973c24cb8SJaswinder Singh Rajput for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 84073c24cb8SJaswinder Singh Rajput for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 84173c24cb8SJaswinder Singh Rajput /* skip invalid cache type */ 84273c24cb8SJaswinder Singh Rajput if (!is_cache_op_valid(type, op)) 84373c24cb8SJaswinder Singh Rajput continue; 84473c24cb8SJaswinder Singh Rajput 84573c24cb8SJaswinder Singh Rajput for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 846689d3018SMarti Raudsepp printf(" %-42s [%s]\n", 84773c24cb8SJaswinder Singh Rajput event_cache_name(type, op, i), 84873c24cb8SJaswinder Singh Rajput event_type_descriptors[4]); 84973c24cb8SJaswinder Singh Rajput } 85073c24cb8SJaswinder Singh Rajput } 85173c24cb8SJaswinder Singh Rajput } 85273c24cb8SJaswinder Singh Rajput 853689d3018SMarti Raudsepp printf("\n"); 854689d3018SMarti Raudsepp printf(" %-42s [raw hardware event descriptor]\n", 85586470930SIngo Molnar "rNNN"); 856689d3018SMarti Raudsepp printf("\n"); 85786470930SIngo Molnar 858f6bdafefSJason Baron print_tracepoint_events(); 859f6bdafefSJason Baron 86086470930SIngo Molnar exit(129); 86186470930SIngo Molnar } 862