[Patch v3 2/8] perf/x86: Free hybrid state on PMU init failure

From: Dapeng Mi

Date: Fri Jul 17 2026 - 04:14:54 EST


If PMU initialization fails, for example in check_hw_exists(), hybrid
state can be left partially initialized: x86_pmu.hybrid_pmu is not freed
and perf_is_hybrid remains set. This can leak memory and leave stale
hybrid state reachable after a failed init path.

Add x86_pmu_free_hybrid() and use it on PMU init failure paths so all
hybrid-related state is consistently reset.

Signed-off-by: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx>
Reviewed-by: Thomas Falcon <thomas.falcon@xxxxxxxxx>
---
arch/x86/events/core.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 872d07a5fa80..6c63b27e11e6 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2130,6 +2130,17 @@ void x86_pmu_show_pmu_cap(struct pmu *pmu)
pr_info("... global_ctrl mask: %016llx\n", hybrid(pmu, intel_ctrl));
}

+static void x86_pmu_free_hybrid(void)
+{
+ if (!x86_pmu.hybrid_pmu)
+ return;
+
+ static_branch_disable(&perf_is_hybrid);
+ kfree(x86_pmu.hybrid_pmu);
+ x86_pmu.hybrid_pmu = NULL;
+ x86_pmu.num_hybrid_pmus = 0;
+}
+
static int __init init_hw_perf_events(void)
{
struct x86_pmu_quirk *quirk;
@@ -2258,9 +2269,6 @@ static int __init init_hw_perf_events(void)
for (j = 0; j < i; j++)
perf_pmu_unregister(&x86_pmu.hybrid_pmu[j].pmu);
pr_warn("Failed to register hybrid PMUs\n");
- kfree(x86_pmu.hybrid_pmu);
- x86_pmu.hybrid_pmu = NULL;
- x86_pmu.num_hybrid_pmus = 0;
goto out2;
}
}
@@ -2276,6 +2284,7 @@ static int __init init_hw_perf_events(void)
pmi_unregister:
unregister_nmi_handler(NMI_LOCAL, "PMI");
out_bad_pmu:
+ x86_pmu_free_hybrid();
memset(&x86_pmu, 0, sizeof(x86_pmu));
return err;
}
--
2.34.1