@@ -2103,7 +2103,7 @@ static int test_event_fake_pmu(const char *str)
parse_events_error__init(&err);
perf_pmu__test_parse_init();
- ret = __parse_events(evlist, str, &err, &perf_pmu__fake);
+ ret = __parse_events(evlist, str, &err, &perf_pmu__fake, /*warn_if_reordered=*/true);
if (ret) {
pr_debug("failed to parse event '%s', err %d, str '%s'\n",
str, ret, err.str);
@@ -785,7 +785,7 @@ static int check_parse_id(const char *id, struct parse_events_error *error,
*/
perf_pmu__test_parse_init();
}
- ret = __parse_events(evlist, dup, error, fake_pmu);
+ ret = __parse_events(evlist, dup, error, fake_pmu, /*warn_if_reordered=*/true);
free(dup);
evlist__delete(evlist);
@@ -1441,7 +1441,8 @@ static int parse_ids(bool metric_no_merge, struct perf_pmu *fake_pmu,
}
pr_debug("Parsing metric events '%s'\n", events.buf);
parse_events_error__init(&parse_error);
- ret = __parse_events(parsed_evlist, events.buf, &parse_error, fake_pmu);
+ ret = __parse_events(parsed_evlist, events.buf, &parse_error, fake_pmu,
+ /*warn_if_reordered=*/false);
if (ret) {
parse_events_error__print(&parse_error, events.buf);
goto err_out;
@@ -2157,11 +2157,13 @@ static int evlist__cmp(void *state, const struct list_head *l, const struct list
return arch_evlist__cmp(lhs, rhs);
}
-static void parse_events__sort_events_and_fix_groups(struct list_head *list)
+static bool parse_events__sort_events_and_fix_groups(struct list_head *list)
{
int idx = -1;
struct evsel *pos, *cur_leader = NULL;
struct perf_evsel *cur_leaders_grp = NULL;
+ bool idx_changed = false;
+ int orig_num_leaders = 0, num_leaders = 0;
/*
* Compute index to insert ungrouped events at. Place them where the
@@ -2170,11 +2172,11 @@ static void parse_events__sort_events_and_fix_groups(struct list_head *list)
list_for_each_entry(pos, list, core.node) {
const struct evsel *pos_leader = evsel__leader(pos);
- if (pos != pos_leader || pos->core.nr_members > 1)
- continue;
+ if (pos == pos_leader)
+ orig_num_leaders++;
- idx = pos->core.idx;
- break;
+ if (idx == -1 && pos == pos_leader && pos->core.nr_members < 2)
+ idx = pos->core.idx;
}
/* Sort events. */
@@ -2192,6 +2194,8 @@ static void parse_events__sort_events_and_fix_groups(struct list_head *list)
bool force_grouped = arch_evsel__must_be_in_group(pos);
/* Reset index and nr_members. */
+ if (pos->core.idx != idx)
+ idx_changed = true;
pos->core.idx = idx++;
pos->core.nr_members = 0;
@@ -2225,12 +2229,18 @@ static void parse_events__sort_events_and_fix_groups(struct list_head *list)
}
}
list_for_each_entry(pos, list, core.node) {
- pos->core.leader->nr_members++;
+ struct evsel *pos_leader = evsel__leader(pos);
+
+ if (pos == pos_leader)
+ num_leaders++;
+ pos_leader->core.nr_members++;
}
+ return idx_changed || num_leaders != orig_num_leaders;
}
int __parse_events(struct evlist *evlist, const char *str,
- struct parse_events_error *err, struct perf_pmu *fake_pmu)
+ struct parse_events_error *err, struct perf_pmu *fake_pmu,
+ bool warn_if_reordered)
{
struct parse_events_state parse_state = {
.list = LIST_HEAD_INIT(parse_state.list),
@@ -2250,7 +2260,9 @@ int __parse_events(struct evlist *evlist, const char *str,
return -1;
}
- parse_events__sort_events_and_fix_groups(&parse_state.list);
+ if (parse_events__sort_events_and_fix_groups(&parse_state.list) &&
+ warn_if_reordered && !parse_state.wild_card_pmus)
+ pr_warning("WARNING: events were regrouped to match PMUs\n");
/*
* Add list to the evlist even with errors to allow callers to clean up.
@@ -26,13 +26,13 @@ int parse_events_option(const struct option *opt, const char *str, int unset);
int parse_events_option_new_evlist(const struct option *opt, const char *str, int unset);
__attribute__((nonnull(1, 2, 3)))
int __parse_events(struct evlist *evlist, const char *str, struct parse_events_error *error,
- struct perf_pmu *fake_pmu);
+ struct perf_pmu *fake_pmu, bool warn_if_reordered);
-__attribute__((nonnull))
+__attribute__((nonnull(1, 2, 3)))
static inline int parse_events(struct evlist *evlist, const char *str,
struct parse_events_error *err)
{
- return __parse_events(evlist, str, err, NULL);
+ return __parse_events(evlist, str, err, /*fake_pmu=*/NULL, /*warn_if_reordered=*/true);
}
int parse_event(struct evlist *evlist, const char *str);
@@ -128,6 +128,7 @@ struct parse_events_state {
int stoken;
struct perf_pmu *fake_pmu;
char *hybrid_pmu_name;
+ bool wild_card_pmus;
};
void parse_events__shrink_config_terms(void);
@@ -323,6 +323,7 @@ event_pmu_name opt_pmu_config
if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms,
/*auto_merge_stats=*/true)) {
ok++;
+ parse_state->wild_card_pmus = true;
}
parse_events_terms__delete(terms);
}