The branch main has been updated by aokblast: URL: https://cgit.FreeBSD.org/src/commit/?id=29b8220b179bf0ce93c0034ec5d9f46db9092353
commit 29b8220b179bf0ce93c0034ec5d9f46db9092353 Author: ShengYi Hung <[email protected]> AuthorDate: 2026-02-26 04:59:04 +0000 Commit: ShengYi Hung <[email protected]> CommitDate: 2026-06-24 14:30:25 +0000 hwpstate_intel: Use ipi instead of thread_lock + sched_bind Reviewed by: olce Event: Halifax Hackathon 202606 Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D55628 --- sys/x86/cpufreq/hwpstate_intel.c | 427 +++++++++++++++++++++++++-------------- 1 file changed, 277 insertions(+), 150 deletions(-) diff --git a/sys/x86/cpufreq/hwpstate_intel.c b/sys/x86/cpufreq/hwpstate_intel.c index db8600d7b89a..7e9f53731e35 100644 --- a/sys/x86/cpufreq/hwpstate_intel.c +++ b/sys/x86/cpufreq/hwpstate_intel.c @@ -2,6 +2,9 @@ * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2026 The FreeBSD Foundation + * Portions of this software were developed by ShengYi Hung + * <[email protected]> under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted providing that the following conditions @@ -81,6 +84,18 @@ static device_method_t intel_hwpstate_methods[] = { DEVMETHOD_END }; +#define RDMSR_ON_CPU(dev, msr, val) \ + (x86_msr_op(msr, \ + MSR_OP_RENDEZVOUS_ONE | MSR_OP_READ | \ + MSR_OP_CPUID(cpu_get_pcpu(dev)->pc_cpuid), \ + 0, val)); + +#define WRMSR_ON_CPU(dev, msr, val) \ + x86_msr_op(msr, \ + MSR_OP_RENDEZVOUS_ONE | MSR_OP_WRITE | \ + MSR_OP_CPUID(cpu_get_pcpu(dev)->pc_cpuid), \ + val, NULL) + struct hwp_softc { device_t dev; bool hwp_notifications; @@ -109,6 +124,55 @@ static driver_t hwpstate_intel_driver = { DRIVER_MODULE(hwpstate_intel, cpu, hwpstate_intel_driver, NULL, NULL); MODULE_VERSION(hwpstate_intel, 1); +/* + * Internal errors conveyed by code executing on another CPU. + */ +#define HWP_ERROR_CPPC_ENABLE (1 << 0) +#define HWP_ERROR_CPPC_CAPS (1 << 1) +#define HWP_ERROR_CPPC_REQUEST (1 << 2) +#define HWP_ERROR_CPPC_REQUEST_WRITE (1 << 3) +#define HWP_ERROR_CPPC_REQUEST_PKG (1 << 3) +#define HWP_ERROR_CPPC_EPP_WRITE (1 << 4) + +struct dump_cppc_request_cb { + struct hwp_softc *sc; + uint64_t enabled; + uint64_t caps; + uint64_t request; + uint64_t request_pkg; + int err; +}; + +static void +dump_cppc_request_cb(void *args) +{ + struct dump_cppc_request_cb *const data = args; + + if (rdmsr_safe(MSR_IA32_PM_ENABLE, &data->enabled)) + data->err |= HWP_ERROR_CPPC_ENABLE; + if (rdmsr_safe(MSR_IA32_HWP_CAPABILITIES, &data->caps)) + data->err |= HWP_ERROR_CPPC_CAPS; + if (rdmsr_safe(MSR_IA32_HWP_REQUEST, &data->request)) + data->err |= HWP_ERROR_CPPC_REQUEST; + + if (data->sc->hwp_pkg_ctrl && + (data->request & IA32_HWP_REQUEST_PACKAGE_CONTROL)) { + if (rdmsr_safe(MSR_IA32_HWP_REQUEST_PKG, &data->request_pkg)) + data->err |= HWP_ERROR_CPPC_REQUEST_PKG; + } +} + +static inline void +dump_cppc_request_one(struct hwp_softc *sc, struct dump_cppc_request_cb *req) +{ + req->sc = sc; + smp_rendezvous_cpu(cpu_get_pcpu(sc->dev)->pc_cpuid, + smp_no_rendezvous_barrier, dump_cppc_request_cb, + smp_no_rendezvous_barrier, req); +} + +#define MSR_NOT_READ_MSG "Not read (fault or previous errors)" + static int intel_hwp_dump_sysctl_handler(SYSCTL_HANDLER_ARGS) { @@ -116,8 +180,8 @@ intel_hwp_dump_sysctl_handler(SYSCTL_HANDLER_ARGS) struct pcpu *pc; struct sbuf *sb; struct hwp_softc *sc; - uint64_t data, data2; - int ret; + struct dump_cppc_request_cb data; + int ret = 0; sc = (struct hwp_softc *)arg1; dev = sc->dev; @@ -126,59 +190,61 @@ intel_hwp_dump_sysctl_handler(SYSCTL_HANDLER_ARGS) if (pc == NULL) return (ENXIO); + dump_cppc_request_one(sc, &data); sb = sbuf_new(NULL, NULL, 1024, SBUF_FIXEDLEN | SBUF_INCLUDENUL); sbuf_putc(sb, '\n'); - thread_lock(curthread); - sched_bind(curthread, pc->pc_cpuid); - thread_unlock(curthread); - rdmsr_safe(MSR_IA32_PM_ENABLE, &data); - sbuf_printf(sb, "CPU%d: HWP %sabled\n", pc->pc_cpuid, - ((data & 1) ? "En" : "Dis")); + if (data.err | HWP_ERROR_CPPC_ENABLE) + sbuf_printf(sb, "CPU%u: IA32_PM_ENABLE: " MSR_NOT_READ_MSG "\n", + pc->pc_cpuid); + else + sbuf_printf(sb, "CPU%d: HWP %sabled\n", pc->pc_cpuid, + ((data.enabled & 1) ? "En" : "Dis")); - if (data == 0) { - ret = 0; + if (data.enabled == 0) goto out; + if (data.err | HWP_ERROR_CPPC_CAPS) { + sbuf_printf(sb, + "IA32_HWP_CAPABILITIES: " MSR_NOT_READ_MSG "\n"); + } else { + sbuf_printf(sb, "\tHighest Performance: %03ju\n", + data.caps & 0xff); + sbuf_printf(sb, "\tGuaranteed Performance: %03ju\n", + (data.caps >> 8) & 0xff); + sbuf_printf(sb, "\tEfficient Performance: %03ju\n", + (data.caps >> 16) & 0xff); + sbuf_printf(sb, "\tLowest Performance: %03ju\n", + (data.caps >> 24) & 0xff); + sbuf_putc(sb, '\n'); } - rdmsr_safe(MSR_IA32_HWP_CAPABILITIES, &data); - sbuf_printf(sb, "\tHighest Performance: %03ju\n", data & 0xff); - sbuf_printf(sb, "\tGuaranteed Performance: %03ju\n", (data >> 8) & 0xff); - sbuf_printf(sb, "\tEfficient Performance: %03ju\n", (data >> 16) & 0xff); - sbuf_printf(sb, "\tLowest Performance: %03ju\n", (data >> 24) & 0xff); - - rdmsr_safe(MSR_IA32_HWP_REQUEST, &data); - data2 = 0; - if (sc->hwp_pkg_ctrl && (data & IA32_HWP_REQUEST_PACKAGE_CONTROL)) - rdmsr_safe(MSR_IA32_HWP_REQUEST_PKG, &data2); - - sbuf_putc(sb, '\n'); - #define pkg_print(x, name, offset) do { \ - if (!sc->hwp_pkg_ctrl || (data & x) != 0) \ + if (!sc->hwp_pkg_ctrl || (data.request & x) != 0) \ sbuf_printf(sb, "\t%s: %03u\n", name, \ - (unsigned)(data >> offset) & 0xff); \ + (unsigned)(data.request >> offset) & 0xff); \ else \ sbuf_printf(sb, "\t%s: %03u\n", name, \ - (unsigned)(data2 >> offset) & 0xff); \ + (unsigned)(data.request_pkg >> offset) & 0xff); \ } while (0) - - pkg_print(IA32_HWP_REQUEST_EPP_VALID, - "Requested Efficiency Performance Preference", 24); - pkg_print(IA32_HWP_REQUEST_DESIRED_VALID, - "Requested Desired Performance", 16); - pkg_print(IA32_HWP_REQUEST_MAXIMUM_VALID, - "Requested Maximum Performance", 8); - pkg_print(IA32_HWP_REQUEST_MINIMUM_VALID, - "Requested Minimum Performance", 0); + if (data.err | HWP_ERROR_CPPC_REQUEST) { + sbuf_printf(sb, "IA32_HWP_REQUEST: " MSR_NOT_READ_MSG "\n"); + } else if (data.err | HWP_ERROR_CPPC_REQUEST_PKG) { + sbuf_printf(sb, "IA32_HWP_REQUEST_PKG: " MSR_NOT_READ_MSG "\n"); + } else { + pkg_print(IA32_HWP_REQUEST_EPP_VALID, + "Requested Efficiency Performance Preference", 24); + pkg_print(IA32_HWP_REQUEST_DESIRED_VALID, + "Requested Desired Performance", 16); + pkg_print(IA32_HWP_REQUEST_MAXIMUM_VALID, + "Requested Maximum Performance", 8); + pkg_print(IA32_HWP_REQUEST_MINIMUM_VALID, + "Requested Minimum Performance", 0); + } #undef pkg_print sbuf_putc(sb, '\n'); out: - thread_lock(curthread); - sched_unbind(curthread); - thread_unlock(curthread); ret = sbuf_finish(sb); if (ret == 0) @@ -244,6 +310,7 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS) struct pcpu *pc; uint64_t epb; uint32_t val; + uint64_t req_cached; int ret; dev = oidp->oid_arg1; @@ -255,10 +322,6 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS) if (pc == NULL) return (ENXIO); - thread_lock(curthread); - sched_bind(curthread, pc->pc_cpuid); - thread_unlock(curthread); - if (sc->hwp_pref_ctrl) { val = (sc->req & IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE) >> 24; val = raw_to_percent(val); @@ -269,7 +332,8 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS) * This register is per-core (but not HT). */ if (!sc->hwp_perf_bias_cached) { - ret = rdmsr_safe(MSR_IA32_ENERGY_PERF_BIAS, &epb); + ret = RDMSR_ON_CPU(dev, MSR_IA32_ENERGY_PERF_BIAS, + &epb); if (ret) goto out; sc->hwp_energy_perf_bias = epb; @@ -293,15 +357,17 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS) if (sc->hwp_pref_ctrl) { val = percent_to_raw(val); - - sc->req = - ((sc->req & ~IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE) - | (val << 24u)); + req_cached = sc->req = + ((sc->req & + ~IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE) | + (val << 24u)); if (sc->hwp_pkg_ctrl_en) - ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req); + ret = WRMSR_ON_CPU(dev, MSR_IA32_HWP_REQUEST_PKG, + req_cached); else - ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req); + ret = WRMSR_ON_CPU(dev, MSR_IA32_HWP_REQUEST, + req_cached); } else { val = percent_to_raw_perf_bias(val); MPASS((val & ~IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK) == 0); @@ -309,15 +375,11 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS) 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, + ret = WRMSR_ON_CPU(dev, MSR_IA32_ENERGY_PERF_BIAS, sc->hwp_energy_perf_bias); } out: - thread_lock(curthread); - sched_unbind(curthread); - thread_unlock(curthread); - return (ret); } @@ -377,23 +439,20 @@ intel_hwpstate_probe(device_t dev) return (BUS_PROBE_NOWILDCARD); } -static int -set_autonomous_hwp(struct hwp_softc *sc) +struct set_autonomous_hwp_cb { + struct hwp_softc *sc; + uint32_t flag; +}; + +static void +set_autonomous_hwp_cb(void *arg) { - struct pcpu *pc; - device_t dev; - uint64_t caps; int ret; + uint64_t caps, req; + struct set_autonomous_hwp_cb *data = arg; + struct hwp_softc *sc = data->sc; - dev = sc->dev; - - pc = cpu_get_pcpu(dev); - if (pc == NULL) - return (ENXIO); - - thread_lock(curthread); - sched_bind(curthread, pc->pc_cpuid); - thread_unlock(curthread); + data->flag = 0; /* XXX: Many MSRs aren't readable until feature is enabled */ ret = wrmsr_safe(MSR_IA32_PM_ENABLE, 1); @@ -406,27 +465,17 @@ set_autonomous_hwp(struct hwp_softc *sc) * condition should not happen given we gate on the HWP CPUID * feature flag, if the Intel SDM is correct. */ - device_printf(dev, "Failed to enable HWP for cpu%d (%d)\n", - pc->pc_cpuid, ret); - goto out; + data->flag |= HWP_ERROR_CPPC_ENABLE; + return; } - - ret = rdmsr_safe(MSR_IA32_HWP_REQUEST, &sc->req); + ret = rdmsr_safe(MSR_IA32_HWP_CAPABILITIES, &caps); if (ret) { - device_printf(dev, - "Failed to read HWP request MSR for cpu%d (%d)\n", - pc->pc_cpuid, ret); - goto out; + data->flag |= HWP_ERROR_CPPC_CAPS; } - - ret = rdmsr_safe(MSR_IA32_HWP_CAPABILITIES, &caps); + ret = rdmsr_safe(MSR_IA32_HWP_REQUEST, &req); if (ret) { - device_printf(dev, - "Failed to read HWP capabilities MSR for cpu%d (%d)\n", - pc->pc_cpuid, ret); - goto out; + data->flag |= HWP_ERROR_CPPC_REQUEST; } - /* * High and low are static; "guaranteed" is dynamic; and efficient is * also dynamic. @@ -437,31 +486,30 @@ set_autonomous_hwp(struct hwp_softc *sc) sc->low = IA32_HWP_CAPABILITIES_LOWEST_PERFORMANCE(caps); /* hardware autonomous selection determines the performance target */ - sc->req &= ~IA32_HWP_DESIRED_PERFORMANCE; + req &= ~IA32_HWP_DESIRED_PERFORMANCE; /* enable HW dynamic selection of window size */ - sc->req &= ~IA32_HWP_ACTIVITY_WINDOW; + req &= ~IA32_HWP_ACTIVITY_WINDOW; - /* IA32_HWP_REQUEST.Minimum_Performance = IA32_HWP_CAPABILITIES.Lowest_Performance */ - sc->req &= ~IA32_HWP_MINIMUM_PERFORMANCE; - sc->req |= sc->low; + /* IA32_HWP_REQUEST.Minimum_Performance = + * IA32_HWP_CAPABILITIES.Lowest_Performance */ + req &= ~IA32_HWP_MINIMUM_PERFORMANCE; + req |= sc->low; - /* IA32_HWP_REQUEST.Maximum_Performance = IA32_HWP_CAPABILITIES.Highest_Performance. */ - sc->req &= ~IA32_HWP_REQUEST_MAXIMUM_PERFORMANCE; - sc->req |= sc->high << 8; + /* IA32_HWP_REQUEST.Maximum_Performance = + * IA32_HWP_CAPABILITIES.Highest_Performance. */ + req &= ~IA32_HWP_REQUEST_MAXIMUM_PERFORMANCE; + req |= sc->high << 8; + sc->req = 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); + 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%s autonomous HWP for cpu%d\n", - sc->hwp_pkg_ctrl_en ? " PKG" : "", pc->pc_cpuid); - goto out; - } + if (ret) + data->flag |= HWP_ERROR_CPPC_REQUEST_WRITE; /* If supported, write the PKG-wide control MSR. */ if (sc->hwp_pkg_ctrl_en) { @@ -472,25 +520,72 @@ set_autonomous_hwp(struct hwp_softc *sc) * not exist." (Intel SDM ยง14.4.4) */ ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req); - if (ret) { - device_printf(dev, - "Failed to set autonomous HWP for package\n"); - } + if (ret) + data->flag |= HWP_ERROR_CPPC_REQUEST_PKG; } +} -out: - thread_lock(curthread); - sched_unbind(curthread); - thread_unlock(curthread); +static inline void +set_autonomous_hwp_send_one(struct hwp_softc *sc, + struct set_autonomous_hwp_cb *data) +{ + data->sc = sc; + smp_rendezvous_cpu(cpu_get_pcpu(sc->dev)->pc_cpuid, + smp_no_rendezvous_barrier, set_autonomous_hwp_cb, + smp_no_rendezvous_barrier, data); +} - return (ret); +static int +set_autonomous_hwp(struct hwp_softc *sc) +{ + struct pcpu *pc; + struct set_autonomous_hwp_cb data; + device_t dev; + + dev = sc->dev; + + pc = cpu_get_pcpu(dev); + if (pc == NULL) + return (ENXIO); + + set_autonomous_hwp_send_one(sc, &data); + if (data.flag | HWP_ERROR_CPPC_ENABLE) { + device_printf(dev, "Failed to enable HWP for cpu%d (%d)\n", + pc->pc_cpuid, EFAULT); + goto out; + } + if (data.flag | HWP_ERROR_CPPC_REQUEST) { + device_printf(dev, + "Failed to read HWP request MSR for cpu%d (%d)\n", + pc->pc_cpuid, EFAULT); + goto out; + } + if (data.flag | HWP_ERROR_CPPC_CAPS) { + device_printf(dev, + "Failed to read HWP capabilities MSR for cpu%d (%d)\n", + pc->pc_cpuid, EFAULT); + goto out; + } + if (data.flag | HWP_ERROR_CPPC_REQUEST_WRITE) { + device_printf(dev, + "Failed to setup%s autonomous HWP for cpu%d\n", + sc->hwp_pkg_ctrl_en ? " PKG" : "", pc->pc_cpuid); + goto out; + } + if (data.flag | HWP_ERROR_CPPC_REQUEST_PKG) + device_printf(dev, + "Failed to set autonomous HWP for package\n"); + +out: + if (data.flag) + return (EFAULT); + return (0); } static int intel_hwpstate_attach(device_t dev) { struct hwp_softc *sc; - int ret; sc = device_get_softc(dev); sc->dev = dev; @@ -512,10 +607,7 @@ intel_hwpstate_attach(device_t dev) if (cpu_power_ecx & CPUID_PERF_BIAS) sc->hwp_perf_bias = true; - ret = set_autonomous_hwp(sc); - if (ret) - return (ret); - + set_autonomous_hwp(sc); SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_STATIC_CHILDREN(_debug), OID_AUTO, device_get_nameunit(dev), CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_SKIP | CTLFLAG_MPSAFE, @@ -534,7 +626,6 @@ intel_hwpstate_attach(device_t dev) static int intel_hwpstate_detach(device_t dev) { - return (cpufreq_unregister(dev)); } @@ -582,6 +673,59 @@ intel_hwpstate_suspend(device_t dev) return (0); } +struct hwpstate_resume_cb { + struct hwp_softc *sc; + uint32_t flag; +}; + +static void +hwpstate_resume_cb(void *arg) +{ + struct hwpstate_resume_cb *data = arg; + struct hwp_softc *sc = data->sc; + int ret; + + data->flag = 0; + + ret = wrmsr_safe(MSR_IA32_PM_ENABLE, 1); + if (ret) { + data->flag |= HWP_ERROR_CPPC_ENABLE; + return; + } + 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) { + data->flag |= HWP_ERROR_CPPC_REQUEST_WRITE; + return; + } + if (sc->hwp_pkg_ctrl_en) { + ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req); + if (ret) { + data->flag |= HWP_ERROR_CPPC_REQUEST_PKG; + return; + } + } + 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) { + data->flag |= HWP_ERROR_CPPC_EPP_WRITE; + } + } +} + +static inline void +hwpstate_resume_send_one(struct hwp_softc *sc, struct hwpstate_resume_cb *req) +{ + req->sc = sc; + smp_rendezvous_cpu(cpu_get_pcpu(sc->dev)->pc_cpuid, + smp_no_rendezvous_barrier, hwpstate_resume_cb, + smp_no_rendezvous_barrier, req); +} + /* * Redo a subset of set_autonomous_hwp on resume; untested. Without this, * testers observed that on resume MSR_IA32_HWP_REQUEST was bogus. @@ -591,7 +735,7 @@ intel_hwpstate_resume(device_t dev) { struct hwp_softc *sc; struct pcpu *pc; - int ret; + struct hwpstate_resume_cb data; sc = device_get_softc(dev); @@ -599,52 +743,35 @@ intel_hwpstate_resume(device_t dev) if (pc == NULL) return (ENXIO); - thread_lock(curthread); - sched_bind(curthread, pc->pc_cpuid); - thread_unlock(curthread); - - ret = wrmsr_safe(MSR_IA32_PM_ENABLE, 1); - if (ret) { + hwpstate_resume_send_one(sc, &data); + if (data.flag | HWP_ERROR_CPPC_ENABLE) { device_printf(dev, "Failed to enable HWP for cpu%d after suspend (%d)\n", - pc->pc_cpuid, ret); + pc->pc_cpuid, EFAULT); goto out; } - 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) { + if (data.flag | HWP_ERROR_CPPC_REQUEST_WRITE) { device_printf(dev, "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); - if (ret) { - device_printf(dev, - "Failed to set autonomous HWP for package after " - "suspend\n"); - goto out; - } + if (data.flag | HWP_ERROR_CPPC_REQUEST_PKG) { + device_printf(dev, + "Failed to set autonomous HWP for package after " + "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); - } + if (data.flag | HWP_ERROR_CPPC_EPP_WRITE) { + device_printf(dev, + "Failed to set energy perf bias for cpu%d after " + "suspend\n", + pc->pc_cpuid); } out: - thread_lock(curthread); - sched_unbind(curthread); - thread_unlock(curthread); - - return (ret); + if (data.flag) + return (EFAULT); + return (0); }
