summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/parse-events.c2
-rw-r--r--tools/perf/util/pmu.c34
-rw-r--r--tools/perf/util/pmu.h2
3 files changed, 29 insertions, 9 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 7cad82a9f578..781747bedc3e 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1348,7 +1348,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
return evsel ? 0 : -ENOMEM;
}
- if (!parse_state->fake_pmu && perf_pmu__check_alias(pmu, head_config, &info))
+ if (!parse_state->fake_pmu && perf_pmu__check_alias(pmu, head_config, &info, err))
return -EINVAL;
if (verbose > 1) {
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index d91367155e29..0c82bbeea7d6 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -1443,17 +1443,33 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
static int check_info_data(struct perf_pmu_alias *alias,
- struct perf_pmu_info *info)
+ struct perf_pmu_info *info,
+ struct parse_events_error *err,
+ int column)
{
/*
* Only one term in event definition can
* define unit, scale and snapshot, fail
* if there's more than one.
*/
- if ((info->unit && alias->unit[0]) ||
- (info->scale && alias->scale) ||
- (info->snapshot && alias->snapshot))
+ if (info->unit && alias->unit[0]) {
+ parse_events_error__handle(err, column,
+ strdup("Attempt to set event's unit twice"),
+ NULL);
+ return -EINVAL;
+ }
+ if (info->scale && alias->scale) {
+ parse_events_error__handle(err, column,
+ strdup("Attempt to set event's scale twice"),
+ NULL);
+ return -EINVAL;
+ }
+ if (info->snapshot && alias->snapshot) {
+ parse_events_error__handle(err, column,
+ strdup("Attempt to set event snapshot twice"),
+ NULL);
return -EINVAL;
+ }
if (alias->unit[0])
info->unit = alias->unit;
@@ -1472,7 +1488,7 @@ static int check_info_data(struct perf_pmu_alias *alias,
* defined for the alias
*/
int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
- struct perf_pmu_info *info)
+ struct perf_pmu_info *info, struct parse_events_error *err)
{
struct parse_events_term *term, *h;
struct perf_pmu_alias *alias;
@@ -1493,10 +1509,14 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
if (!alias)
continue;
ret = pmu_alias_terms(alias, &term->list);
- if (ret)
+ if (ret) {
+ parse_events_error__handle(err, term->err_term,
+ strdup("Failure to duplicate terms"),
+ NULL);
return ret;
+ }
- ret = check_info_data(alias, info);
+ ret = check_info_data(alias, info, err, term->err_term);
if (ret)
return ret;
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index f37e3d75094f..03211de345c1 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -185,7 +185,7 @@ int perf_pmu__config_terms(struct perf_pmu *pmu,
__u64 perf_pmu__format_bits(struct perf_pmu *pmu, const char *name);
int perf_pmu__format_type(struct perf_pmu *pmu, const char *name);
int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
- struct perf_pmu_info *info);
+ struct perf_pmu_info *info, struct parse_events_error *err);
int perf_pmu__find_event(struct perf_pmu *pmu, const char *event, void *state, pmu_event_callback cb);
int perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd, bool eager_load);