Date: Wed, 29 Aug 2012 08:34:16 +0000 (UTC) From: Andriy Gapon <avg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r239808 - stable/8/sys/dev/acpica Message-ID: <201208290834.q7T8YGFl012651@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avg Date: Wed Aug 29 08:34:16 2012 New Revision: 239808 URL: http://svn.freebsd.org/changeset/base/239808 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/8/sys/dev/acpica/acpi_cpu.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/dev/ (props changed) Modified: stable/8/sys/dev/acpica/acpi_cpu.c ============================================================================== --- stable/8/sys/dev/acpica/acpi_cpu.c Wed Aug 29 08:14:16 2012 (r239807) +++ stable/8/sys/dev/acpica/acpi_cpu.c Wed Aug 29 08:34:16 2012 (r239808) @@ -86,6 +86,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; }; @@ -135,13 +136,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; @@ -170,7 +170,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); @@ -579,6 +579,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 @@ -783,7 +784,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 @@ -792,24 +792,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. */ @@ -818,8 +804,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); } @@ -838,7 +822,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; } @@ -1021,8 +1005,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; @@ -1031,16 +1013,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); } @@ -1168,12 +1142,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; @@ -1197,18 +1171,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); @@ -1221,22 +1200,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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208290834.q7T8YGFl012651>