hwpstate_intel(4): Detect and support PKG variant
If package-level control is present, we default to using it. Per-core software control may be enabled by setting the machdep.hwpstate_pkg_ctrl tunable to "0" in loader.conf(5).
This commit is contained in:
parent
556a1a0bc6
commit
cd4e43b27d
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 22, 2020
|
||||
.Dd February 1, 2020
|
||||
.Dt HWPSTATE_INTEL 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -49,7 +49,15 @@ Can be used to disable
|
||||
.Nm ,
|
||||
allowing other compatible drivers to manage performance states, like
|
||||
.Xr est 4 .
|
||||
.Pq default 0
|
||||
Defaults to
|
||||
.Dv Qq 0
|
||||
(enabled).
|
||||
.It Va machdep.hwpstate_pkg_ctrl
|
||||
Selects between package-level control (the default) and per-core control.
|
||||
.Dv Qq 1
|
||||
selects package-level control and
|
||||
.Dv Qq 0
|
||||
selects core-level control.
|
||||
.El
|
||||
.Sh SYSCTL VARIABLES
|
||||
The following
|
||||
|
@ -88,6 +88,7 @@ struct hwp_softc {
|
||||
bool hwp_activity_window;
|
||||
bool hwp_pref_ctrl;
|
||||
bool hwp_pkg_ctrl;
|
||||
bool hwp_pkg_ctrl_en;
|
||||
bool hwp_perf_bias;
|
||||
|
||||
uint64_t req; /* Cached copy of last request */
|
||||
@ -109,6 +110,11 @@ DRIVER_MODULE(hwpstate_intel, cpu, hwpstate_intel_driver,
|
||||
hwpstate_intel_devclass, NULL, NULL);
|
||||
MODULE_VERSION(hwpstate_intel, 1);
|
||||
|
||||
static bool hwpstate_pkg_ctrl_enable = true;
|
||||
SYSCTL_BOOL(_machdep, OID_AUTO, hwpstate_pkg_ctrl, CTLFLAG_RDTUN,
|
||||
&hwpstate_pkg_ctrl_enable, 0,
|
||||
"Set 1 (default) to enable package-level control, 0 to disable");
|
||||
|
||||
static int
|
||||
intel_hwp_dump_sysctl_handler(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
@ -260,7 +266,10 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS)
|
||||
thread_unlock(curthread);
|
||||
|
||||
if (sc->hwp_pref_ctrl) {
|
||||
ret = rdmsr_safe(MSR_IA32_HWP_REQUEST, &requested);
|
||||
if (sc->hwp_pkg_ctrl_en)
|
||||
ret = rdmsr_safe(MSR_IA32_HWP_REQUEST_PKG, &requested);
|
||||
else
|
||||
ret = rdmsr_safe(MSR_IA32_HWP_REQUEST, &requested);
|
||||
if (ret)
|
||||
goto out;
|
||||
val = (requested & IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE) >> 24;
|
||||
@ -293,9 +302,12 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS)
|
||||
val = percent_to_raw(val);
|
||||
|
||||
requested &= ~IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE;
|
||||
requested |= val << 24;
|
||||
requested |= val << 24u;
|
||||
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, requested);
|
||||
if (sc->hwp_pkg_ctrl_en)
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, requested);
|
||||
else
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, requested);
|
||||
} else {
|
||||
requested = percent_to_raw_perf_bias(val);
|
||||
MPASS((requested & ~IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK) == 0);
|
||||
@ -347,7 +359,6 @@ intel_hwpstate_probe(device_t dev)
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
/* FIXME: Need to support PKG variant */
|
||||
static int
|
||||
set_autonomous_hwp(struct hwp_softc *sc)
|
||||
{
|
||||
@ -421,11 +432,30 @@ set_autonomous_hwp(struct hwp_softc *sc)
|
||||
sc->req &= ~IA32_HWP_REQUEST_MAXIMUM_PERFORMANCE;
|
||||
sc->req |= sc->high << 8;
|
||||
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req);
|
||||
/* If supported, request package-level control for this CPU. */
|
||||
if (sc->hwp_pkg_ctrl_en)
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req |
|
||||
IA32_HWP_REQUEST_PACKAGE_CONTROL);
|
||||
else
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req);
|
||||
if (ret) {
|
||||
device_printf(dev,
|
||||
"Failed to setup autonomous HWP for cpu%d\n",
|
||||
pc->pc_cpuid);
|
||||
"Failed to setup%s autonomous HWP for cpu%d\n",
|
||||
sc->hwp_pkg_ctrl_en ? " PKG" : "", pc->pc_cpuid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If supported, write the PKG-wide control MSR. */
|
||||
if (sc->hwp_pkg_ctrl_en) {
|
||||
/*
|
||||
* "The structure of the IA32_HWP_REQUEST_PKG MSR
|
||||
* (package-level) is identical to the IA32_HWP_REQUEST MSR
|
||||
* with the exception of the Package Control field, which does
|
||||
* not exist." (Intel SDM §14.4.4)
|
||||
*/
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req);
|
||||
device_printf(dev,
|
||||
"Failed to set autonomous HWP for package\n");
|
||||
}
|
||||
|
||||
out:
|
||||
@ -455,6 +485,9 @@ intel_hwpstate_attach(device_t dev)
|
||||
if (cpu_power_eax & CPUTPM1_HWP_PKG)
|
||||
sc->hwp_pkg_ctrl = true;
|
||||
|
||||
/* Allow administrators to disable pkg-level control. */
|
||||
sc->hwp_pkg_ctrl_en = (sc->hwp_pkg_ctrl && hwpstate_pkg_ctrl_enable);
|
||||
|
||||
/* ecx */
|
||||
if (cpu_power_ecx & CPUID_PERF_BIAS)
|
||||
sc->hwp_perf_bias = true;
|
||||
@ -558,11 +591,21 @@ intel_hwpstate_resume(device_t dev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req);
|
||||
if (sc->hwp_pkg_ctrl_en)
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req |
|
||||
IA32_HWP_REQUEST_PACKAGE_CONTROL);
|
||||
else
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req);
|
||||
if (ret) {
|
||||
device_printf(dev,
|
||||
"Failed to setup autonomous HWP for cpu%d after suspend\n",
|
||||
pc->pc_cpuid);
|
||||
"Failed to set%s autonomous HWP for cpu%d after suspend\n",
|
||||
sc->hwp_pkg_ctrl_en ? " PKG" : "", pc->pc_cpuid);
|
||||
goto out;
|
||||
}
|
||||
if (sc->hwp_pkg_ctrl_en) {
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req);
|
||||
device_printf(dev,
|
||||
"Failed to set autonomous HWP for package after suspend\n");
|
||||
}
|
||||
|
||||
out:
|
||||
|
Loading…
x
Reference in New Issue
Block a user