perf metricgroup: Fix find_evsel_group() event selector
The following command segfaults on my x86 broadwell: $ ./perf stat -M frontend_bound,retiring,backend_bound,bad_speculation sleep 1 WARNING: grouped events cpus do not match, disabling group: anon group { raw 0x10e } anon group { raw 0x10e } perf: util/evsel.c:1596: get_group_fd: Assertion `!(!leader->core.fd)' failed. Aborted (core dumped) The issue shows itself as a use-after-free in evlist__check_cpu_maps(), whereby the leader of an event selector (evsel) has been deleted (yet we still attempt to verify for an evsel). Fundamentally the problem comes from metricgroup__setup_events() -> find_evsel_group(), and has developed from the previous fix attempt in commit9c880c24cb
("perf metricgroup: Fix for metrics containing duration_time"). The problem now is that the logic in checking if an evsel is in the same group is subtly broken for the "cycles" event. For the "cycles" event, the pmu_name is NULL; however the logic in find_evsel_group() may set an event matched against "cycles" as used, when it should not be. This leads to a condition where an evsel is set, yet its leader is not. Fix the check for evsel pmu_name by not matching evsels when either has a NULL pmu_name. There is still a pre-existing metric issue whereby the ordering of the metrics may break the 'stat' function, as discussed at: https://lore.kernel.org/lkml/49c6fccb-b716-1bf0-18a6-cace1cdb66b9@huawei.com/ Fixes:9c880c24cb
("perf metricgroup: Fix for metrics containing duration_time") Signed-off-by: John Garry <john.garry@huawei.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> # On a Thinkpad T450S Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lore.kernel.org/lkml/1623335580-187317-2-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
9ed13a17e3
commit
fc96ec4d5d
|
@ -162,10 +162,10 @@ static bool contains_event(struct evsel **metric_events, int num_events,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool evsel_same_pmu(struct evsel *ev1, struct evsel *ev2)
|
static bool evsel_same_pmu_or_none(struct evsel *ev1, struct evsel *ev2)
|
||||||
{
|
{
|
||||||
if (!ev1->pmu_name || !ev2->pmu_name)
|
if (!ev1->pmu_name || !ev2->pmu_name)
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
return !strcmp(ev1->pmu_name, ev2->pmu_name);
|
return !strcmp(ev1->pmu_name, ev2->pmu_name);
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist,
|
||||||
*/
|
*/
|
||||||
if (!has_constraint &&
|
if (!has_constraint &&
|
||||||
ev->leader != metric_events[i]->leader &&
|
ev->leader != metric_events[i]->leader &&
|
||||||
evsel_same_pmu(ev->leader, metric_events[i]->leader))
|
evsel_same_pmu_or_none(ev->leader, metric_events[i]->leader))
|
||||||
break;
|
break;
|
||||||
if (!strcmp(metric_events[i]->name, ev->name)) {
|
if (!strcmp(metric_events[i]->name, ev->name)) {
|
||||||
set_bit(ev->idx, evlist_used);
|
set_bit(ev->idx, evlist_used);
|
||||||
|
|
Loading…
Reference in New Issue