hwpstate_intel(4): Save admin-set EPP/EPB and restore after suspend

This commit is contained in:
Conrad Meyer
2020-02-01 20:12:02 +00:00
parent c93eb470b4
commit e656fa70dc
+39 -21
View File
@@ -90,8 +90,10 @@ struct hwp_softc {
bool hwp_pkg_ctrl; bool hwp_pkg_ctrl;
bool hwp_pkg_ctrl_en; bool hwp_pkg_ctrl_en;
bool hwp_perf_bias; bool hwp_perf_bias;
bool hwp_perf_bias_cached;
uint64_t req; /* Cached copy of last request */ uint64_t req; /* Cached copy of HWP_REQUEST */
uint64_t hwp_energy_perf_bias; /* Cache PERF_BIAS */
uint8_t high; uint8_t high;
uint8_t guaranteed; uint8_t guaranteed;
@@ -248,7 +250,7 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS)
struct hwp_softc *sc; struct hwp_softc *sc;
device_t dev; device_t dev;
struct pcpu *pc; struct pcpu *pc;
uint64_t requested; uint64_t epb;
uint32_t val; uint32_t val;
int ret; int ret;
@@ -266,13 +268,7 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS)
thread_unlock(curthread); thread_unlock(curthread);
if (sc->hwp_pref_ctrl) { if (sc->hwp_pref_ctrl) {
if (sc->hwp_pkg_ctrl_en) val = (sc->req & IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE) >> 24;
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;
val = raw_to_percent(val); val = raw_to_percent(val);
} else { } else {
/* /*
@@ -280,10 +276,15 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS)
* uses MSR_IA32_ENERGY_PERF_BIAS instead (Intel SDM §14.4.4). * uses MSR_IA32_ENERGY_PERF_BIAS instead (Intel SDM §14.4.4).
* This register is per-core (but not HT). * This register is per-core (but not HT).
*/ */
ret = rdmsr_safe(MSR_IA32_ENERGY_PERF_BIAS, &requested); if (!sc->hwp_perf_bias_cached) {
if (ret) ret = rdmsr_safe(MSR_IA32_ENERGY_PERF_BIAS, &epb);
goto out; if (ret)
val = requested & IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK; goto out;
sc->hwp_energy_perf_bias = epb;
sc->hwp_perf_bias_cached = true;
}
val = sc->hwp_energy_perf_bias &
IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK;
val = raw_to_percent_perf_bias(val); val = raw_to_percent_perf_bias(val);
} }
@@ -301,17 +302,23 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS)
if (sc->hwp_pref_ctrl) { if (sc->hwp_pref_ctrl) {
val = percent_to_raw(val); val = percent_to_raw(val);
requested &= ~IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE; sc->req =
requested |= val << 24u; ((sc->req & ~IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE)
| (val << 24u));
if (sc->hwp_pkg_ctrl_en) if (sc->hwp_pkg_ctrl_en)
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, requested); ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req);
else else
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, requested); ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req);
} else { } else {
requested = percent_to_raw_perf_bias(val); val = percent_to_raw_perf_bias(val);
MPASS((requested & ~IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK) == 0); MPASS((val & ~IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK) == 0);
ret = wrmsr_safe(MSR_IA32_ENERGY_PERF_BIAS, requested);
sc->hwp_energy_perf_bias =
((sc->hwp_energy_perf_bias &
~IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK) | val);
ret = wrmsr_safe(MSR_IA32_ENERGY_PERF_BIAS,
sc->hwp_energy_perf_bias);
} }
out: out:
@@ -604,10 +611,21 @@ intel_hwpstate_resume(device_t dev)
} }
if (sc->hwp_pkg_ctrl_en) { if (sc->hwp_pkg_ctrl_en) {
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req); ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req);
if (ret) if (ret) {
device_printf(dev, device_printf(dev,
"Failed to set autonomous HWP for package after " "Failed to set autonomous HWP for package after "
"suspend\n"); "suspend\n");
goto out;
}
}
if (!sc->hwp_pref_ctrl && sc->hwp_perf_bias_cached) {
ret = wrmsr_safe(MSR_IA32_ENERGY_PERF_BIAS,
sc->hwp_energy_perf_bias);
if (ret) {
device_printf(dev,
"Failed to set energy perf bias for cpu%d after "
"suspend\n", pc->pc_cpuid);
}
} }
out: out: