1 2 #include "../perf.h" 3 #include "util.h" 4 #include "parse-options.h" 5 #include "parse-events.h" 6 #include "exec_cmd.h" 7 #include "string.h" 8 9 extern char *strcasestr(const char *haystack, const char *needle); 10 11 int nr_counters; 12 13 struct perf_counter_attr attrs[MAX_COUNTERS]; 14 15 struct event_symbol { 16 u8 type; 17 u64 config; 18 char *symbol; 19 char *alias; 20 }; 21 22 #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x 23 #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 24 25 static struct event_symbol event_symbols[] = { 26 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, 27 { CHW(INSTRUCTIONS), "instructions", "" }, 28 { CHW(CACHE_REFERENCES), "cache-references", "" }, 29 { CHW(CACHE_MISSES), "cache-misses", "" }, 30 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, 31 { CHW(BRANCH_MISSES), "branch-misses", "" }, 32 { CHW(BUS_CYCLES), "bus-cycles", "" }, 33 34 { CSW(CPU_CLOCK), "cpu-clock", "" }, 35 { CSW(TASK_CLOCK), "task-clock", "" }, 36 { CSW(PAGE_FAULTS), "page-faults", "" }, 37 { CSW(PAGE_FAULTS), "faults", "" }, 38 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, 39 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, 40 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, 41 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 42 }; 43 44 #define __PERF_COUNTER_FIELD(config, name) \ 45 ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT) 46 47 #define PERF_COUNTER_RAW(config) __PERF_COUNTER_FIELD(config, RAW) 48 #define PERF_COUNTER_CONFIG(config) __PERF_COUNTER_FIELD(config, CONFIG) 49 #define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE) 50 #define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT) 51 52 static char *hw_event_names[] = { 53 "cycles", 54 "instructions", 55 "cache-references", 56 "cache-misses", 57 "branches", 58 "branch-misses", 59 "bus-cycles", 60 }; 61 62 static char *sw_event_names[] = { 63 "cpu-clock-msecs", 64 "task-clock-msecs", 65 "page-faults", 66 "context-switches", 67 "CPU-migrations", 68 "minor-faults", 69 "major-faults", 70 }; 71 72 #define MAX_ALIASES 8 73 74 static char *hw_cache [][MAX_ALIASES] = { 75 { "L1-data" , "l1-d", "l1d" }, 76 { "L1-instruction" , "l1-i", "l1i" }, 77 { "L2" , "l2" }, 78 { "Data-TLB" , "dtlb", "d-tlb" }, 79 { "Instruction-TLB" , "itlb", "i-tlb" }, 80 { "Branch" , "bpu" , "btb", "bpc" }, 81 }; 82 83 static char *hw_cache_op [][MAX_ALIASES] = { 84 { "Load" , "read" }, 85 { "Store" , "write" }, 86 { "Prefetch" , "speculative-read", "speculative-load" }, 87 }; 88 89 static char *hw_cache_result [][MAX_ALIASES] = { 90 { "Reference" , "ops", "access" }, 91 { "Miss" }, 92 }; 93 94 char *event_name(int counter) 95 { 96 u64 config = attrs[counter].config; 97 int type = attrs[counter].type; 98 static char buf[32]; 99 100 if (attrs[counter].type == PERF_TYPE_RAW) { 101 sprintf(buf, "raw 0x%llx", config); 102 return buf; 103 } 104 105 switch (type) { 106 case PERF_TYPE_HARDWARE: 107 if (config < PERF_COUNT_HW_MAX) 108 return hw_event_names[config]; 109 return "unknown-hardware"; 110 111 case PERF_TYPE_HW_CACHE: { 112 u8 cache_type, cache_op, cache_result; 113 static char name[100]; 114 115 cache_type = (config >> 0) & 0xff; 116 if (cache_type > PERF_COUNT_HW_CACHE_MAX) 117 return "unknown-ext-hardware-cache-type"; 118 119 cache_op = (config >> 8) & 0xff; 120 if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX) 121 return "unknown-ext-hardware-cache-op"; 122 123 cache_result = (config >> 16) & 0xff; 124 if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX) 125 return "unknown-ext-hardware-cache-result"; 126 127 sprintf(name, "%s-Cache-%s-%ses", 128 hw_cache[cache_type][0], 129 hw_cache_op[cache_op][0], 130 hw_cache_result[cache_result][0]); 131 132 return name; 133 } 134 135 case PERF_TYPE_SOFTWARE: 136 if (config < PERF_COUNT_SW_MAX) 137 return sw_event_names[config]; 138 return "unknown-software"; 139 140 default: 141 break; 142 } 143 144 return "unknown"; 145 } 146 147 static int parse_aliases(const char *str, char *names[][MAX_ALIASES], int size) 148 { 149 int i, j; 150 151 for (i = 0; i < size; i++) { 152 for (j = 0; j < MAX_ALIASES; j++) { 153 if (!names[i][j]) 154 break; 155 if (strcasestr(str, names[i][j])) 156 return i; 157 } 158 } 159 160 return -1; 161 } 162 163 static int parse_generic_hw_symbols(const char *str, struct perf_counter_attr *attr) 164 { 165 int cache_type = -1, cache_op = 0, cache_result = 0; 166 167 cache_type = parse_aliases(str, hw_cache, PERF_COUNT_HW_CACHE_MAX); 168 /* 169 * No fallback - if we cannot get a clear cache type 170 * then bail out: 171 */ 172 if (cache_type == -1) 173 return -EINVAL; 174 175 cache_op = parse_aliases(str, hw_cache_op, PERF_COUNT_HW_CACHE_OP_MAX); 176 /* 177 * Fall back to reads: 178 */ 179 if (cache_op == -1) 180 cache_op = PERF_COUNT_HW_CACHE_OP_READ; 181 182 cache_result = parse_aliases(str, hw_cache_result, 183 PERF_COUNT_HW_CACHE_RESULT_MAX); 184 /* 185 * Fall back to accesses: 186 */ 187 if (cache_result == -1) 188 cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; 189 190 attr->config = cache_type | (cache_op << 8) | (cache_result << 16); 191 attr->type = PERF_TYPE_HW_CACHE; 192 193 return 0; 194 } 195 196 static int check_events(const char *str, unsigned int i) 197 { 198 if (!strncmp(str, event_symbols[i].symbol, 199 strlen(event_symbols[i].symbol))) 200 return 1; 201 202 if (strlen(event_symbols[i].alias)) 203 if (!strncmp(str, event_symbols[i].alias, 204 strlen(event_symbols[i].alias))) 205 return 1; 206 return 0; 207 } 208 209 /* 210 * Each event can have multiple symbolic names. 211 * Symbolic names are (almost) exactly matched. 212 */ 213 static int parse_event_symbols(const char *str, struct perf_counter_attr *attr) 214 { 215 u64 config, id; 216 int type; 217 unsigned int i; 218 const char *sep, *pstr; 219 220 if (str[0] == 'r' && hex2u64(str + 1, &config) > 0) { 221 attr->type = PERF_TYPE_RAW; 222 attr->config = config; 223 224 return 0; 225 } 226 227 pstr = str; 228 sep = strchr(pstr, ':'); 229 if (sep) { 230 type = atoi(pstr); 231 pstr = sep + 1; 232 id = atoi(pstr); 233 sep = strchr(pstr, ':'); 234 if (sep) { 235 pstr = sep + 1; 236 if (strchr(pstr, 'k')) 237 attr->exclude_user = 1; 238 if (strchr(pstr, 'u')) 239 attr->exclude_kernel = 1; 240 } 241 attr->type = type; 242 attr->config = id; 243 244 return 0; 245 } 246 247 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { 248 if (check_events(str, i)) { 249 attr->type = event_symbols[i].type; 250 attr->config = event_symbols[i].config; 251 252 return 0; 253 } 254 } 255 256 return parse_generic_hw_symbols(str, attr); 257 } 258 259 int parse_events(const struct option *opt, const char *str, int unset) 260 { 261 struct perf_counter_attr attr; 262 int ret; 263 264 memset(&attr, 0, sizeof(attr)); 265 again: 266 if (nr_counters == MAX_COUNTERS) 267 return -1; 268 269 ret = parse_event_symbols(str, &attr); 270 if (ret < 0) 271 return ret; 272 273 attrs[nr_counters] = attr; 274 nr_counters++; 275 276 str = strstr(str, ","); 277 if (str) { 278 str++; 279 goto again; 280 } 281 282 return 0; 283 } 284 285 static const char * const event_type_descriptors[] = { 286 "", 287 "Hardware event", 288 "Software event", 289 "Tracepoint event", 290 "Hardware cache event", 291 }; 292 293 /* 294 * Print the help text for the event symbols: 295 */ 296 void print_events(void) 297 { 298 struct event_symbol *syms = event_symbols; 299 unsigned int i, type, prev_type = -1; 300 char name[40]; 301 302 fprintf(stderr, "\n"); 303 fprintf(stderr, "List of pre-defined events (to be used in -e):\n"); 304 305 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 306 type = syms->type + 1; 307 if (type > ARRAY_SIZE(event_type_descriptors)) 308 type = 0; 309 310 if (type != prev_type) 311 fprintf(stderr, "\n"); 312 313 if (strlen(syms->alias)) 314 sprintf(name, "%s OR %s", syms->symbol, syms->alias); 315 else 316 strcpy(name, syms->symbol); 317 fprintf(stderr, " %-40s [%s]\n", name, 318 event_type_descriptors[type]); 319 320 prev_type = type; 321 } 322 323 fprintf(stderr, "\n"); 324 fprintf(stderr, " %-40s [raw hardware event descriptor]\n", 325 "rNNN"); 326 fprintf(stderr, "\n"); 327 328 exit(129); 329 } 330