Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F156915371
D35704.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D35704.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D35704: Patch acpi_thermal to work on CPUs with independent frequency control.
Attached
Detach File
Event Timeline
Log In to Comment