Page MenuHomeFreeBSD

D35704.diff
No OneTemporary

D35704.diff

Index: libexec/rc/rc.conf
===================================================================
--- libexec/rc/rc.conf
+++ libexec/rc/rc.conf
@@ -712,8 +712,12 @@
devfs_load_rulesets="YES" # Enable to always load the default rulesets
performance_cx_lowest="NONE" # Online CPU idle state
performance_cpu_freq="NONE" # Online CPU frequency
+performance_tz0_active="NONE" # Online forced active cooling zone
+performance_tz0_PSV="NONE" # Online passive cooling threshold
economy_cx_lowest="Cmax" # Offline CPU idle state
economy_cpu_freq="NONE" # Offline CPU frequency
+economy_tz0_active="NONE" # Offline forced active cooling zone
+economy_tz0_PSV="NONE" # Offline passive cooling threshold
virecover_enable="YES" # Perform housekeeping for the vi(1) editor
ugidfw_enable="NO" # Load mac_bsdextended(4) rules on boot
bsdextended_script="/etc/rc.bsdextended" # Default mac_bsdextended(4)
Index: libexec/rc/rc.d/power_profile
===================================================================
--- libexec/rc/rc.d/power_profile
+++ libexec/rc/rc.d/power_profile
@@ -80,6 +80,14 @@
esac
# Set the various sysctls based on the profile's values.
+node="hw.acpi.thermal.tz0._PSV"
+eval value=\$${profile}_tz0_PSV
+sysctl_set
+
+node="hw.acpi.thermal.tz0.active"
+eval value=\$${profile}_tz0_active
+sysctl_set
+
node="hw.acpi.cpu.cx_lowest"
highest_value="C1"
lowest_value="Cmax"
Index: sys/dev/acpica/acpi_thermal.c
===================================================================
--- sys/dev/acpica/acpi_thermal.c
+++ sys/dev/acpica/acpi_thermal.c
@@ -605,7 +605,7 @@
/* XXX (de)activate any passive cooling that may be required. */
/*
- * If the temperature is at _HOT or _CRT, increment our event count.
+ * If the temperature is at _CR3, _HOT or _CRT, increment our event count.
* If it has occurred enough times, shutdown the system. This is
* needed because some systems will report an invalid high temperature
* for one poll cycle. It is suspected this is due to the embedded
@@ -1023,51 +1023,68 @@
static int
acpi_tz_cpufreq_restore(struct acpi_tz_softc *sc)
{
- device_t dev;
- int error;
+ device_t *devs;
+ int devcount, error, n;
if (!sc->tz_cooling_updated)
return (0);
- if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL)
+
+ if ((error = devclass_get_devices(devclass_find("cpufreq"), &devs, &devcount))) {
+ free(devs, M_TEMP);
return (ENXIO);
+ }
+
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
"temperature %d.%dC: resuming previous clock speed (%d MHz)\n",
TZ_KELVTOC(sc->tz_temperature), sc->tz_cooling_saved_freq);
- error = CPUFREQ_SET(dev, NULL, CPUFREQ_PRIO_KERN);
+ for (n = 0; n < devcount; n++) {
+ if ((error = CPUFREQ_SET(devs[n], NULL, CPUFREQ_PRIO_KERN))) {
+ /*
+ * If you find yourself here: cf_set_method() in kern_cpu.c
+ * requires CPUFREQ_GET() be run before CPUFREQ_SET(), otherwise on
+ * a restore sc->curr_level.total_set.freq = CPUFREQ_VAL_UNKNOWN,
+ * and then if it hasn't been updated the next save/restore will fail.
+ */
+ device_printf(sc->tz_dev, "cpu%d: failed to restore cpufreq priority\n", n);
+ break;
+ }
+ }
if (error == 0)
sc->tz_cooling_updated = FALSE;
+
+ free(devs, M_TEMP);
return (error);
}
static int
acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req)
{
- device_t dev;
+ device_t *devs;
struct cf_level *levels;
- int num_levels, error, freq, desired_freq, perf, i;
+ int num_levels, error, freq, desired_freq, perf, devcount, i, n;
levels = malloc(CPUFREQ_MAX_LEVELS * sizeof(*levels), M_TEMP, M_NOWAIT);
if (levels == NULL)
return (ENOMEM);
/*
- * Find the main device, cpufreq0. We don't yet support independent
- * CPU frequency control on SMP.
+ * Find the main device, cpufreq0. We make plans based upon cpu0, and
+ * change all the cpu frequencies to the same level.
*/
- if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL) {
- error = ENXIO;
+ if ((error = devclass_get_devices(devclass_find("cpufreq"), &devs, &devcount))) {
+ free(devs, M_TEMP);
goto out;
}
- /* Get the current frequency. */
- error = CPUFREQ_GET(dev, &levels[0]);
+ /* Get the current frequency for cpu0. */
+ error = CPUFREQ_GET(devs[0], &levels[0]);
if (error)
goto out;
freq = levels[0].total_set.freq;
- /* Get the current available frequency levels. */
+ /* Get the current available frequency levels for cpu0. */
num_levels = CPUFREQ_MAX_LEVELS;
- error = CPUFREQ_LEVELS(dev, levels, &num_levels);
+ error = CPUFREQ_LEVELS(devs[0], levels, &num_levels);
if (error) {
if (error == E2BIG)
printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n");
@@ -1128,8 +1145,22 @@
TZ_KELVTOC(sc->tz_temperature),
(freq > levels[i].total_set.freq) ? "de" : "in",
freq, levels[i].total_set.freq);
- error = CPUFREQ_SET(dev, &levels[i], CPUFREQ_PRIO_KERN);
- if (error == 0 && !sc->tz_cooling_updated) {
+
+ /* Change all the cpus to the chosen frequency. */
+ for (n = 0; n < devcount; n++) {
+ /* CPUFREQ_SET() fails occasionally without this. */
+ if ((error = CPUFREQ_GET(devs[n], &levels[0])))
+ goto out;
+
+ if ((error = CPUFREQ_LEVELS(devs[n], levels, &num_levels))) {
+ if (error == E2BIG)
+ printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n");
+ goto out;
+ }
+ if ((error = CPUFREQ_SET(devs[n], &levels[i], CPUFREQ_PRIO_KERN)))
+ goto out;
+ }
+ if (!sc->tz_cooling_updated) {
sc->tz_cooling_saved_freq = freq;
sc->tz_cooling_updated = TRUE;
}
@@ -1138,6 +1169,7 @@
out:
if (levels)
free(levels, M_TEMP);
+ free(devs, M_TEMP);
return (error);
}

File Metadata

Mime Type
text/plain
Expires
Mon, May 18, 8:11 AM (3 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33239216
Default Alt Text
D35704.diff (5 KB)

Event Timeline