diff options
-rw-r--r-- | tools/perf/util/parse-events.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index b2dd0779dacc..98125319b158 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #define YY_EXTRA_TYPE int | 15 | #define YY_EXTRA_TYPE int |
16 | #include "parse-events-flex.h" | 16 | #include "parse-events-flex.h" |
17 | #include "pmu.h" | 17 | #include "pmu.h" |
18 | #include "thread_map.h" | ||
18 | 19 | ||
19 | #define MAX_NAME_LEN 100 | 20 | #define MAX_NAME_LEN 100 |
20 | 21 | ||
@@ -1076,6 +1077,33 @@ int is_valid_tracepoint(const char *event_string) | |||
1076 | return 0; | 1077 | return 0; |
1077 | } | 1078 | } |
1078 | 1079 | ||
1080 | static bool is_event_supported(u8 type, unsigned config) | ||
1081 | { | ||
1082 | bool ret = true; | ||
1083 | struct perf_evsel *evsel; | ||
1084 | struct perf_event_attr attr = { | ||
1085 | .type = type, | ||
1086 | .config = config, | ||
1087 | .disabled = 1, | ||
1088 | .exclude_kernel = 1, | ||
1089 | }; | ||
1090 | struct { | ||
1091 | struct thread_map map; | ||
1092 | int threads[1]; | ||
1093 | } tmap = { | ||
1094 | .map.nr = 1, | ||
1095 | .threads = { 0 }, | ||
1096 | }; | ||
1097 | |||
1098 | evsel = perf_evsel__new(&attr, 0); | ||
1099 | if (evsel) { | ||
1100 | ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; | ||
1101 | perf_evsel__delete(evsel); | ||
1102 | } | ||
1103 | |||
1104 | return ret; | ||
1105 | } | ||
1106 | |||
1079 | static void __print_events_type(u8 type, struct event_symbol *syms, | 1107 | static void __print_events_type(u8 type, struct event_symbol *syms, |
1080 | unsigned max) | 1108 | unsigned max) |
1081 | { | 1109 | { |
@@ -1083,14 +1111,16 @@ static void __print_events_type(u8 type, struct event_symbol *syms, | |||
1083 | unsigned i; | 1111 | unsigned i; |
1084 | 1112 | ||
1085 | for (i = 0; i < max ; i++, syms++) { | 1113 | for (i = 0; i < max ; i++, syms++) { |
1114 | if (!is_event_supported(type, i)) | ||
1115 | continue; | ||
1116 | |||
1086 | if (strlen(syms->alias)) | 1117 | if (strlen(syms->alias)) |
1087 | snprintf(name, sizeof(name), "%s OR %s", | 1118 | snprintf(name, sizeof(name), "%s OR %s", |
1088 | syms->symbol, syms->alias); | 1119 | syms->symbol, syms->alias); |
1089 | else | 1120 | else |
1090 | snprintf(name, sizeof(name), "%s", syms->symbol); | 1121 | snprintf(name, sizeof(name), "%s", syms->symbol); |
1091 | 1122 | ||
1092 | printf(" %-50s [%s]\n", name, | 1123 | printf(" %-50s [%s]\n", name, event_type_descriptors[type]); |
1093 | event_type_descriptors[type]); | ||
1094 | } | 1124 | } |
1095 | } | 1125 | } |
1096 | 1126 | ||
@@ -1119,6 +1149,10 @@ int print_hwcache_events(const char *event_glob, bool name_only) | |||
1119 | if (event_glob != NULL && !strglobmatch(name, event_glob)) | 1149 | if (event_glob != NULL && !strglobmatch(name, event_glob)) |
1120 | continue; | 1150 | continue; |
1121 | 1151 | ||
1152 | if (!is_event_supported(PERF_TYPE_HW_CACHE, | ||
1153 | type | (op << 8) | (i << 16))) | ||
1154 | continue; | ||
1155 | |||
1122 | if (name_only) | 1156 | if (name_only) |
1123 | printf("%s ", name); | 1157 | printf("%s ", name); |
1124 | else | 1158 | else |
@@ -1148,6 +1182,9 @@ static void print_symbol_events(const char *event_glob, unsigned type, | |||
1148 | (syms->alias && strglobmatch(syms->alias, event_glob)))) | 1182 | (syms->alias && strglobmatch(syms->alias, event_glob)))) |
1149 | continue; | 1183 | continue; |
1150 | 1184 | ||
1185 | if (!is_event_supported(type, i)) | ||
1186 | continue; | ||
1187 | |||
1151 | if (name_only) { | 1188 | if (name_only) { |
1152 | printf("%s ", syms->symbol); | 1189 | printf("%s ", syms->symbol); |
1153 | continue; | 1190 | continue; |