|
@@ -268,6 +268,9 @@ const char *event_name(struct perf_evsel *evsel)
|
|
|
u64 config = evsel->attr.config;
|
|
|
int type = evsel->attr.type;
|
|
|
|
|
|
+ if (evsel->name)
|
|
|
+ return evsel->name;
|
|
|
+
|
|
|
return __event_name(type, config);
|
|
|
}
|
|
|
|
|
@@ -782,8 +785,10 @@ int parse_events(const struct option *opt, const char *str, int unset __used)
|
|
|
struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
|
|
|
struct perf_event_attr attr;
|
|
|
enum event_result ret;
|
|
|
+ const char *ostr;
|
|
|
|
|
|
for (;;) {
|
|
|
+ ostr = str;
|
|
|
memset(&attr, 0, sizeof(attr));
|
|
|
ret = parse_event_symbols(opt, &str, &attr);
|
|
|
if (ret == EVT_FAILED)
|
|
@@ -798,6 +803,11 @@ int parse_events(const struct option *opt, const char *str, int unset __used)
|
|
|
if (evsel == NULL)
|
|
|
return -1;
|
|
|
perf_evlist__add(evlist, evsel);
|
|
|
+
|
|
|
+ evsel->name = calloc(str - ostr + 1, 1);
|
|
|
+ if (!evsel->name)
|
|
|
+ return -1;
|
|
|
+ strncpy(evsel->name, ostr, str - ostr);
|
|
|
}
|
|
|
|
|
|
if (*str == 0)
|
|
@@ -848,7 +858,7 @@ static const char * const event_type_descriptors[] = {
|
|
|
* Print the events from <debugfs_mount_point>/tracing/events
|
|
|
*/
|
|
|
|
|
|
-static void print_tracepoint_events(void)
|
|
|
+void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
|
|
|
{
|
|
|
DIR *sys_dir, *evt_dir;
|
|
|
struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
|
|
@@ -863,6 +873,9 @@ static void print_tracepoint_events(void)
|
|
|
return;
|
|
|
|
|
|
for_each_subsystem(sys_dir, sys_dirent, sys_next) {
|
|
|
+ if (subsys_glob != NULL &&
|
|
|
+ !strglobmatch(sys_dirent.d_name, subsys_glob))
|
|
|
+ continue;
|
|
|
|
|
|
snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
|
|
|
sys_dirent.d_name);
|
|
@@ -871,6 +884,10 @@ static void print_tracepoint_events(void)
|
|
|
continue;
|
|
|
|
|
|
for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
|
|
|
+ if (event_glob != NULL &&
|
|
|
+ !strglobmatch(evt_dirent.d_name, event_glob))
|
|
|
+ continue;
|
|
|
+
|
|
|
snprintf(evt_path, MAXPATHLEN, "%s:%s",
|
|
|
sys_dirent.d_name, evt_dirent.d_name);
|
|
|
printf(" %-42s [%s]\n", evt_path,
|
|
@@ -922,13 +939,61 @@ int is_valid_tracepoint(const char *event_string)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+void print_events_type(u8 type)
|
|
|
+{
|
|
|
+ struct event_symbol *syms = event_symbols;
|
|
|
+ unsigned int i;
|
|
|
+ char name[64];
|
|
|
+
|
|
|
+ for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
|
|
|
+ if (type != syms->type)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (strlen(syms->alias))
|
|
|
+ snprintf(name, sizeof(name), "%s OR %s",
|
|
|
+ syms->symbol, syms->alias);
|
|
|
+ else
|
|
|
+ snprintf(name, sizeof(name), "%s", syms->symbol);
|
|
|
+
|
|
|
+ printf(" %-42s [%s]\n", name,
|
|
|
+ event_type_descriptors[type]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int print_hwcache_events(const char *event_glob)
|
|
|
+{
|
|
|
+ unsigned int type, op, i, printed = 0;
|
|
|
+
|
|
|
+ for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
|
|
|
+ for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
|
|
|
+ /* skip invalid cache type */
|
|
|
+ if (!is_cache_op_valid(type, op))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
|
|
|
+ char *name = event_cache_name(type, op, i);
|
|
|
+
|
|
|
+ if (event_glob != NULL &&
|
|
|
+ !strglobmatch(name, event_glob))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ printf(" %-42s [%s]\n", name,
|
|
|
+ event_type_descriptors[PERF_TYPE_HW_CACHE]);
|
|
|
+ ++printed;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return printed;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Print the help text for the event symbols:
|
|
|
*/
|
|
|
-void print_events(void)
|
|
|
+void print_events(const char *event_glob)
|
|
|
{
|
|
|
struct event_symbol *syms = event_symbols;
|
|
|
- unsigned int i, type, op, prev_type = -1;
|
|
|
+ unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0;
|
|
|
char name[40];
|
|
|
|
|
|
printf("\n");
|
|
@@ -937,8 +1002,16 @@ void print_events(void)
|
|
|
for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
|
|
|
type = syms->type;
|
|
|
|
|
|
- if (type != prev_type)
|
|
|
+ if (type != prev_type && printed) {
|
|
|
printf("\n");
|
|
|
+ printed = 0;
|
|
|
+ ntypes_printed++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (event_glob != NULL &&
|
|
|
+ !(strglobmatch(syms->symbol, event_glob) ||
|
|
|
+ (syms->alias && strglobmatch(syms->alias, event_glob))))
|
|
|
+ continue;
|
|
|
|
|
|
if (strlen(syms->alias))
|
|
|
sprintf(name, "%s OR %s", syms->symbol, syms->alias);
|
|
@@ -948,22 +1021,17 @@ void print_events(void)
|
|
|
event_type_descriptors[type]);
|
|
|
|
|
|
prev_type = type;
|
|
|
+ ++printed;
|
|
|
}
|
|
|
|
|
|
- printf("\n");
|
|
|
- for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
|
|
|
- for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
|
|
|
- /* skip invalid cache type */
|
|
|
- if (!is_cache_op_valid(type, op))
|
|
|
- continue;
|
|
|
-
|
|
|
- for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
|
|
|
- printf(" %-42s [%s]\n",
|
|
|
- event_cache_name(type, op, i),
|
|
|
- event_type_descriptors[PERF_TYPE_HW_CACHE]);
|
|
|
- }
|
|
|
- }
|
|
|
+ if (ntypes_printed) {
|
|
|
+ printed = 0;
|
|
|
+ printf("\n");
|
|
|
}
|
|
|
+ print_hwcache_events(event_glob);
|
|
|
+
|
|
|
+ if (event_glob != NULL)
|
|
|
+ return;
|
|
|
|
|
|
printf("\n");
|
|
|
printf(" %-42s [%s]\n",
|
|
@@ -976,7 +1044,7 @@ void print_events(void)
|
|
|
event_type_descriptors[PERF_TYPE_BREAKPOINT]);
|
|
|
printf("\n");
|
|
|
|
|
|
- print_tracepoint_events();
|
|
|
+ print_tracepoint_events(NULL, NULL);
|
|
|
|
|
|
exit(129);
|
|
|
}
|