Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 20 Mar 2005 23:13:28 -0800
From:      Nate Lawson <nate@root.org>
To:        Kevin Oberman <oberman@es.net>
Cc:        acpi@freebsd.org
Subject:   Re: Issues with powerd
Message-ID:  <423E7418.5060609@root.org>
In-Reply-To: <20050309192938.23DCB5D07@ptavv.es.net>
References:  <20050309192938.23DCB5D07@ptavv.es.net>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------040509050201070607060202
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Kevin Oberman wrote:
> I have finally had a little time to play with powerd and I didn't find
> adaptive mode worked too well for me on my T30 running a Gnome desktop.
> 
> The effect of running powerd was to move the freq in a rapid sawtooth
> dropping quickly to 150 MHz and them jumping back to 1800 and
> repeating. If the CPU was busy, the low point of the sawtooth would be
> elevated to 300or 600, but the basic pattern was constant oscillation.
> 
> I looked at the source and decided that two things were wrong.
> 
> 1. Dropping to half of the initial CPU speed was to a good choice. The
> drop is speed was too quick and it resulted in reducing the number of
> CPU performance levels to a small number instead of the 15 that should
> be available.
> 
> 2. When the CPU got busier, jumping all the way to full speed was
> excessive and would always result in the sawtooth oscillation.
> 
> I modified powerd to increase or decrease cpufreq in single steps instead
> of jumping (in either direction) and lowered DEFAULT_ACTIVE_PERCENT to
> 75. This results in a system that wanders between 150 and 450 when idle
> and climbs to full speed when under load.
> 
> I suspect this is sub-optimal, but I think it's a lot better then the
> current operation. I will try to spend some time tweaking the algorithm
> a bit to see what makes things run best (for my personal idea of "best".
> 
> Ideally, I'd like to see it stay constant an an idle or constantly
> loaded system and I suspect that I will need to add hysteresis to get
> there. 

Please try the attached patch.  It delays IDLE_DECAY_COUNT poll cycles 
before starting the descent to slowest speed.  The current value of 4 
waits a second.  This should slow the "sawtooth" issue.  Once it starts 
the decay, it drops one setting per poll interval.  It still jumps 
immediately to full speed once below 80% idle but I think this will 
solve your issue.  If not, try tweaking IDLE_DECAY_COUNT.

-- 
Nate

--------------040509050201070607060202
Content-Type: text/plain;
 name="powerd.c.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="powerd.c.diff"

Index: powerd.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/powerd/powerd.c,v
retrieving revision 1.4
diff -u -r1.4 powerd.c
--- powerd.c	27 Feb 2005 01:58:49 -0000	1.4
+++ powerd.c	21 Mar 2005 07:10:16 -0000
@@ -46,6 +46,7 @@
 #define DEFAULT_ACTIVE_PERCENT	80
 #define DEFAULT_IDLE_PERCENT	90
 #define DEFAULT_POLL_INTERVAL	500
+#define IDLE_DECAY_COUNT	4
 
 enum modes_t {
 	MODE_MIN,
@@ -237,7 +238,7 @@
 main(int argc, char * argv[])
 {
 	long idle, total;
-	int curfreq, *freqs, i, numfreqs;
+	int curfreq, *freqs, i, idle_count, numfreqs;
 	int ch, mode_ac, mode_battery, mode_none, acline, mode, vflag;
 	size_t len;
 
@@ -246,7 +247,7 @@
 	cpu_running_mark = DEFAULT_ACTIVE_PERCENT;
 	cpu_idle_mark = DEFAULT_IDLE_PERCENT;
 	poll_ival = DEFAULT_POLL_INTERVAL;
-	vflag = 0;
+	vflag = idle_count = 0;
 	apm_fd = -1;
 
 	while ((ch = getopt(argc, argv, "a:b:i:n:p:r:v")) != EOF)
@@ -380,11 +381,13 @@
 		/*
 		 * If we're idle less than the active mark, jump the CPU to
 		 * its fastest speed if we're not there yet.  If we're idle
-		 * more than the idle mark, drop down to the first setting
-		 * that is half the current speed (exponential backoff).
+		 * more than the idle mark, drop down to the next lower
+		 * setting after a short delay to be sure we're really idle.
 		 */
-		if (idle < (total * cpu_running_mark) / 100 &&
-		    curfreq < freqs[0]) {
+		if (idle < (total * cpu_running_mark) / 100) {
+			idle_count = 0;
+			if (curfreq == freqs[0])
+				continue;
 			if (vflag) {
 				printf("idle time < %d%%, increasing clock"
 				    " speed from %d MHz to %d MHz\n",
@@ -395,8 +398,11 @@
 				    freqs[0]);
 		} else if (idle > (total * cpu_idle_mark) / 100 &&
 		    curfreq > freqs[numfreqs - 1]) {
+			if (++idle_count < IDLE_DECAY_COUNT)
+				continue;
+
 			for (i = 0; i < numfreqs - 1; i++) {
-				if (freqs[i] <= curfreq / 2)
+				if (freqs[i] < curfreq)
 					break;
 			}
 			if (vflag) {

--------------040509050201070607060202--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?423E7418.5060609>