Skip to content

Commit

Permalink
perf/core: Clean up perf_try_init_event()
Browse files Browse the repository at this point in the history
Make sure that perf_try_init_event() doesn't leave event->pmu nor
event->destroy set on failure.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Ravi Bangoria <ravi.bangoria@amd.com>
Link: https://lore.kernel.org/r/20250205102449.110145835@infradead.org
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Mar 5, 2025
1 parent 66477c7 commit da02f54
Showing 1 changed file with 38 additions and 27 deletions.
65 changes: 38 additions & 27 deletions kernel/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -12109,40 +12109,51 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event)
if (ctx)
perf_event_ctx_unlock(event->group_leader, ctx);

if (!ret) {
if (!(pmu->capabilities & PERF_PMU_CAP_EXTENDED_REGS) &&
has_extended_regs(event))
ret = -EOPNOTSUPP;
if (ret)
goto err_pmu;

if (pmu->capabilities & PERF_PMU_CAP_NO_EXCLUDE &&
event_has_any_exclude_flag(event))
ret = -EINVAL;
if (!(pmu->capabilities & PERF_PMU_CAP_EXTENDED_REGS) &&
has_extended_regs(event)) {
ret = -EOPNOTSUPP;
goto err_destroy;
}

if (pmu->scope != PERF_PMU_SCOPE_NONE && event->cpu >= 0) {
const struct cpumask *cpumask = perf_scope_cpu_topology_cpumask(pmu->scope, event->cpu);
struct cpumask *pmu_cpumask = perf_scope_cpumask(pmu->scope);
int cpu;

if (pmu_cpumask && cpumask) {
cpu = cpumask_any_and(pmu_cpumask, cpumask);
if (cpu >= nr_cpu_ids)
ret = -ENODEV;
else
event->event_caps |= PERF_EV_CAP_READ_SCOPE;
} else {
ret = -ENODEV;
}
}
if (pmu->capabilities & PERF_PMU_CAP_NO_EXCLUDE &&
event_has_any_exclude_flag(event)) {
ret = -EINVAL;
goto err_destroy;
}

if (ret && event->destroy)
event->destroy(event);
if (pmu->scope != PERF_PMU_SCOPE_NONE && event->cpu >= 0) {
const struct cpumask *cpumask;
struct cpumask *pmu_cpumask;
int cpu;

cpumask = perf_scope_cpu_topology_cpumask(pmu->scope, event->cpu);
pmu_cpumask = perf_scope_cpumask(pmu->scope);

ret = -ENODEV;
if (!pmu_cpumask || !cpumask)
goto err_destroy;

cpu = cpumask_any_and(pmu_cpumask, cpumask);
if (cpu >= nr_cpu_ids)
goto err_destroy;

event->event_caps |= PERF_EV_CAP_READ_SCOPE;
}

if (ret) {
event->pmu = NULL;
module_put(pmu->module);
return 0;

err_destroy:
if (event->destroy) {
event->destroy(event);
event->destroy = NULL;
}

err_pmu:
event->pmu = NULL;
module_put(pmu->module);
return ret;
}

Expand Down

0 comments on commit da02f54

Please sign in to comment.