aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c404
1 files changed, 284 insertions, 120 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 044178408783..8cfb48cbbea0 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,23 +1,28 @@
1 1
2#include "../perf.h"
3#include "util.h" 2#include "util.h"
3#include "../perf.h"
4#include "parse-options.h" 4#include "parse-options.h"
5#include "parse-events.h" 5#include "parse-events.h"
6#include "exec_cmd.h" 6#include "exec_cmd.h"
7#include "string.h" 7#include "string.h"
8#include "cache.h" 8#include "cache.h"
9 9#include "header.h"
10extern char *strcasestr(const char *haystack, const char *needle);
11 10
12int nr_counters; 11int nr_counters;
13 12
14struct perf_counter_attr attrs[MAX_COUNTERS]; 13struct perf_event_attr attrs[MAX_COUNTERS];
15 14
16struct event_symbol { 15struct event_symbol {
17 u8 type; 16 u8 type;
18 u64 config; 17 u64 config;
19 char *symbol; 18 const char *symbol;
20 char *alias; 19 const char *alias;
20};
21
22enum event_result {
23 EVT_FAILED,
24 EVT_HANDLED,
25 EVT_HANDLED_ALL
21}; 26};
22 27
23char debugfs_path[MAXPATHLEN]; 28char debugfs_path[MAXPATHLEN];
@@ -43,15 +48,15 @@ static struct event_symbol event_symbols[] = {
43 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 48 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" },
44}; 49};
45 50
46#define __PERF_COUNTER_FIELD(config, name) \ 51#define __PERF_EVENT_FIELD(config, name) \
47 ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT) 52 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
48 53
49#define PERF_COUNTER_RAW(config) __PERF_COUNTER_FIELD(config, RAW) 54#define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW)
50#define PERF_COUNTER_CONFIG(config) __PERF_COUNTER_FIELD(config, CONFIG) 55#define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG)
51#define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE) 56#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE)
52#define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT) 57#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT)
53 58
54static char *hw_event_names[] = { 59static const char *hw_event_names[] = {
55 "cycles", 60 "cycles",
56 "instructions", 61 "instructions",
57 "cache-references", 62 "cache-references",
@@ -61,7 +66,7 @@ static char *hw_event_names[] = {
61 "bus-cycles", 66 "bus-cycles",
62}; 67};
63 68
64static char *sw_event_names[] = { 69static const char *sw_event_names[] = {
65 "cpu-clock-msecs", 70 "cpu-clock-msecs",
66 "task-clock-msecs", 71 "task-clock-msecs",
67 "page-faults", 72 "page-faults",
@@ -73,7 +78,7 @@ static char *sw_event_names[] = {
73 78
74#define MAX_ALIASES 8 79#define MAX_ALIASES 8
75 80
76static char *hw_cache[][MAX_ALIASES] = { 81static const char *hw_cache[][MAX_ALIASES] = {
77 { "L1-dcache", "l1-d", "l1d", "L1-data", }, 82 { "L1-dcache", "l1-d", "l1d", "L1-data", },
78 { "L1-icache", "l1-i", "l1i", "L1-instruction", }, 83 { "L1-icache", "l1-i", "l1i", "L1-instruction", },
79 { "LLC", "L2" }, 84 { "LLC", "L2" },
@@ -82,13 +87,13 @@ static char *hw_cache[][MAX_ALIASES] = {
82 { "branch", "branches", "bpu", "btb", "bpc", }, 87 { "branch", "branches", "bpu", "btb", "bpc", },
83}; 88};
84 89
85static char *hw_cache_op[][MAX_ALIASES] = { 90static const char *hw_cache_op[][MAX_ALIASES] = {
86 { "load", "loads", "read", }, 91 { "load", "loads", "read", },
87 { "store", "stores", "write", }, 92 { "store", "stores", "write", },
88 { "prefetch", "prefetches", "speculative-read", "speculative-load", }, 93 { "prefetch", "prefetches", "speculative-read", "speculative-load", },
89}; 94};
90 95
91static char *hw_cache_result[][MAX_ALIASES] = { 96static const char *hw_cache_result[][MAX_ALIASES] = {
92 { "refs", "Reference", "ops", "access", }, 97 { "refs", "Reference", "ops", "access", },
93 { "misses", "miss", }, 98 { "misses", "miss", },
94}; 99};
@@ -113,11 +118,9 @@ static unsigned long hw_cache_stat[C(MAX)] = {
113 [C(BPU)] = (CACHE_READ), 118 [C(BPU)] = (CACHE_READ),
114}; 119};
115 120
116#define for_each_subsystem(sys_dir, sys_dirent, sys_next, file, st) \ 121#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \
117 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 122 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \
118 if (snprintf(file, MAXPATHLEN, "%s/%s", debugfs_path, \ 123 if (sys_dirent.d_type == DT_DIR && \
119 sys_dirent.d_name) && \
120 (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \
121 (strcmp(sys_dirent.d_name, ".")) && \ 124 (strcmp(sys_dirent.d_name, ".")) && \
122 (strcmp(sys_dirent.d_name, ".."))) 125 (strcmp(sys_dirent.d_name, "..")))
123 126
@@ -136,16 +139,14 @@ static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
136 return 0; 139 return 0;
137} 140}
138 141
139#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, file, st) \ 142#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \
140 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ 143 while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \
141 if (snprintf(file, MAXPATHLEN, "%s/%s/%s", debugfs_path, \ 144 if (evt_dirent.d_type == DT_DIR && \
142 sys_dirent.d_name, evt_dirent.d_name) && \
143 (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \
144 (strcmp(evt_dirent.d_name, ".")) && \ 145 (strcmp(evt_dirent.d_name, ".")) && \
145 (strcmp(evt_dirent.d_name, "..")) && \ 146 (strcmp(evt_dirent.d_name, "..")) && \
146 (!tp_event_has_id(&sys_dirent, &evt_dirent))) 147 (!tp_event_has_id(&sys_dirent, &evt_dirent)))
147 148
148#define MAX_EVENT_LENGTH 30 149#define MAX_EVENT_LENGTH 512
149 150
150int valid_debugfs_mount(const char *debugfs) 151int valid_debugfs_mount(const char *debugfs)
151{ 152{
@@ -158,32 +159,35 @@ int valid_debugfs_mount(const char *debugfs)
158 return 0; 159 return 0;
159} 160}
160 161
161static char *tracepoint_id_to_name(u64 config) 162struct tracepoint_path *tracepoint_id_to_path(u64 config)
162{ 163{
163 static char tracepoint_name[2 * MAX_EVENT_LENGTH]; 164 struct tracepoint_path *path = NULL;
164 DIR *sys_dir, *evt_dir; 165 DIR *sys_dir, *evt_dir;
165 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 166 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
166 struct stat st;
167 char id_buf[4]; 167 char id_buf[4];
168 int fd; 168 int fd;
169 u64 id; 169 u64 id;
170 char evt_path[MAXPATHLEN]; 170 char evt_path[MAXPATHLEN];
171 char dir_path[MAXPATHLEN];
171 172
172 if (valid_debugfs_mount(debugfs_path)) 173 if (valid_debugfs_mount(debugfs_path))
173 return "unkown"; 174 return NULL;
174 175
175 sys_dir = opendir(debugfs_path); 176 sys_dir = opendir(debugfs_path);
176 if (!sys_dir) 177 if (!sys_dir)
177 goto cleanup; 178 return NULL;
179
180 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
178 181
179 for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) { 182 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
180 evt_dir = opendir(evt_path); 183 sys_dirent.d_name);
184 evt_dir = opendir(dir_path);
181 if (!evt_dir) 185 if (!evt_dir)
182 goto cleanup; 186 continue;
183 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, 187
184 evt_path, st) { 188 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
185 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", 189
186 debugfs_path, sys_dirent.d_name, 190 snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
187 evt_dirent.d_name); 191 evt_dirent.d_name);
188 fd = open(evt_path, O_RDONLY); 192 fd = open(evt_path, O_RDONLY);
189 if (fd < 0) 193 if (fd < 0)
@@ -197,18 +201,48 @@ static char *tracepoint_id_to_name(u64 config)
197 if (id == config) { 201 if (id == config) {
198 closedir(evt_dir); 202 closedir(evt_dir);
199 closedir(sys_dir); 203 closedir(sys_dir);
200 snprintf(tracepoint_name, 2 * MAX_EVENT_LENGTH, 204 path = calloc(1, sizeof(path));
201 "%s:%s", sys_dirent.d_name, 205 path->system = malloc(MAX_EVENT_LENGTH);
202 evt_dirent.d_name); 206 if (!path->system) {
203 return tracepoint_name; 207 free(path);
208 return NULL;
209 }
210 path->name = malloc(MAX_EVENT_LENGTH);
211 if (!path->name) {
212 free(path->system);
213 free(path);
214 return NULL;
215 }
216 strncpy(path->system, sys_dirent.d_name,
217 MAX_EVENT_LENGTH);
218 strncpy(path->name, evt_dirent.d_name,
219 MAX_EVENT_LENGTH);
220 return path;
204 } 221 }
205 } 222 }
206 closedir(evt_dir); 223 closedir(evt_dir);
207 } 224 }
208 225
209cleanup:
210 closedir(sys_dir); 226 closedir(sys_dir);
211 return "unkown"; 227 return NULL;
228}
229
230#define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1)
231static const char *tracepoint_id_to_name(u64 config)
232{
233 static char buf[TP_PATH_LEN];
234 struct tracepoint_path *path;
235
236 path = tracepoint_id_to_path(config);
237 if (path) {
238 snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name);
239 free(path->name);
240 free(path->system);
241 free(path);
242 } else
243 snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown");
244
245 return buf;
212} 246}
213 247
214static int is_cache_op_valid(u8 cache_type, u8 cache_op) 248static int is_cache_op_valid(u8 cache_type, u8 cache_op)
@@ -235,7 +269,7 @@ static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
235 return name; 269 return name;
236} 270}
237 271
238char *event_name(int counter) 272const char *event_name(int counter)
239{ 273{
240 u64 config = attrs[counter].config; 274 u64 config = attrs[counter].config;
241 int type = attrs[counter].type; 275 int type = attrs[counter].type;
@@ -243,7 +277,7 @@ char *event_name(int counter)
243 return __event_name(type, config); 277 return __event_name(type, config);
244} 278}
245 279
246char *__event_name(int type, u64 config) 280const char *__event_name(int type, u64 config)
247{ 281{
248 static char buf[32]; 282 static char buf[32];
249 283
@@ -294,7 +328,7 @@ char *__event_name(int type, u64 config)
294 return "unknown"; 328 return "unknown";
295} 329}
296 330
297static int parse_aliases(const char **str, char *names[][MAX_ALIASES], int size) 331static int parse_aliases(const char **str, const char *names[][MAX_ALIASES], int size)
298{ 332{
299 int i, j; 333 int i, j;
300 int n, longest = -1; 334 int n, longest = -1;
@@ -314,8 +348,8 @@ static int parse_aliases(const char **str, char *names[][MAX_ALIASES], int size)
314 return -1; 348 return -1;
315} 349}
316 350
317static int 351static enum event_result
318parse_generic_hw_event(const char **str, struct perf_counter_attr *attr) 352parse_generic_hw_event(const char **str, struct perf_event_attr *attr)
319{ 353{
320 const char *s = *str; 354 const char *s = *str;
321 int cache_type = -1, cache_op = -1, cache_result = -1; 355 int cache_type = -1, cache_op = -1, cache_result = -1;
@@ -326,7 +360,7 @@ parse_generic_hw_event(const char **str, struct perf_counter_attr *attr)
326 * then bail out: 360 * then bail out:
327 */ 361 */
328 if (cache_type == -1) 362 if (cache_type == -1)
329 return 0; 363 return EVT_FAILED;
330 364
331 while ((cache_op == -1 || cache_result == -1) && *s == '-') { 365 while ((cache_op == -1 || cache_result == -1) && *s == '-') {
332 ++s; 366 ++s;
@@ -372,27 +406,115 @@ parse_generic_hw_event(const char **str, struct perf_counter_attr *attr)
372 attr->type = PERF_TYPE_HW_CACHE; 406 attr->type = PERF_TYPE_HW_CACHE;
373 407
374 *str = s; 408 *str = s;
375 return 1; 409 return EVT_HANDLED;
410}
411
412static enum event_result
413parse_single_tracepoint_event(char *sys_name,
414 const char *evt_name,
415 unsigned int evt_length,
416 char *flags,
417 struct perf_event_attr *attr,
418 const char **strp)
419{
420 char evt_path[MAXPATHLEN];
421 char id_buf[4];
422 u64 id;
423 int fd;
424
425 if (flags) {
426 if (!strncmp(flags, "record", strlen(flags))) {
427 attr->sample_type |= PERF_SAMPLE_RAW;
428 attr->sample_type |= PERF_SAMPLE_TIME;
429 attr->sample_type |= PERF_SAMPLE_CPU;
430 }
431 }
432
433 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
434 sys_name, evt_name);
435
436 fd = open(evt_path, O_RDONLY);
437 if (fd < 0)
438 return EVT_FAILED;
439
440 if (read(fd, id_buf, sizeof(id_buf)) < 0) {
441 close(fd);
442 return EVT_FAILED;
443 }
444
445 close(fd);
446 id = atoll(id_buf);
447 attr->config = id;
448 attr->type = PERF_TYPE_TRACEPOINT;
449 *strp = evt_name + evt_length;
450
451 return EVT_HANDLED;
376} 452}
377 453
378static int parse_tracepoint_event(const char **strp, 454/* sys + ':' + event + ':' + flags*/
379 struct perf_counter_attr *attr) 455#define MAX_EVOPT_LEN (MAX_EVENT_LENGTH * 2 + 2 + 128)
456static enum event_result
457parse_subsystem_tracepoint_event(char *sys_name, char *flags)
458{
459 char evt_path[MAXPATHLEN];
460 struct dirent *evt_ent;
461 DIR *evt_dir;
462
463 snprintf(evt_path, MAXPATHLEN, "%s/%s", debugfs_path, sys_name);
464 evt_dir = opendir(evt_path);
465
466 if (!evt_dir) {
467 perror("Can't open event dir");
468 return EVT_FAILED;
469 }
470
471 while ((evt_ent = readdir(evt_dir))) {
472 char event_opt[MAX_EVOPT_LEN + 1];
473 int len;
474 unsigned int rem = MAX_EVOPT_LEN;
475
476 if (!strcmp(evt_ent->d_name, ".")
477 || !strcmp(evt_ent->d_name, "..")
478 || !strcmp(evt_ent->d_name, "enable")
479 || !strcmp(evt_ent->d_name, "filter"))
480 continue;
481
482 len = snprintf(event_opt, MAX_EVOPT_LEN, "%s:%s", sys_name,
483 evt_ent->d_name);
484 if (len < 0)
485 return EVT_FAILED;
486
487 rem -= len;
488 if (flags) {
489 if (rem < strlen(flags) + 1)
490 return EVT_FAILED;
491
492 strcat(event_opt, ":");
493 strcat(event_opt, flags);
494 }
495
496 if (parse_events(NULL, event_opt, 0))
497 return EVT_FAILED;
498 }
499
500 return EVT_HANDLED_ALL;
501}
502
503
504static enum event_result parse_tracepoint_event(const char **strp,
505 struct perf_event_attr *attr)
380{ 506{
381 const char *evt_name; 507 const char *evt_name;
382 char *flags; 508 char *flags;
383 char sys_name[MAX_EVENT_LENGTH]; 509 char sys_name[MAX_EVENT_LENGTH];
384 char id_buf[4];
385 int fd;
386 unsigned int sys_length, evt_length; 510 unsigned int sys_length, evt_length;
387 u64 id;
388 char evt_path[MAXPATHLEN];
389 511
390 if (valid_debugfs_mount(debugfs_path)) 512 if (valid_debugfs_mount(debugfs_path))
391 return 0; 513 return 0;
392 514
393 evt_name = strchr(*strp, ':'); 515 evt_name = strchr(*strp, ':');
394 if (!evt_name) 516 if (!evt_name)
395 return 0; 517 return EVT_FAILED;
396 518
397 sys_length = evt_name - *strp; 519 sys_length = evt_name - *strp;
398 if (sys_length >= MAX_EVENT_LENGTH) 520 if (sys_length >= MAX_EVENT_LENGTH)
@@ -404,32 +526,22 @@ static int parse_tracepoint_event(const char **strp,
404 526
405 flags = strchr(evt_name, ':'); 527 flags = strchr(evt_name, ':');
406 if (flags) { 528 if (flags) {
407 *flags = '\0'; 529 /* split it out: */
530 evt_name = strndup(evt_name, flags - evt_name);
408 flags++; 531 flags++;
409 if (!strncmp(flags, "record", strlen(flags)))
410 attr->sample_type |= PERF_SAMPLE_RAW;
411 } 532 }
412 533
413 evt_length = strlen(evt_name); 534 evt_length = strlen(evt_name);
414 if (evt_length >= MAX_EVENT_LENGTH) 535 if (evt_length >= MAX_EVENT_LENGTH)
415 return 0; 536 return EVT_FAILED;
416 537
417 snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path, 538 if (!strcmp(evt_name, "*")) {
418 sys_name, evt_name); 539 *strp = evt_name + evt_length;
419 fd = open(evt_path, O_RDONLY); 540 return parse_subsystem_tracepoint_event(sys_name, flags);
420 if (fd < 0) 541 } else
421 return 0; 542 return parse_single_tracepoint_event(sys_name, evt_name,
422 543 evt_length, flags,
423 if (read(fd, id_buf, sizeof(id_buf)) < 0) { 544 attr, strp);
424 close(fd);
425 return 0;
426 }
427 close(fd);
428 id = atoll(id_buf);
429 attr->config = id;
430 attr->type = PERF_TYPE_TRACEPOINT;
431 *strp = evt_name + evt_length;
432 return 1;
433} 545}
434 546
435static int check_events(const char *str, unsigned int i) 547static int check_events(const char *str, unsigned int i)
@@ -447,8 +559,8 @@ static int check_events(const char *str, unsigned int i)
447 return 0; 559 return 0;
448} 560}
449 561
450static int 562static enum event_result
451parse_symbolic_event(const char **strp, struct perf_counter_attr *attr) 563parse_symbolic_event(const char **strp, struct perf_event_attr *attr)
452{ 564{
453 const char *str = *strp; 565 const char *str = *strp;
454 unsigned int i; 566 unsigned int i;
@@ -460,32 +572,33 @@ parse_symbolic_event(const char **strp, struct perf_counter_attr *attr)
460 attr->type = event_symbols[i].type; 572 attr->type = event_symbols[i].type;
461 attr->config = event_symbols[i].config; 573 attr->config = event_symbols[i].config;
462 *strp = str + n; 574 *strp = str + n;
463 return 1; 575 return EVT_HANDLED;
464 } 576 }
465 } 577 }
466 return 0; 578 return EVT_FAILED;
467} 579}
468 580
469static int parse_raw_event(const char **strp, struct perf_counter_attr *attr) 581static enum event_result
582parse_raw_event(const char **strp, struct perf_event_attr *attr)
470{ 583{
471 const char *str = *strp; 584 const char *str = *strp;
472 u64 config; 585 u64 config;
473 int n; 586 int n;
474 587
475 if (*str != 'r') 588 if (*str != 'r')
476 return 0; 589 return EVT_FAILED;
477 n = hex2u64(str + 1, &config); 590 n = hex2u64(str + 1, &config);
478 if (n > 0) { 591 if (n > 0) {
479 *strp = str + n + 1; 592 *strp = str + n + 1;
480 attr->type = PERF_TYPE_RAW; 593 attr->type = PERF_TYPE_RAW;
481 attr->config = config; 594 attr->config = config;
482 return 1; 595 return EVT_HANDLED;
483 } 596 }
484 return 0; 597 return EVT_FAILED;
485} 598}
486 599
487static int 600static enum event_result
488parse_numeric_event(const char **strp, struct perf_counter_attr *attr) 601parse_numeric_event(const char **strp, struct perf_event_attr *attr)
489{ 602{
490 const char *str = *strp; 603 const char *str = *strp;
491 char *endp; 604 char *endp;
@@ -500,14 +613,14 @@ parse_numeric_event(const char **strp, struct perf_counter_attr *attr)
500 attr->type = type; 613 attr->type = type;
501 attr->config = config; 614 attr->config = config;
502 *strp = endp; 615 *strp = endp;
503 return 1; 616 return EVT_HANDLED;
504 } 617 }
505 } 618 }
506 return 0; 619 return EVT_FAILED;
507} 620}
508 621
509static int 622static enum event_result
510parse_event_modifier(const char **strp, struct perf_counter_attr *attr) 623parse_event_modifier(const char **strp, struct perf_event_attr *attr)
511{ 624{
512 const char *str = *strp; 625 const char *str = *strp;
513 int eu = 1, ek = 1, eh = 1; 626 int eu = 1, ek = 1, eh = 1;
@@ -539,37 +652,87 @@ parse_event_modifier(const char **strp, struct perf_counter_attr *attr)
539 * Each event can have multiple symbolic names. 652 * Each event can have multiple symbolic names.
540 * Symbolic names are (almost) exactly matched. 653 * Symbolic names are (almost) exactly matched.
541 */ 654 */
542static int parse_event_symbols(const char **str, struct perf_counter_attr *attr) 655static enum event_result
656parse_event_symbols(const char **str, struct perf_event_attr *attr)
543{ 657{
544 if (!(parse_tracepoint_event(str, attr) || 658 enum event_result ret;
545 parse_raw_event(str, attr) || 659
546 parse_numeric_event(str, attr) || 660 ret = parse_tracepoint_event(str, attr);
547 parse_symbolic_event(str, attr) || 661 if (ret != EVT_FAILED)
548 parse_generic_hw_event(str, attr))) 662 goto modifier;
549 return 0; 663
664 ret = parse_raw_event(str, attr);
665 if (ret != EVT_FAILED)
666 goto modifier;
550 667
668 ret = parse_numeric_event(str, attr);
669 if (ret != EVT_FAILED)
670 goto modifier;
671
672 ret = parse_symbolic_event(str, attr);
673 if (ret != EVT_FAILED)
674 goto modifier;
675
676 ret = parse_generic_hw_event(str, attr);
677 if (ret != EVT_FAILED)
678 goto modifier;
679
680 return EVT_FAILED;
681
682modifier:
551 parse_event_modifier(str, attr); 683 parse_event_modifier(str, attr);
552 684
553 return 1; 685 return ret;
554} 686}
555 687
688static void store_event_type(const char *orgname)
689{
690 char filename[PATH_MAX], *c;
691 FILE *file;
692 int id;
693
694 sprintf(filename, "%s/", debugfs_path);
695 strncat(filename, orgname, strlen(orgname));
696 strcat(filename, "/id");
697
698 c = strchr(filename, ':');
699 if (c)
700 *c = '/';
701
702 file = fopen(filename, "r");
703 if (!file)
704 return;
705 if (fscanf(file, "%i", &id) < 1)
706 die("cannot store event ID");
707 fclose(file);
708 perf_header__push_event(id, orgname);
709}
710
711
556int parse_events(const struct option *opt __used, const char *str, int unset __used) 712int parse_events(const struct option *opt __used, const char *str, int unset __used)
557{ 713{
558 struct perf_counter_attr attr; 714 struct perf_event_attr attr;
715 enum event_result ret;
716
717 if (strchr(str, ':'))
718 store_event_type(str);
559 719
560 for (;;) { 720 for (;;) {
561 if (nr_counters == MAX_COUNTERS) 721 if (nr_counters == MAX_COUNTERS)
562 return -1; 722 return -1;
563 723
564 memset(&attr, 0, sizeof(attr)); 724 memset(&attr, 0, sizeof(attr));
565 if (!parse_event_symbols(&str, &attr)) 725 ret = parse_event_symbols(&str, &attr);
726 if (ret == EVT_FAILED)
566 return -1; 727 return -1;
567 728
568 if (!(*str == 0 || *str == ',' || isspace(*str))) 729 if (!(*str == 0 || *str == ',' || isspace(*str)))
569 return -1; 730 return -1;
570 731
571 attrs[nr_counters] = attr; 732 if (ret != EVT_HANDLED_ALL) {
572 nr_counters++; 733 attrs[nr_counters] = attr;
734 nr_counters++;
735 }
573 736
574 if (*str == 0) 737 if (*str == 0)
575 break; 738 break;
@@ -598,31 +761,32 @@ static void print_tracepoint_events(void)
598{ 761{
599 DIR *sys_dir, *evt_dir; 762 DIR *sys_dir, *evt_dir;
600 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; 763 struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
601 struct stat st;
602 char evt_path[MAXPATHLEN]; 764 char evt_path[MAXPATHLEN];
765 char dir_path[MAXPATHLEN];
603 766
604 if (valid_debugfs_mount(debugfs_path)) 767 if (valid_debugfs_mount(debugfs_path))
605 return; 768 return;
606 769
607 sys_dir = opendir(debugfs_path); 770 sys_dir = opendir(debugfs_path);
608 if (!sys_dir) 771 if (!sys_dir)
609 goto cleanup; 772 return;
610 773
611 for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) { 774 for_each_subsystem(sys_dir, sys_dirent, sys_next) {
612 evt_dir = opendir(evt_path); 775
776 snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
777 sys_dirent.d_name);
778 evt_dir = opendir(dir_path);
613 if (!evt_dir) 779 if (!evt_dir)
614 goto cleanup; 780 continue;
615 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, 781
616 evt_path, st) { 782 for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
617 snprintf(evt_path, MAXPATHLEN, "%s:%s", 783 snprintf(evt_path, MAXPATHLEN, "%s:%s",
618 sys_dirent.d_name, evt_dirent.d_name); 784 sys_dirent.d_name, evt_dirent.d_name);
619 fprintf(stderr, " %-40s [%s]\n", evt_path, 785 fprintf(stderr, " %-42s [%s]\n", evt_path,
620 event_type_descriptors[PERF_TYPE_TRACEPOINT+1]); 786 event_type_descriptors[PERF_TYPE_TRACEPOINT+1]);
621 } 787 }
622 closedir(evt_dir); 788 closedir(evt_dir);
623 } 789 }
624
625cleanup:
626 closedir(sys_dir); 790 closedir(sys_dir);
627} 791}
628 792
@@ -650,7 +814,7 @@ void print_events(void)
650 sprintf(name, "%s OR %s", syms->symbol, syms->alias); 814 sprintf(name, "%s OR %s", syms->symbol, syms->alias);
651 else 815 else
652 strcpy(name, syms->symbol); 816 strcpy(name, syms->symbol);
653 fprintf(stderr, " %-40s [%s]\n", name, 817 fprintf(stderr, " %-42s [%s]\n", name,
654 event_type_descriptors[type]); 818 event_type_descriptors[type]);
655 819
656 prev_type = type; 820 prev_type = type;
@@ -664,7 +828,7 @@ void print_events(void)
664 continue; 828 continue;
665 829
666 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 830 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
667 fprintf(stderr, " %-40s [%s]\n", 831 fprintf(stderr, " %-42s [%s]\n",
668 event_cache_name(type, op, i), 832 event_cache_name(type, op, i),
669 event_type_descriptors[4]); 833 event_type_descriptors[4]);
670 } 834 }
@@ -672,7 +836,7 @@ void print_events(void)
672 } 836 }
673 837
674 fprintf(stderr, "\n"); 838 fprintf(stderr, "\n");
675 fprintf(stderr, " %-40s [raw hardware event descriptor]\n", 839 fprintf(stderr, " %-42s [raw hardware event descriptor]\n",
676 "rNNN"); 840 "rNNN");
677 fprintf(stderr, "\n"); 841 fprintf(stderr, "\n");
678 842