svn commit: r326638 - stable/10/sys/x86/cpufreq
Jung-uk Kim
jkim at FreeBSD.org
Wed Dec 6 21:40:26 UTC 2017
Author: jkim
Date: Wed Dec 6 21:40:24 2017
New Revision: 326638
URL: https://svnweb.freebsd.org/changeset/base/326638
Log:
MFC: r267961, r309361, r322710, r323286, r326378, r326383, r326407
Sync. hwpstate with head.
r267961 (hselasky, partial):
Remove a redundant TUNABLE statement.
r309361 (danfe):
- Mention mismatching numbers in MSR vs. ACPI _PSS count warning.
- Rephrase unsupported AMD CPUs message and wrap as an overly long line.
- Improve readability when reporting resulted P-state transition (debug).
r322710, r323286 (cem):
- Add support for family 17h pstate info from MSRs.
- Yield CPU awaiting frequency change.
r326378, r326383, r326407:
- Fix some style(9) nits.
- Add a tunable "debug.hwpstate_verify" to check P-state after changing it
and turn it off by default.
Modified:
stable/10/sys/x86/cpufreq/hwpstate.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/x86/cpufreq/hwpstate.c
==============================================================================
--- stable/10/sys/x86/cpufreq/hwpstate.c Wed Dec 6 21:39:01 2017 (r326637)
+++ stable/10/sys/x86/cpufreq/hwpstate.c Wed Dec 6 21:40:24 2017 (r326638)
@@ -83,11 +83,15 @@ __FBSDID("$FreeBSD$");
#define AMD_10H_11H_CUR_DID(msr) (((msr) >> 6) & 0x07)
#define AMD_10H_11H_CUR_FID(msr) ((msr) & 0x3F)
+#define AMD_17H_CUR_VID(msr) (((msr) >> 14) & 0xFF)
+#define AMD_17H_CUR_DID(msr) (((msr) >> 8) & 0x3F)
+#define AMD_17H_CUR_FID(msr) ((msr) & 0xFF)
+
#define HWPSTATE_DEBUG(dev, msg...) \
- do{ \
- if(hwpstate_verbose) \
+ do { \
+ if (hwpstate_verbose) \
device_printf(dev, msg); \
- }while(0)
+ } while (0)
struct hwpstate_setting {
int freq; /* CPU clock in Mhz or 100ths of a percent. */
@@ -117,11 +121,14 @@ static int hwpstate_get_info_from_acpi_perf(device_t d
static int hwpstate_get_info_from_msr(device_t dev);
static int hwpstate_goto_pstate(device_t dev, int pstate_id);
-static int hwpstate_verbose = 0;
-SYSCTL_INT(_debug, OID_AUTO, hwpstate_verbose, CTLFLAG_RW | CTLFLAG_TUN,
- &hwpstate_verbose, 0, "Debug hwpstate");
-TUNABLE_INT("debug.hwpstate_verbose", &hwpstate_verbose);
+static int hwpstate_verbose;
+SYSCTL_INT(_debug, OID_AUTO, hwpstate_verbose, CTLFLAG_RWTUN,
+ &hwpstate_verbose, 0, "Debug hwpstate");
+static int hwpstate_verify;
+SYSCTL_INT(_debug, OID_AUTO, hwpstate_verify, CTLFLAG_RWTUN,
+ &hwpstate_verify, 0, "Verify P-state after setting");
+
static device_method_t hwpstate_methods[] = {
/* Device interface */
DEVMETHOD(device_identify, hwpstate_identify),
@@ -155,61 +162,69 @@ DRIVER_MODULE(hwpstate, cpu, hwpstate_driver, hwpstate
* Go to Px-state on all cpus considering the limit.
*/
static int
-hwpstate_goto_pstate(device_t dev, int pstate)
+hwpstate_goto_pstate(device_t dev, int id)
{
- int i;
+ sbintime_t sbt;
uint64_t msr;
- int j;
- int limit;
- int id = pstate;
- int error;
-
+ int cpu, i, j, limit;
+
/* get the current pstate limit */
msr = rdmsr(MSR_AMD_10H_11H_LIMIT);
limit = AMD_10H_11H_GET_PSTATE_LIMIT(msr);
- if(limit > id)
+ if (limit > id)
id = limit;
+ cpu = curcpu;
+ HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", id, cpu);
+ /* Go To Px-state */
+ wrmsr(MSR_AMD_10H_11H_CONTROL, id);
+
/*
* We are going to the same Px-state on all cpus.
* Probably should take _PSD into account.
*/
- error = 0;
CPU_FOREACH(i) {
+ if (i == cpu)
+ continue;
+
/* Bind to each cpu. */
thread_lock(curthread);
sched_bind(curthread, i);
thread_unlock(curthread);
- HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n",
- id, PCPU_GET(cpuid));
+ HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", id, i);
/* Go To Px-state */
wrmsr(MSR_AMD_10H_11H_CONTROL, id);
}
- CPU_FOREACH(i) {
- /* Bind to each cpu. */
- thread_lock(curthread);
- sched_bind(curthread, i);
- thread_unlock(curthread);
- /* wait loop (100*100 usec is enough ?) */
- for(j = 0; j < 100; j++){
- /* get the result. not assure msr=id */
- msr = rdmsr(MSR_AMD_10H_11H_STATUS);
- if(msr == id){
- break;
+
+ /*
+ * Verify whether each core is in the requested P-state.
+ */
+ if (hwpstate_verify) {
+ CPU_FOREACH(i) {
+ thread_lock(curthread);
+ sched_bind(curthread, i);
+ thread_unlock(curthread);
+ /* wait loop (100*100 usec is enough ?) */
+ for (j = 0; j < 100; j++) {
+ /* get the result. not assure msr=id */
+ msr = rdmsr(MSR_AMD_10H_11H_STATUS);
+ if (msr == id)
+ break;
+ sbt = SBT_1MS / 10;
+ tsleep_sbt(dev, PZERO, "pstate_goto", sbt,
+ sbt >> tc_precexp, 0);
}
- DELAY(100);
+ HWPSTATE_DEBUG(dev, "result: P%d-state on cpu%d\n",
+ (int)msr, i);
+ if (msr != id) {
+ HWPSTATE_DEBUG(dev,
+ "error: loop is not enough.\n");
+ return (ENXIO);
+ }
}
- HWPSTATE_DEBUG(dev, "result P%d-state on cpu%d\n",
- (int)msr, PCPU_GET(cpuid));
- if (msr != id) {
- HWPSTATE_DEBUG(dev, "error: loop is not enough.\n");
- error = ENXIO;
- }
}
- thread_lock(curthread);
- sched_unbind(curthread);
- thread_unlock(curthread);
- return (error);
+
+ return (0);
}
static int
@@ -243,7 +258,7 @@ hwpstate_get(device_t dev, struct cf_setting *cf)
if (cf == NULL)
return (EINVAL);
msr = rdmsr(MSR_AMD_10H_11H_STATUS);
- if(msr >= sc->cfnum)
+ if (msr >= sc->cfnum)
return (EINVAL);
set = sc->hwpstate_settings[msr];
@@ -368,7 +383,8 @@ hwpstate_probe(device_t dev)
*/
msr = rdmsr(MSR_AMD_10H_11H_LIMIT);
if (sc->cfnum != 1 + AMD_10H_11H_GET_PSTATE_MAX_VAL(msr)) {
- HWPSTATE_DEBUG(dev, "msr and acpi _PSS count mismatch.\n");
+ HWPSTATE_DEBUG(dev, "MSR (%jd) and ACPI _PSS (%d)"
+ " count mismatch\n", (intmax_t)msr, sc->cfnum);
error = TRUE;
}
}
@@ -417,7 +433,7 @@ hwpstate_get_info_from_msr(device_t dev)
fid = AMD_10H_11H_CUR_FID(msr);
/* Convert fid/did to frequency. */
- switch(family) {
+ switch (family) {
case 0x11:
hwpstate_set[i].freq = (100 * (fid + 0x08)) >> did;
break;
@@ -427,8 +443,18 @@ hwpstate_get_info_from_msr(device_t dev)
case 0x16:
hwpstate_set[i].freq = (100 * (fid + 0x10)) >> did;
break;
+ case 0x17:
+ did = AMD_17H_CUR_DID(msr);
+ if (did == 0) {
+ HWPSTATE_DEBUG(dev, "unexpected did: 0\n");
+ did = 1;
+ }
+ fid = AMD_17H_CUR_FID(msr);
+ hwpstate_set[i].freq = (200 * fid) / did;
+ break;
default:
- HWPSTATE_DEBUG(dev, "get_info_from_msr: AMD family 0x%02x CPU's are not implemented yet. sorry.\n", family);
+ HWPSTATE_DEBUG(dev, "get_info_from_msr: AMD family"
+ " 0x%02x CPUs are not supported yet\n", family);
return (ENXIO);
}
hwpstate_set[i].pstate_id = i;
More information about the svn-src-all
mailing list