Skip to content

Commit b161f25

Browse files
captain5050acmel
authored andcommitted
perf parse-events: Only move force grouped evsels when sorting
Prior to this change, events without a group would be sorted as if they were from the location of the first event without a group. For example instructions and cycles are without a group: instructions,{imc_free_running/data_read/,imc_free_running/data_write/},cycles parse events would create an eventual evlist like: instructions,cycles,{uncore_imc_free_running_0/data_read/,uncore_imc_free_running_1/data_read/,uncore_imc_free_running_0/data_write/,uncore_imc_free_running_1/data_write/} This is done so that perf metric events, that must always be in a group, will be adjacent and so can be forced into a group. This change modifies the sorting so that only force grouped events, like perf metrics, are sorted and all other events keep their position with respect to groups in the evlist. The location of the force grouped event is chosen to match the first force grouped event. For architectures without force grouped events, ie anything not Intel Icelake or newer, this should mean sorting and fixing doesn't modify the event positions except when fixing the grouping for PMUs of things like uncore events. Fixes: 347c2f0 ("perf parse-events: Sort and group parsed events") Reported-by: Andi Kleen <[email protected]> Signed-off-by: Ian Rogers <[email protected]> Tested-by: Andi Kleen <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Kan Liang <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Xing Zhengjun <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent e8d3834 commit b161f25

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

tools/perf/util/parse-events.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,16 +2100,16 @@ __weak int arch_evlist__cmp(const struct evsel *lhs, const struct evsel *rhs)
21002100
return lhs->core.idx - rhs->core.idx;
21012101
}
21022102

2103-
static int evlist__cmp(void *state, const struct list_head *l, const struct list_head *r)
2103+
static int evlist__cmp(void *_fg_idx, const struct list_head *l, const struct list_head *r)
21042104
{
21052105
const struct perf_evsel *lhs_core = container_of(l, struct perf_evsel, node);
21062106
const struct evsel *lhs = container_of(lhs_core, struct evsel, core);
21072107
const struct perf_evsel *rhs_core = container_of(r, struct perf_evsel, node);
21082108
const struct evsel *rhs = container_of(rhs_core, struct evsel, core);
2109-
int *leader_idx = state;
2110-
int lhs_leader_idx = *leader_idx, rhs_leader_idx = *leader_idx, ret;
2109+
int *force_grouped_idx = _fg_idx;
2110+
int lhs_sort_idx, rhs_sort_idx, ret;
21112111
const char *lhs_pmu_name, *rhs_pmu_name;
2112-
bool lhs_has_group = false, rhs_has_group = false;
2112+
bool lhs_has_group, rhs_has_group;
21132113

21142114
/*
21152115
* First sort by grouping/leader. Read the leader idx only if the evsel
@@ -2121,15 +2121,25 @@ static int evlist__cmp(void *state, const struct list_head *l, const struct list
21212121
*/
21222122
if (lhs_core->leader != lhs_core || lhs_core->nr_members > 1) {
21232123
lhs_has_group = true;
2124-
lhs_leader_idx = lhs_core->leader->idx;
2124+
lhs_sort_idx = lhs_core->leader->idx;
2125+
} else {
2126+
lhs_has_group = false;
2127+
lhs_sort_idx = *force_grouped_idx != -1 && arch_evsel__must_be_in_group(lhs)
2128+
? *force_grouped_idx
2129+
: lhs_core->idx;
21252130
}
21262131
if (rhs_core->leader != rhs_core || rhs_core->nr_members > 1) {
21272132
rhs_has_group = true;
2128-
rhs_leader_idx = rhs_core->leader->idx;
2133+
rhs_sort_idx = rhs_core->leader->idx;
2134+
} else {
2135+
rhs_has_group = false;
2136+
rhs_sort_idx = *force_grouped_idx != -1 && arch_evsel__must_be_in_group(rhs)
2137+
? *force_grouped_idx
2138+
: rhs_core->idx;
21292139
}
21302140

2131-
if (lhs_leader_idx != rhs_leader_idx)
2132-
return lhs_leader_idx - rhs_leader_idx;
2141+
if (lhs_sort_idx != rhs_sort_idx)
2142+
return lhs_sort_idx - rhs_sort_idx;
21332143

21342144
/* Group by PMU if there is a group. Groups can't span PMUs. */
21352145
if (lhs_has_group && rhs_has_group) {
@@ -2146,7 +2156,7 @@ static int evlist__cmp(void *state, const struct list_head *l, const struct list
21462156

21472157
static int parse_events__sort_events_and_fix_groups(struct list_head *list)
21482158
{
2149-
int idx = 0, unsorted_idx = -1;
2159+
int idx = 0, force_grouped_idx = -1;
21502160
struct evsel *pos, *cur_leader = NULL;
21512161
struct perf_evsel *cur_leaders_grp = NULL;
21522162
bool idx_changed = false, cur_leader_force_grouped = false;
@@ -2174,12 +2184,14 @@ static int parse_events__sort_events_and_fix_groups(struct list_head *list)
21742184
*/
21752185
pos->core.idx = idx++;
21762186

2177-
if (unsorted_idx == -1 && pos == pos_leader && pos->core.nr_members < 2)
2178-
unsorted_idx = pos->core.idx;
2187+
/* Remember an index to sort all forced grouped events together to. */
2188+
if (force_grouped_idx == -1 && pos == pos_leader && pos->core.nr_members < 2 &&
2189+
arch_evsel__must_be_in_group(pos))
2190+
force_grouped_idx = pos->core.idx;
21792191
}
21802192

21812193
/* Sort events. */
2182-
list_sort(&unsorted_idx, list, evlist__cmp);
2194+
list_sort(&force_grouped_idx, list, evlist__cmp);
21832195

21842196
/*
21852197
* Recompute groups, splitting for PMUs and adding groups for events
@@ -2190,7 +2202,8 @@ static int parse_events__sort_events_and_fix_groups(struct list_head *list)
21902202
const struct evsel *pos_leader = evsel__leader(pos);
21912203
const char *pos_pmu_name = pos->group_pmu_name;
21922204
const char *cur_leader_pmu_name;
2193-
bool pos_force_grouped = arch_evsel__must_be_in_group(pos);
2205+
bool pos_force_grouped = force_grouped_idx != -1 &&
2206+
arch_evsel__must_be_in_group(pos);
21942207

21952208
/* Reset index and nr_members. */
21962209
if (pos->core.idx != idx)

0 commit comments

Comments
 (0)