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.c60
1 files changed, 41 insertions, 19 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6de6f89c2a61..1e15df10a88c 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -10,7 +10,7 @@
10#include "symbol.h" 10#include "symbol.h"
11#include "cache.h" 11#include "cache.h"
12#include "header.h" 12#include "header.h"
13#include <lk/debugfs.h> 13#include <api/fs/debugfs.h>
14#include "parse-events-bison.h" 14#include "parse-events-bison.h"
15#define YY_EXTRA_TYPE int 15#define YY_EXTRA_TYPE int
16#include "parse-events-flex.h" 16#include "parse-events-flex.h"
@@ -204,7 +204,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
204 } 204 }
205 path->name = malloc(MAX_EVENT_LENGTH); 205 path->name = malloc(MAX_EVENT_LENGTH);
206 if (!path->name) { 206 if (!path->name) {
207 free(path->system); 207 zfree(&path->system);
208 free(path); 208 free(path);
209 return NULL; 209 return NULL;
210 } 210 }
@@ -236,8 +236,8 @@ struct tracepoint_path *tracepoint_name_to_path(const char *name)
236 path->name = strdup(str+1); 236 path->name = strdup(str+1);
237 237
238 if (path->system == NULL || path->name == NULL) { 238 if (path->system == NULL || path->name == NULL) {
239 free(path->system); 239 zfree(&path->system);
240 free(path->name); 240 zfree(&path->name);
241 free(path); 241 free(path);
242 path = NULL; 242 path = NULL;
243 } 243 }
@@ -269,9 +269,10 @@ const char *event_type(int type)
269 269
270 270
271 271
272static int __add_event(struct list_head *list, int *idx, 272static struct perf_evsel *
273 struct perf_event_attr *attr, 273__add_event(struct list_head *list, int *idx,
274 char *name, struct cpu_map *cpus) 274 struct perf_event_attr *attr,
275 char *name, struct cpu_map *cpus)
275{ 276{
276 struct perf_evsel *evsel; 277 struct perf_evsel *evsel;
277 278
@@ -279,19 +280,19 @@ static int __add_event(struct list_head *list, int *idx,
279 280
280 evsel = perf_evsel__new_idx(attr, (*idx)++); 281 evsel = perf_evsel__new_idx(attr, (*idx)++);
281 if (!evsel) 282 if (!evsel)
282 return -ENOMEM; 283 return NULL;
283 284
284 evsel->cpus = cpus; 285 evsel->cpus = cpus;
285 if (name) 286 if (name)
286 evsel->name = strdup(name); 287 evsel->name = strdup(name);
287 list_add_tail(&evsel->node, list); 288 list_add_tail(&evsel->node, list);
288 return 0; 289 return evsel;
289} 290}
290 291
291static int add_event(struct list_head *list, int *idx, 292static int add_event(struct list_head *list, int *idx,
292 struct perf_event_attr *attr, char *name) 293 struct perf_event_attr *attr, char *name)
293{ 294{
294 return __add_event(list, idx, attr, name, NULL); 295 return __add_event(list, idx, attr, name, NULL) ? 0 : -ENOMEM;
295} 296}
296 297
297static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) 298static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
@@ -633,6 +634,9 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
633{ 634{
634 struct perf_event_attr attr; 635 struct perf_event_attr attr;
635 struct perf_pmu *pmu; 636 struct perf_pmu *pmu;
637 struct perf_evsel *evsel;
638 const char *unit;
639 double scale;
636 640
637 pmu = perf_pmu__find(name); 641 pmu = perf_pmu__find(name);
638 if (!pmu) 642 if (!pmu)
@@ -640,7 +644,7 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
640 644
641 memset(&attr, 0, sizeof(attr)); 645 memset(&attr, 0, sizeof(attr));
642 646
643 if (perf_pmu__check_alias(pmu, head_config)) 647 if (perf_pmu__check_alias(pmu, head_config, &unit, &scale))
644 return -EINVAL; 648 return -EINVAL;
645 649
646 /* 650 /*
@@ -652,8 +656,14 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
652 if (perf_pmu__config(pmu, &attr, head_config)) 656 if (perf_pmu__config(pmu, &attr, head_config))
653 return -EINVAL; 657 return -EINVAL;
654 658
655 return __add_event(list, idx, &attr, pmu_event_name(head_config), 659 evsel = __add_event(list, idx, &attr, pmu_event_name(head_config),
656 pmu->cpus); 660 pmu->cpus);
661 if (evsel) {
662 evsel->unit = unit;
663 evsel->scale = scale;
664 }
665
666 return evsel ? 0 : -ENOMEM;
657} 667}
658 668
659int parse_events__modifier_group(struct list_head *list, 669int parse_events__modifier_group(struct list_head *list,
@@ -810,8 +820,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
810 if (!add && get_event_modifier(&mod, str, NULL)) 820 if (!add && get_event_modifier(&mod, str, NULL))
811 return -EINVAL; 821 return -EINVAL;
812 822
813 list_for_each_entry(evsel, list, node) { 823 __evlist__for_each(list, evsel) {
814
815 if (add && get_event_modifier(&mod, str, evsel)) 824 if (add && get_event_modifier(&mod, str, evsel))
816 return -EINVAL; 825 return -EINVAL;
817 826
@@ -835,7 +844,7 @@ int parse_events_name(struct list_head *list, char *name)
835{ 844{
836 struct perf_evsel *evsel; 845 struct perf_evsel *evsel;
837 846
838 list_for_each_entry(evsel, list, node) { 847 __evlist__for_each(list, evsel) {
839 if (!evsel->name) 848 if (!evsel->name)
840 evsel->name = strdup(name); 849 evsel->name = strdup(name);
841 } 850 }
@@ -907,7 +916,7 @@ int parse_events_terms(struct list_head *terms, const char *str)
907 ret = parse_events__scanner(str, &data, PE_START_TERMS); 916 ret = parse_events__scanner(str, &data, PE_START_TERMS);
908 if (!ret) { 917 if (!ret) {
909 list_splice(data.terms, terms); 918 list_splice(data.terms, terms);
910 free(data.terms); 919 zfree(&data.terms);
911 return 0; 920 return 0;
912 } 921 }
913 922
@@ -1082,12 +1091,12 @@ int is_valid_tracepoint(const char *event_string)
1082static bool is_event_supported(u8 type, unsigned config) 1091static bool is_event_supported(u8 type, unsigned config)
1083{ 1092{
1084 bool ret = true; 1093 bool ret = true;
1094 int open_return;
1085 struct perf_evsel *evsel; 1095 struct perf_evsel *evsel;
1086 struct perf_event_attr attr = { 1096 struct perf_event_attr attr = {
1087 .type = type, 1097 .type = type,
1088 .config = config, 1098 .config = config,
1089 .disabled = 1, 1099 .disabled = 1,
1090 .exclude_kernel = 1,
1091 }; 1100 };
1092 struct { 1101 struct {
1093 struct thread_map map; 1102 struct thread_map map;
@@ -1099,7 +1108,20 @@ static bool is_event_supported(u8 type, unsigned config)
1099 1108
1100 evsel = perf_evsel__new(&attr); 1109 evsel = perf_evsel__new(&attr);
1101 if (evsel) { 1110 if (evsel) {
1102 ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0; 1111 open_return = perf_evsel__open(evsel, NULL, &tmap.map);
1112 ret = open_return >= 0;
1113
1114 if (open_return == -EACCES) {
1115 /*
1116 * This happens if the paranoid value
1117 * /proc/sys/kernel/perf_event_paranoid is set to 2
1118 * Re-run with exclude_kernel set; we don't do that
1119 * by default as some ARM machines do not support it.
1120 *
1121 */
1122 evsel->attr.exclude_kernel = 1;
1123 ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0;
1124 }
1103 perf_evsel__delete(evsel); 1125 perf_evsel__delete(evsel);
1104 } 1126 }
1105 1127