]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
powercap: intel_rapl: Remove incorrect CPU check in PMU context
authorKuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Mon, 9 Feb 2026 23:43:09 +0000 (15:43 -0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 11 Feb 2026 20:03:39 +0000 (21:03 +0100)
The RAPL MSR read path incorrectly validates CPU context when called
from the PMU subsystem:

    if (atomic) {
        if (unlikely(smp_processor_id() != cpu))
            return -EIO;
        rdmsrq(ra->reg.msr, ra->value);
    }

This check fails for package-scoped MSRs like RAPL energy counters,
which are readable from any CPU within the package.

The perf tool avoids hitting this check by validating against
/sys/bus/event_source/devices/power/cpumask before opening events.
However, turbostat does not perform this validation and may attempt
reads from non-lead CPUs, causing the check to fail and return zero
power values.

Since package-scoped MSRs are architecturally accessible from any CPU
in the package, remove the CPU matching check.

Also rename 'atomic' to 'pmu_ctx' to clarify this indicates PMU context
where rdmsrq() can be used directly instead of rdmsrl_safe_on_cpu().

Fixes: 748d6ba43afd ("powercap: intel_rapl: Enable MSR-based RAPL PMU support")
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Tested-by: Furquim Ulisses <ulisses.furquim@intel.com>
Reviewed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260209234310.1440722-2-sathyanarayanan.kuppuswamy@linux.intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/powercap/intel_rapl_common.c
drivers/powercap/intel_rapl_msr.c
include/linux/intel_rapl.h

index 3ff6da3bf4e63000f29ba326a8979823a5c993df..3705d0608a0fba7096b7e9a9413c5e320a8d0a0b 100644 (file)
@@ -254,7 +254,7 @@ static void rapl_init_domains(struct rapl_package *rp);
 static int rapl_read_data_raw(struct rapl_domain *rd,
                              enum rapl_primitives prim,
                              bool xlate, u64 *data,
-                             bool atomic);
+                             bool pmu_ctx);
 static int rapl_write_data_raw(struct rapl_domain *rd,
                               enum rapl_primitives prim,
                               unsigned long long value);
@@ -832,7 +832,7 @@ prim_fixups(struct rapl_domain *rd, enum rapl_primitives prim)
  */
 static int rapl_read_data_raw(struct rapl_domain *rd,
                              enum rapl_primitives prim, bool xlate, u64 *data,
-                             bool atomic)
+                             bool pmu_ctx)
 {
        u64 value;
        enum rapl_primitives prim_fixed = prim_fixups(rd, prim);
@@ -854,7 +854,7 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
 
        ra.mask = rpi->mask;
 
-       if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra, atomic)) {
+       if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra, pmu_ctx)) {
                pr_debug("failed to read reg 0x%llx for %s:%s\n", ra.reg.val, rd->rp->name, rd->name);
                return -EIO;
        }
index a2bc0a9c1e103554134ef955cc82dbc0f5f310d0..3d5e7f56d68a15a9591f09f300ba11979ffce5bc 100644 (file)
@@ -110,16 +110,14 @@ static int rapl_cpu_down_prep(unsigned int cpu)
        return 0;
 }
 
-static int rapl_msr_read_raw(int cpu, struct reg_action *ra, bool atomic)
+static int rapl_msr_read_raw(int cpu, struct reg_action *ra, bool pmu_ctx)
 {
        /*
-        * When called from atomic-context (eg PMU event handler)
-        * perform MSR read directly using rdmsrq().
+        * When called from PMU context, perform MSR read directly using
+        * rdmsrq() without IPI overhead. Package-scoped MSRs are readable
+        * from any CPU in the package.
         */
-       if (atomic) {
-               if (unlikely(smp_processor_id() != cpu))
-                       return -EIO;
-
+       if (pmu_ctx) {
                rdmsrq(ra->reg.msr, ra->value);
                goto out;
        }
index f479ef5b3341cff3a59518811285893993828476..fa1f328d67120470c3333e1a77a285df734e3b8f 100644 (file)
@@ -152,7 +152,7 @@ struct rapl_if_priv {
        union rapl_reg reg_unit;
        union rapl_reg regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
        int limits[RAPL_DOMAIN_MAX];
-       int (*read_raw)(int id, struct reg_action *ra, bool atomic);
+       int (*read_raw)(int id, struct reg_action *ra, bool pmu_ctx);
        int (*write_raw)(int id, struct reg_action *ra);
        void *defaults;
        void *rpi;