Page MenuHomeFreeBSD

D40158.id.diff
No OneTemporary

D40158.id.diff

diff --git a/sys/x86/cpufreq/hwpstate_amd.c b/sys/x86/cpufreq/hwpstate_amd.c
--- a/sys/x86/cpufreq/hwpstate_amd.c
+++ b/sys/x86/cpufreq/hwpstate_amd.c
@@ -123,6 +123,7 @@
static int hwpstate_features(driver_t *driver, u_int *features);
static int hwpstate_get_info_from_acpi_perf(device_t dev, device_t perf_dev);
static int hwpstate_get_info_from_msr(device_t dev);
+static void hwpstate_override_msr(device_t dev);
static int hwpstate_goto_pstate(device_t dev, int pstate_id);
static int hwpstate_verbose;
@@ -144,6 +145,11 @@
&hwpstate_prefer_msr, 0,
"If enabled (1), use MSR instead of acpi_perf for P-state information");
+static char hwpstate_override_pstatecfgmsr[8 * sizeof("0x8000000049120890")];
+SYSCTL_STRING(_debug, OID_AUTO, hwpstate_override_pstatecfgmsr, CTLFLAG_RWTUN,
+ hwpstate_override_pstatecfgmsr, sizeof(hwpstate_override_pstatecfgmsr),
+ "Allows overriding PStateDef, up to 8 hexadecimals");
+
static device_method_t hwpstate_methods[] = {
/* Device interface */
DEVMETHOD(device_identify, hwpstate_identify),
@@ -181,7 +187,7 @@
{
sbintime_t sbt;
uint64_t msr;
- int cpu, i, j, limit;
+ int i, j, limit;
if (hwpstate_pstate_limit) {
/* get the current pstate limit */
@@ -194,40 +200,25 @@
}
}
- 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.
*/
- 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, i);
- /* Go To Px-state */
- wrmsr(MSR_AMD_10H_11H_CONTROL, id);
- }
+ HWPSTATE_DEBUG(dev, "setting P%d-state\n", id);
+ x86_msr_op(MSR_AMD_10H_11H_CONTROL, MSR_OP_RENDEZVOUS_ALL | MSR_OP_WRITE,
+ id, NULL);
/*
* 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);
+ /* get the result. to assure msr==id */
+ x86_msr_op(MSR_AMD_10H_11H_STATUS,
+ MSR_OP_RENDEZVOUS_ONE | MSR_OP_READ | MSR_OP_CPUID(i),
+ 0, &msr);
if (msr == id)
break;
sbt = SBT_1MS / 10;
@@ -413,6 +404,9 @@
}
}
+ if (strlen(&hwpstate_override_pstatecfgmsr[0]) > 0)
+ hwpstate_override_msr(dev);
+
/*
* If we cannot get info from acpi_perf,
* Let's get info from MSRs.
@@ -433,6 +427,37 @@
return (cpufreq_register(dev));
}
+static void
+hwpstate_override_msr(device_t dev)
+{
+ char temp[sizeof(hwpstate_override_pstatecfgmsr)];
+ char *token, *next;
+ uint64_t msr[8];
+ int nvalid, i;
+
+ memcpy(&temp[0], &hwpstate_override_pstatecfgmsr[0], sizeof(temp));
+ next = &temp[0];
+ token = strsep(&next, " ");
+ /* Ignore PStateCurLim here, sysadmin knows best. */
+ for (nvalid = 0; (nvalid < 8) && (token != NULL); ) {
+ if (sscanf(token, "0x%lx", &msr[nvalid]) == 1) {
+ HWPSTATE_DEBUG(dev, "Overriding P%d-state with 0x%lx.\n",
+ nvalid, msr[nvalid]);
+ ++nvalid;
+ } else {
+ HWPSTATE_DEBUG(dev,
+ "P%d-state MSR override value not parsable: \"%s\"\n",
+ nvalid, token);
+ break;
+ }
+ token = strsep(&next, " ");
+ }
+
+ for (i = 0; i < nvalid; ++i)
+ x86_msr_op(MSR_AMD_10H_11H_CONFIG + i,
+ MSR_OP_RENDEZVOUS_ALL | MSR_OP_WRITE, msr[i], NULL);
+}
+
static int
hwpstate_get_info_from_msr(device_t dev)
{
@@ -449,6 +474,7 @@
hwpstate_set = sc->hwpstate_settings;
for (i = 0; i < sc->cfnum; i++) {
msr = rdmsr(MSR_AMD_10H_11H_CONFIG + i);
+ HWPSTATE_DEBUG(dev, "PStateDef[%d]: 0x%lx\n", i, msr);
if ((msr & ((uint64_t)1 << 63)) == 0) {
HWPSTATE_DEBUG(dev, "msr is not valid.\n");
return (ENXIO);

File Metadata

Mime Type
text/plain
Expires
Thu, May 21, 6:51 PM (17 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33366425
Default Alt Text
D40158.id.diff (3 KB)

Event Timeline