[PATCH 02/15] perf/x86/intel: Reset active_fixed_ctrl_val on CPU teardown

From: Dapeng Mi

Date: Mon Sep 28 2026 - 03:51:35 EST


cpuc->active_fixed_ctrl_val tracks the value currently programmed into
MSR_CORE_PERF_FIXED_CTR_CTRL, and reprogramming is skipped when the new
value matches the cached one.

After a CPU offline/online cycle, MSR_CORE_PERF_FIXED_CTR_CTRL may return
to its reset state, but active_fixed_ctrl_val may still hold the
pre-offline value. If the next computed fixed_ctrl_val matches that stale
cache entry, the MSR update is incorrectly skipped, leaving
MSR_CORE_PERF_FIXED_CTR_CTRL uninitialized for fixed counters and
resulting in errors in fixed counter counting or samplig.

Clear active_fixed_ctrl_val and MSR_CORE_PERF_FIXED_CTR_CTRL during CPU
teardown so MSR_CORE_PERF_FIXED_CTR_CTRL is always reprogrammed when the
CPU comes back online.

Fixes: fae9ebde9696 ("perf/x86/intel: Optimize FIXED_CTR_CTRL access")
Signed-off-by: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx>
---
arch/x86/events/intel/core.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 65815d13ae3f..b8dd7b73c31a 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -6591,8 +6591,25 @@ static void free_excl_cntrs(struct cpu_hw_events *cpuc)
cpuc->constraint_list = NULL;
}

+static void fini_fixed_cntrs_on_cpu(int cpu)
+{
+ struct cpu_hw_events *cpuc;
+
+ if (x86_pmu.version < 2)
+ return;
+
+ /*
+ * Clear active_fixed_ctrl_val so MSR_CORE_PERF_FIXED_CTR_CTRL
+ * can be reprogrammed after CPU online.
+ */
+ cpuc = &per_cpu(cpu_hw_events, cpu);
+ cpuc->active_fixed_ctrl_val = 0;
+ wrmsrq_on_cpu(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
+}
+
static void intel_pmu_cpu_dying(int cpu)
{
+ fini_fixed_cntrs_on_cpu(cpu);
fini_debug_store_on_cpu(cpu);
fini_arch_pebs_on_cpu(cpu);
}
--
2.34.1