misc/136354: powerd Support for maxspeed in adaptive modes

Rene Schickbauer cavac at magicbooks.org
Sun Jul 5 16:10:01 UTC 2009


>Number:         136354
>Category:       misc
>Synopsis:       powerd Support for maxspeed in adaptive modes
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 05 16:10:00 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Rene Schickbauer
>Release:        8-current
>Organization:
>Environment:
FreeBSD titan 8.0-CURRENT-200906 FreeBSD 8.0-CURRENT-200906 #1: Tue Jun 30 13:29:40 CEST 2009     root at titan:/usr/obj/usr/src/sys/GENERIC  i386

>Description:
This patch enables users to use the powerd adaptive modes while still maintaining a cooler/less power hungry system by limiting the max. CPU speed powerd can set.

This patch also includes an update to the powerd manpage. I also moved the description of the available modes to a dedicated section to make them easier to find.

I wrote this patch, to limit my EEE PC's power consumption/heat production without having to fall back to minimum performance.  
>How-To-Repeat:
Run an Intel Atom based NetBook with powerd set to "adaptive" and "make buildworld". It gets hot enough to get you burned when held in hand or lap (like when debugging FreeBSD while waiting for the bus).
>Fix:
See attached patch

Patch attached with submission follows:

diff -u powerd.orig/powerd.8 powerd/powerd.8
--- powerd.orig/powerd.8	2009-07-05 16:04:19.000000000 +0200
+++ powerd/powerd.8	2009-07-05 17:18:12.000000000 +0200
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD: src/usr.sbin/powerd/powerd.8,v 1.13 2008/12/24 09:17:30 trhodes Exp $
 .\"
-.Dd December 24, 2008
+.Dd July 5, 2009
 .Dt POWERD 8
 .Os
 .Sh NAME
@@ -33,7 +33,9 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl a Ar mode
+.Op Fl x Ar maxspeed
 .Op Fl b Ar mode
+.Op Fl y Ar maxspeed
 .Op Fl i Ar percent
 .Op Fl n Ar mode
 .Op Fl p Ar ival
@@ -45,22 +47,10 @@
 .Nm
 utility monitors the system state and sets various power control options
 accordingly.
-It offers three modes (maximum, minimum, and adaptive) that can be
-individually selected while on AC power or batteries.
-The modes maximum, minimum, adaptive and hiadaptive may be abbreviated
-max, min, adp, hadp.
-.Pp
-Maximum mode chooses the highest performance values.
-Minimum mode selects the lowest performance values to get the most power
-savings.
-Adaptive mode attempts to strike a balance by degrading performance when
-the system appears idle and increasing it when the system is busy.
-It offers a good balance between a small performance loss for greatly
-increased power savings.
-Hiadaptive mode is alike adaptive mode, but tuned for systems where
-performance and interactivity are more important then power consumption.
-It rises frequency faster, drops slower and keeps twice lower CPU load.
-The default mode is adaptive for battery power and hiadaptive for the rest.
+It offers multiple modes (maximum, minimum, and two adaptive modes) that can be
+individually selected while on AC power or batteries. See
+.Ar MODES
+below for details.
 .Pp
 The
 .Nm
@@ -99,7 +89,57 @@
 Messages about power changes will be printed to stdout and
 .Nm
 will operate in the foreground.
+.It Fl x Ar mode
+Selects the
+.Ar maxspeed
+in Mhz for adaptive modes to use while on AC power.
+.It Fl y Ar mode
+Selects the
+.Ar maxspeed
+in Mhz for adaptive modes to use while on battery power.
 .El
+.Sh MODES
+The following
+.Ar mode
+flags are currently implemented:
+.Pp
+.Ar max
+or
+.Ar maximum
+mode chooses the highest performance values.
+.Pp
+.Ar min
+or
+.Ar minimum
+mode selects the lowest performance values to get the most power
+savings.
+.Pp
+.Ar adp
+or
+.Ar adaptive
+mode attempts to strike a balance by degrading performance when
+the system appears idle and increasing it when the system is busy.
+It offers a good balance between a small performance loss for greatly
+increased power savings.
+.Pp
+.Ar hadp
+or
+.Ar hiadaptive
+mode is alike adaptive mode, but tuned for systems where
+performance and interactivity are more important then power consumption.
+It rises frequency faster, drops slower and keeps twice lower CPU load.
+.Pp
+For both adaptive modes, it is possible to set
+.Ar maxspeed
+to lower power consumption by limiting the dynamic range
+.Nm
+uses.
+.Pp
+The default mode is
+.Ar adaptive
+for battery power and
+.Ar hiadaptive
+for the rest.
 .Sh SEE ALSO
 .Xr acpi 4 ,
 .Xr apm 4 ,
@@ -121,6 +161,8 @@
 then updated it for
 .Xr cpufreq 4 ,
 added features, and wrote this manual page.
+.An Rene Schickbauer
+added speed limiting and rewrote parts of this manual page.
 .Sh BUGS
 The
 .Nm
diff -u powerd.orig/powerd.c powerd/powerd.c
--- powerd.orig/powerd.c	2009-07-05 16:04:19.000000000 +0200
+++ powerd/powerd.c	2009-07-05 17:22:35.000000000 +0200
@@ -118,6 +118,9 @@
 #endif
 static int	devd_pipe = -1;
 
+static int  maxspeed_ac = 0;
+static int  maxspeed_battery = 0;
+
 #define DEVD_RETRY_INTERVAL 60 /* seconds */
 static struct timeval tried_devd;
 
@@ -418,7 +421,7 @@
 {
 
 	fprintf(stderr,
-"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-P pidfile]\n");
+"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-P pidfile] [-x maxspeed] [-y maxspeed]\n");
 	exit(1);
 }
 
@@ -431,13 +434,16 @@
 	struct pidfh *pfh = NULL;
 	const char *pidfile = NULL;
 	int freq, curfreq, initfreq, *freqs, i, j, *mwatts, numfreqs, load;
-	int ch, mode, mode_ac, mode_battery, mode_none;
+	int ch, mode, mode_ac, mode_battery, mode_none, maxspeed;
 	uint64_t mjoules_used;
 	size_t len;
 
 	/* Default mode for all AC states is adaptive. */
 	mode_ac = mode_none = MODE_HIADAPTIVE;
 	mode_battery = MODE_ADAPTIVE;
+    maxspeed_ac = 0;
+    maxspeed_battery = 0;
+    maxspeed = 0;
 	cpu_running_mark = DEFAULT_ACTIVE_PERCENT;
 	cpu_idle_mark = DEFAULT_IDLE_PERCENT;
 	poll_ival = DEFAULT_POLL_INTERVAL;
@@ -448,7 +454,7 @@
 	if (geteuid() != 0)
 		errx(1, "must be root to run");
 
-	while ((ch = getopt(argc, argv, "a:b:i:n:p:P:r:v")) != -1)
+	while ((ch = getopt(argc, argv, "a:b:x:y:i:n:p:P:r:v")) != -1)
 		switch (ch) {
 		case 'a':
 			parse_mode(optarg, &mode_ac, ch);
@@ -464,6 +470,22 @@
 				usage();
 			}
 			break;
+        case 'x':
+            maxspeed_ac = atoi(optarg);
+			if (maxspeed_ac <= 0) {
+				warnx("%d is not a valid CPU speed",
+				    maxspeed_ac);
+				usage();
+			}
+            break;
+        case 'y':
+            maxspeed_battery = atoi(optarg);
+			if (maxspeed_battery <= 0) {
+				warnx("%d is not a valid CPU speed",
+				    maxspeed_battery);
+				usage();
+			}
+            break;
 		case 'n':
 			parse_mode(optarg, &mode_none, ch);
 			break;
@@ -574,12 +596,15 @@
 		switch (acline_status) {
 		case SRC_AC:
 			mode = mode_ac;
+            maxspeed = maxspeed_ac;
 			break;
 		case SRC_BATTERY:
 			mode = mode_battery;
+            maxspeed = maxspeed_battery;
 			break;
 		case SRC_UNKNOWN:
 			mode = mode_none;
+            maxspeed = 0;
 			break;
 		default:
 			errx(1, "invalid AC line status %d", acline_status);
@@ -647,6 +672,7 @@
 					freq *= 2;
 				else
 					freq = freq * load / cpu_running_mark;
+                
 				if (freq > freqs[0])
 					freq = freqs[0];
 			} else if (load < cpu_idle_mark &&
@@ -657,6 +683,11 @@
 				if (freq < freqs[numfreqs - 1])
 					freq = freqs[numfreqs - 1];
 			}
+            if(maxspeed > 0 && freq > maxspeed) {
+                if(vflag)
+                    printf("Limiting calculated freq (%d Mhz) to %d Mhz\n", freq, maxspeed);
+                freq = maxspeed;
+            }
 		} else { /* MODE_HIADAPTIVE */
 			if (load > cpu_running_mark / 2) {
 				if (load > 95 || load > cpu_running_mark)
@@ -673,6 +704,11 @@
 				if (freq < freqs[numfreqs - 1])
 					freq = freqs[numfreqs - 1];
 			}
+            if(maxspeed > 0 && freq > maxspeed) {
+                if(vflag)
+                    printf("Limiting calculated freq (%d Mhz) to %d Mhz\n", freq, maxspeed);
+                freq = maxspeed;
+            }
 		}
 		if (vflag) {
 		    printf("load %3d%%, current freq %4d MHz (%2d), wanted freq %4d MHz\n",


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list