Skip to content

Commit d8ca203

Browse files
zhang-ruigregkh
authored andcommitted
powercap: intel_rapl: Do not change CLAMPING bit if ENABLE bit cannot be changed
commit 9642092 upstream. PL1 cannot be disabled on some platforms. The ENABLE bit is still set after software clears it. This behavior leads to a scenario where, upon user request to disable the Power Limit through the powercap sysfs, the ENABLE bit remains set while the CLAMPING bit is inadvertently cleared. According to the Intel Software Developer's Manual, the CLAMPING bit, "When set, allows the processor to go below the OS requested P states in order to maintain the power below specified Platform Power Limit value." Thus this means the system may operate at higher power levels than intended on such platforms. Enhance the code to check ENABLE bit after writing to it, and stop further processing if ENABLE bit cannot be changed. Reported-by: Srinivas Pandruvada <[email protected]> Fixes: 2d281d8 ("PowerCap: Introduce Intel RAPL power capping driver") Cc: All applicable <[email protected]> Signed-off-by: Zhang Rui <[email protected]> Link: https://patch.msgid.link/[email protected] [ rjw: Use str_enabled_disabled() instead of open-coded equivalent ] Signed-off-by: Rafael J. Wysocki <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 53892dc commit d8ca203

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

drivers/powercap/intel_rapl_common.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,28 @@ static int set_domain_enable(struct powercap_zone *power_zone, bool mode)
340340
{
341341
struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
342342
struct rapl_defaults *defaults = get_defaults(rd->rp);
343+
u64 val;
343344
int ret;
344345

345346
cpus_read_lock();
346347
ret = rapl_write_pl_data(rd, POWER_LIMIT1, PL_ENABLE, mode);
347-
if (!ret && defaults->set_floor_freq)
348+
if (ret)
349+
goto end;
350+
351+
ret = rapl_read_pl_data(rd, POWER_LIMIT1, PL_ENABLE, false, &val);
352+
if (ret)
353+
goto end;
354+
355+
if (mode != val) {
356+
pr_debug("%s cannot be %s\n", power_zone->name,
357+
str_enabled_disabled(mode));
358+
goto end;
359+
}
360+
361+
if (defaults->set_floor_freq)
348362
defaults->set_floor_freq(rd, mode);
363+
364+
end:
349365
cpus_read_unlock();
350366

351367
return ret;

0 commit comments

Comments
 (0)