svn commit: r239807 - stable/9/sys/dev/acpica
Andriy Gapon
avg at FreeBSD.org
Wed Aug 29 08:14:17 UTC 2012
Author: avg
Date: Wed Aug 29 08:14:16 2012
New Revision: 239807
URL: http://svn.freebsd.org/changeset/base/239807
Log:
MFC r238418: acpi_cpu: separate a notion of current deepest
allowed+available Cx level from a user-set persistent limit on the said level
Modified:
stable/9/sys/dev/acpica/acpi_cpu.c
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/dev/ (props changed)
Modified: stable/9/sys/dev/acpica/acpi_cpu.c
==============================================================================
--- stable/9/sys/dev/acpica/acpi_cpu.c Wed Aug 29 06:43:28 2012 (r239806)
+++ stable/9/sys/dev/acpica/acpi_cpu.c Wed Aug 29 08:14:16 2012 (r239807)
@@ -89,6 +89,7 @@ struct acpi_cpu_softc {
struct sysctl_ctx_list cpu_sysctl_ctx;
struct sysctl_oid *cpu_sysctl_tree;
int cpu_cx_lowest;
+ int cpu_cx_lowest_lim;
char cpu_cx_supported[64];
int cpu_rid;
};
@@ -138,13 +139,12 @@ static int cpu_quirks; /* Indicate any
/* Runtime state. */
static int cpu_disable_idle; /* Disable entry to idle function */
-static int cpu_cx_count; /* Number of valid Cx states */
/* Values for sysctl. */
static struct sysctl_ctx_list cpu_sysctl_ctx;
static struct sysctl_oid *cpu_sysctl_tree;
static int cpu_cx_generic;
-static int cpu_cx_lowest;
+static int cpu_cx_lowest_lim;
static device_t *cpu_devices;
static int cpu_ndevices;
@@ -173,7 +173,7 @@ static void acpi_cpu_idle(void);
static void acpi_cpu_notify(ACPI_HANDLE h, UINT32 notify, void *context);
static int acpi_cpu_quirks(void);
static int acpi_cpu_usage_sysctl(SYSCTL_HANDLER_ARGS);
-static int acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc, int val);
+static int acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc);
static int acpi_cpu_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_cpu_global_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS);
@@ -590,6 +590,7 @@ acpi_cpu_cx_probe(struct acpi_cpu_softc
/* Use initial sleep value of 1 sec. to start with lowest idle state. */
sc->cpu_prev_sleep = 1000000;
sc->cpu_cx_lowest = 0;
+ sc->cpu_cx_lowest_lim = 0;
/*
* Check for the ACPI 2.0 _CST sleep states object. If we can't find
@@ -816,7 +817,6 @@ acpi_cpu_startup(void *arg)
*/
acpi_cpu_quirks();
- cpu_cx_count = 0;
if (cpu_cx_generic) {
/*
* We are using generic Cx mode, probe for available Cx states
@@ -825,24 +825,10 @@ acpi_cpu_startup(void *arg)
for (i = 0; i < cpu_ndevices; i++) {
sc = device_get_softc(cpu_devices[i]);
acpi_cpu_generic_cx_probe(sc);
- if (sc->cpu_cx_count > cpu_cx_count)
- cpu_cx_count = sc->cpu_cx_count;
- }
-
- /*
- * Find the highest Cx state common to all CPUs
- * in the system, taking quirks into account.
- */
- for (i = 0; i < cpu_ndevices; i++) {
- sc = device_get_softc(cpu_devices[i]);
- if (sc->cpu_cx_count < cpu_cx_count)
- cpu_cx_count = sc->cpu_cx_count;
}
} else {
/*
* We are using _CST mode, remove C3 state if necessary.
- * Update the largest Cx state supported in the global cpu_cx_count.
- * It will be used in the global Cx sysctl handler.
* As we now know for sure that we will be using _CST mode
* install our notify handler.
*/
@@ -851,8 +837,6 @@ acpi_cpu_startup(void *arg)
if (cpu_quirks & CPU_QUIRK_NO_C3) {
sc->cpu_cx_count = sc->cpu_non_c3 + 1;
}
- if (sc->cpu_cx_count > cpu_cx_count)
- cpu_cx_count = sc->cpu_cx_count;
AcpiInstallNotifyHandler(sc->cpu_handle, ACPI_DEVICE_NOTIFY,
acpi_cpu_notify, sc);
}
@@ -871,7 +855,7 @@ acpi_cpu_startup(void *arg)
"Global lowest Cx sleep state to use");
/* Take over idling from cpu_idle_default(). */
- cpu_cx_lowest = 0;
+ cpu_cx_lowest_lim = 0;
cpu_disable_idle = FALSE;
cpu_idle_hook = acpi_cpu_idle;
}
@@ -1062,8 +1046,6 @@ static void
acpi_cpu_notify(ACPI_HANDLE h, UINT32 notify, void *context)
{
struct acpi_cpu_softc *sc = (struct acpi_cpu_softc *)context;
- struct acpi_cpu_softc *isc;
- int i;
if (notify != ACPI_NOTIFY_CX_STATES)
return;
@@ -1072,16 +1054,8 @@ acpi_cpu_notify(ACPI_HANDLE h, UINT32 no
acpi_cpu_cx_cst(sc);
acpi_cpu_cx_list(sc);
- /* Update the new lowest useable Cx state for all CPUs. */
ACPI_SERIAL_BEGIN(cpu);
- cpu_cx_count = 0;
- for (i = 0; i < cpu_ndevices; i++) {
- isc = device_get_softc(cpu_devices[i]);
- if (isc->cpu_cx_count > cpu_cx_count)
- cpu_cx_count = isc->cpu_cx_count;
- }
- if (sc->cpu_cx_lowest < cpu_cx_lowest)
- acpi_cpu_set_cx_lowest(sc, min(cpu_cx_lowest, sc->cpu_cx_count - 1));
+ acpi_cpu_set_cx_lowest(sc);
ACPI_SERIAL_END(cpu);
}
@@ -1209,12 +1183,12 @@ acpi_cpu_usage_sysctl(SYSCTL_HANDLER_ARG
}
static int
-acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc, int val)
+acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc)
{
int i;
ACPI_SERIAL_ASSERT(cpu);
- sc->cpu_cx_lowest = val;
+ sc->cpu_cx_lowest = min(sc->cpu_cx_lowest_lim, sc->cpu_cx_count - 1);
/* If not disabling, cache the new lowest non-C3 state. */
sc->cpu_non_c3 = 0;
@@ -1238,18 +1212,23 @@ acpi_cpu_cx_lowest_sysctl(SYSCTL_HANDLER
int val, error;
sc = (struct acpi_cpu_softc *) arg1;
- snprintf(state, sizeof(state), "C%d", sc->cpu_cx_lowest + 1);
+ snprintf(state, sizeof(state), "C%d", sc->cpu_cx_lowest_lim + 1);
error = sysctl_handle_string(oidp, state, sizeof(state), req);
if (error != 0 || req->newptr == NULL)
return (error);
if (strlen(state) < 2 || toupper(state[0]) != 'C')
return (EINVAL);
- val = (int) strtol(state + 1, NULL, 10) - 1;
- if (val < 0 || val > sc->cpu_cx_count - 1)
- return (EINVAL);
+ if (strcasecmp(state, "Cmax") == 0)
+ val = MAX_CX_STATES;
+ else {
+ val = (int) strtol(state + 1, NULL, 10);
+ if (val < 1 || val > MAX_CX_STATES)
+ return (EINVAL);
+ }
ACPI_SERIAL_BEGIN(cpu);
- acpi_cpu_set_cx_lowest(sc, val);
+ sc->cpu_cx_lowest_lim = val - 1;
+ acpi_cpu_set_cx_lowest(sc);
ACPI_SERIAL_END(cpu);
return (0);
@@ -1262,22 +1241,27 @@ acpi_cpu_global_cx_lowest_sysctl(SYSCTL_
char state[8];
int val, error, i;
- snprintf(state, sizeof(state), "C%d", cpu_cx_lowest + 1);
+ snprintf(state, sizeof(state), "C%d", cpu_cx_lowest_lim + 1);
error = sysctl_handle_string(oidp, state, sizeof(state), req);
if (error != 0 || req->newptr == NULL)
return (error);
if (strlen(state) < 2 || toupper(state[0]) != 'C')
return (EINVAL);
- val = (int) strtol(state + 1, NULL, 10) - 1;
- if (val < 0 || val > cpu_cx_count - 1)
- return (EINVAL);
- cpu_cx_lowest = val;
+ if (strcasecmp(state, "Cmax") == 0)
+ val = MAX_CX_STATES;
+ else {
+ val = (int) strtol(state + 1, NULL, 10);
+ if (val < 1 || val > MAX_CX_STATES)
+ return (EINVAL);
+ }
/* Update the new lowest useable Cx state for all CPUs. */
ACPI_SERIAL_BEGIN(cpu);
+ cpu_cx_lowest_lim = val - 1;
for (i = 0; i < cpu_ndevices; i++) {
sc = device_get_softc(cpu_devices[i]);
- acpi_cpu_set_cx_lowest(sc, min(val, sc->cpu_cx_count - 1));
+ sc->cpu_cx_lowest_lim = cpu_cx_lowest_lim;
+ acpi_cpu_set_cx_lowest(sc);
}
ACPI_SERIAL_END(cpu);
More information about the svn-src-stable
mailing list