Commit da02f54e authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

perf/core: Clean up perf_try_init_event()



Make sure that perf_try_init_event() doesn't leave event->pmu nor
event->destroy set on failure.

Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Acked-by: default avatarRavi Bangoria <ravi.bangoria@amd.com>
Link: https://lore.kernel.org/r/20250205102449.110145835@infradead.org
parent 66477c72
Loading
Loading
Loading
Loading
+38 −27
Original line number Diff line number Diff line
@@ -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 (ret)
		goto err_pmu;

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

	if (pmu->capabilities & PERF_PMU_CAP_NO_EXCLUDE &&
		    event_has_any_exclude_flag(event))
	    event_has_any_exclude_flag(event)) {
		ret = -EINVAL;
		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);
		const struct cpumask *cpumask;
		struct cpumask *pmu_cpumask;
		int cpu;

			if (pmu_cpumask && cpumask) {
		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)
					ret = -ENODEV;
				else
			goto err_destroy;

		event->event_caps |= PERF_EV_CAP_READ_SCOPE;
			} else {
				ret = -ENODEV;
			}
	}

		if (ret && event->destroy)
	return 0;

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

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

	return ret;
}