From olli@secnetix.de  Tue Aug 14 11:30:07 2007
Return-Path: <olli@secnetix.de>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 74FDD16A417
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 14 Aug 2007 11:30:07 +0000 (UTC)
	(envelope-from olli@secnetix.de)
Received: from pluto.secnetix.de (pluto.secnetix.de [88.198.44.136])
	by mx1.freebsd.org (Postfix) with ESMTP id 210B213C48A
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 14 Aug 2007 11:30:06 +0000 (UTC)
	(envelope-from olli@secnetix.de)
Received: from pluto.secnetix.de (localhost.secnetix.de [127.0.0.1])
	by pluto.secnetix.de (8.14.1/8.14.1) with ESMTP id l7EB6S5o085622;
	Tue, 14 Aug 2007 13:06:28 +0200 (CEST)
	(envelope-from oliver.fromme@secnetix.de)
Received: (from olli@localhost)
	by pluto.secnetix.de (8.14.1/8.14.1/Submit) id l7EB6SVj085621;
	Tue, 14 Aug 2007 13:06:28 +0200 (CEST)
	(envelope-from olli)
Message-Id: <200708141106.l7EB6SVj085621@pluto.secnetix.de>
Date: Tue, 14 Aug 2007 13:06:28 +0200 (CEST)
From: Oliver Fromme <olli@secnetix.de>
Reply-To: Oliver Fromme <olli@secnetix.de>
To: FreeBSD-gnats-submit@freebsd.org
Cc: Oliver Fromme <olli@secnetix.de>
Subject: [PATCH] Add step down/up options to powerd(8)
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         115513
>Category:       bin
>Synopsis:       [patch] [request] Add step down/up options to powerd(8)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Aug 14 11:40:02 GMT 2007
>Closed-Date:    Fri Jan 09 22:26:40 UTC 2009
>Last-Modified:  Fri Jan 09 22:26:40 UTC 2009
>Originator:     Oliver Fromme
>Release:        FreeBSD 6.2-STABLE-20070808 i386
>Organization:
secnetix GmbH & Co. KG
		http://www.secnetix.de/bsd
>Environment:
System: FreeBSD pluto.secnetix.de 6.2-STABLE-20070808 FreeBSD 6.2-STABLE-20070808 #0: Wed Aug 8 14:35:59 CEST 2007 olli@pluto.secnetix.de:/usr/obj/usr/src/sys/PLUTO i386

>Description:

   By default, powerd(1) adjusts the CPU freq level by one
   step down upon every polling interval if the CPU idle
   percent level is considered to be high, or two steps up
   if the CPU idle percent level is considered to be low.
   Those values (one step down, two steps up) are hardcoded
   and cannot be changed by the user.

   However, in some situations it is desirable to change
   those numbers.  In particular, if the system supports
   many fine-grained levels, it can take a long time for
   the CPU to get back to full performance.  Making the
   polling interval shorter isn't always a desirable
   solution because of side effects.

   The patch presented here adds two options -d and -u
   which specify the number of freq steps (down and up,
   respectively) when changing the performance level.
   The default values are 1 and 2, i.e. the same as
   previous behaviour without the patch.

   A diff to the manpage is included, too.

>How-To-Repeat:

   n/a

>Fix:

--- powerd.8.orig	2006-01-24 18:02:39.000000000 +0100
+++ powerd.8	2007-08-14 12:51:33.000000000 +0200
@@ -34,11 +34,13 @@
 .Nm
 .Op Fl a Ar mode
 .Op Fl b Ar mode
+.Op Fl d Ar steps_down
 .Op Fl i Ar percent
 .Op Fl n Ar mode
 .Op Fl p Ar ival
 .Op Fl P Ar pidfile
 .Op Fl r Ar percent
+.Op Fl u Ar steps_up
 .Op Fl v
 .Sh DESCRIPTION
 The
@@ -70,6 +72,11 @@
 Selects the
 .Ar mode
 to use while on battery power.
+.It Fl d Ar steps_down
+In adaptive mode, degrade the performance by
+.Ar steps_down
+levels every time the CPU idle percent level is considered to be high.
+The default is 1.
 .It Fl i Ar percent
 Specifies the CPU idle percent level when
 adaptive
@@ -92,6 +99,11 @@
 adaptive
 mode should consider the CPU running and increase performance.
 The default is 65% or lower.
+.It Fl u Ar steps_up
+In adaptive mode, increase the performance by
+.Ar steps_up
+levels every time the CPU idle percent level is considered to be low.
+The default is 2.
 .It Fl v
 Verbose mode.
 Messages about power changes will be printed to stdout and
--- powerd.c.orig	2007-08-08 13:52:24.000000000 +0200
+++ powerd.c	2007-08-14 12:43:37.000000000 +0200
@@ -50,6 +50,8 @@
 #define DEFAULT_ACTIVE_PERCENT	65
 #define DEFAULT_IDLE_PERCENT	90
 #define DEFAULT_POLL_INTERVAL	500	/* Poll interval in milliseconds */
+#define DEFAULT_STEPS_DOWN	1
+#define DEFAULT_STEPS_UP	2
 
 enum modes_t {
 	MODE_MIN,
@@ -261,6 +263,7 @@
 	long idle, total;
 	int curfreq, *freqs, i, *mwatts, numfreqs;
 	int ch, mode_ac, mode_battery, mode_none, acline, mode, vflag;
+	int steps_down, steps_up;
 	uint64_t mjoules_used;
 	size_t len;
 
@@ -269,6 +272,8 @@
 	cpu_running_mark = DEFAULT_ACTIVE_PERCENT;
 	cpu_idle_mark = DEFAULT_IDLE_PERCENT;
 	poll_ival = DEFAULT_POLL_INTERVAL;
+	steps_down = DEFAULT_STEPS_DOWN;
+	steps_up = DEFAULT_STEPS_UP;
 	mjoules_used = 0;
 	vflag = 0;
 	apm_fd = -1;
@@ -277,7 +282,7 @@
 	if (geteuid() != 0)
 		errx(1, "must be root to run");
 
-	while ((ch = getopt(argc, argv, "a:b:i:n:p:P:r:v")) != EOF)
+	while ((ch = getopt(argc, argv, "a:b:d:i:n:p:P:r:u:v")) != EOF)
 		switch (ch) {
 		case 'a':
 			parse_mode(optarg, &mode_ac, ch);
@@ -285,6 +290,14 @@
 		case 'b':
 			parse_mode(optarg, &mode_battery, ch);
 			break;
+		case 'd':
+			steps_down = atoi(optarg);
+			if (steps_down < 0) {
+				warnx("%d is not a valid step count",
+				    steps_down);
+				usage();
+			}
+			break;
 		case 'i':
 			cpu_idle_mark = atoi(optarg);
 			if (cpu_idle_mark < 0 || cpu_idle_mark > 100) {
@@ -314,6 +327,14 @@
 				usage();
 			}
 			break;
+		case 'u':
+			steps_up = atoi(optarg);
+			if (steps_up < 0) {
+				warnx("%d is not a valid step count",
+				    steps_up);
+				usage();
+			}
+			break;
 		case 'v':
 			vflag = 1;
 			break;
@@ -470,7 +491,7 @@
 		}
 		if (idle < (total * cpu_running_mark) / 100 &&
 		    curfreq < freqs[0]) {
-			i -= 2;
+			i -= steps_down;
 			if (i < 0)
 				i = 0;
 			if (vflag) {
@@ -483,7 +504,9 @@
 				    freqs[i]);
 		} else if (idle > (total * cpu_idle_mark) / 100 &&
 		    curfreq > freqs[numfreqs - 1]) {
-			i++;
+			i += steps_up;
+			if (i > numfreqs - 1)
+				i = numfreqs - 1;
 			if (vflag) {
 				printf("idle time > %d%%, decreasing clock"
 				    " speed from %d MHz to %d MHz\n",
>Release-Note:
>Audit-Trail:

From: Oliver Fromme <olli@secnetix.de>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/115513: [PATCH] Add step down/up options to powerd(8)
Date: Fri, 17 Aug 2007 11:53:18 +0200 (CEST)

 I'm sorry, the sense of "up" and "down" was reversed in the
 first patch.  Below is the correct patch (RELENG_6).  On
 -current one hunk is rejected, but can be applied manually
 without problems.
 
 Just to illustrate, the following is the default behaviour
 with standard powerd(8) on my notebook when a CPU-intensive
 application (e.g. movie player, screen saver, whatever) is
 started:
 
 dev.cpu.0.freq: 100
 dev.cpu.0.freq: 100
 dev.cpu.0.freq: 100   <-- app is started
 dev.cpu.0.freq: 300
 dev.cpu.0.freq: 500
 dev.cpu.0.freq: 700
 dev.cpu.0.freq: 933
 dev.cpu.0.freq: 1166
 dev.cpu.0.freq: 1400
 dev.cpu.0.freq: 1600   <-- CPU is at full speed
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1400
 dev.cpu.0.freq: 1333
 dev.cpu.0.freq: 1166
 dev.cpu.0.freq: 1067
 dev.cpu.0.freq: 933
 dev.cpu.0.freq: 800
 dev.cpu.0.freq: 700
 dev.cpu.0.freq: 600
 dev.cpu.0.freq: 500
 dev.cpu.0.freq: 400
 dev.cpu.0.freq: 300
 dev.cpu.0.freq: 200
 dev.cpu.0.freq: 100
 dev.cpu.0.freq: 100
 dev.cpu.0.freq: 100
 
 That means it takes a while to get up to speed.  For a
 movie player or screen saver that means that it starts
 jerkily, which is annoying and makes FreeBSD look bad.  :-(
 
 With the below patch applied and option "-u 7", powerd
 goes up much more quickly, and then the beginning of the
 movie is perfectly smooth:
 
 dev.cpu.0.freq: 100
 dev.cpu.0.freq: 100
 dev.cpu.0.freq: 100
 dev.cpu.0.freq: 800
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1600
 dev.cpu.0.freq: 1400
 dev.cpu.0.freq: 1333
 dev.cpu.0.freq: 1166
 dev.cpu.0.freq: 1067
 dev.cpu.0.freq: 933
 dev.cpu.0.freq: 800
 dev.cpu.0.freq: 700
 dev.cpu.0.freq: 600
 dev.cpu.0.freq: 400
 dev.cpu.0.freq: 300
 dev.cpu.0.freq: 200
 dev.cpu.0.freq: 100
 dev.cpu.0.freq: 100
 dev.cpu.0.freq: 100
 
 --- powerd.8.orig	2006-01-24 18:02:39.000000000 +0100
 +++ powerd.8	2007-08-17 10:32:26.000000000 +0200
 @@ -34,11 +34,13 @@
  .Nm
  .Op Fl a Ar mode
  .Op Fl b Ar mode
 +.Op Fl d Ar steps_down
  .Op Fl i Ar percent
  .Op Fl n Ar mode
  .Op Fl p Ar ival
  .Op Fl P Ar pidfile
  .Op Fl r Ar percent
 +.Op Fl u Ar steps_up
  .Op Fl v
  .Sh DESCRIPTION
  The
 @@ -70,6 +72,11 @@
  Selects the
  .Ar mode
  to use while on battery power.
 +.It Fl d Ar steps_down
 +In adaptive mode, degrade the performance by
 +.Ar steps_down
 +levels every time the CPU idle percent level is considered to be high.
 +The default is 1.
  .It Fl i Ar percent
  Specifies the CPU idle percent level when
  adaptive
 @@ -92,6 +99,11 @@
  adaptive
  mode should consider the CPU running and increase performance.
  The default is 65% or lower.
 +.It Fl u Ar steps_up
 +In adaptive mode, increase the performance by
 +.Ar steps_up
 +levels every time the CPU idle percent level is considered to be low.
 +The default is 2.
  .It Fl v
  Verbose mode.
  Messages about power changes will be printed to stdout and
 --- powerd.c.orig	2007-08-08 14:31:33.000000000 +0200
 +++ powerd.c	2007-08-17 10:36:57.000000000 +0200
 @@ -50,6 +50,8 @@
  #define DEFAULT_ACTIVE_PERCENT	65
  #define DEFAULT_IDLE_PERCENT	90
  #define DEFAULT_POLL_INTERVAL	500	/* Poll interval in milliseconds */
 +#define DEFAULT_STEPS_DOWN	1
 +#define DEFAULT_STEPS_UP	2
  
  enum modes_t {
  	MODE_MIN,
 @@ -261,6 +263,7 @@
  	long idle, total;
  	int curfreq, *freqs, i, *mwatts, numfreqs;
  	int ch, mode_ac, mode_battery, mode_none, acline, mode, vflag;
 +	int steps_down, steps_up;
  	uint64_t mjoules_used;
  	size_t len;
  
 @@ -269,6 +272,8 @@
  	cpu_running_mark = DEFAULT_ACTIVE_PERCENT;
  	cpu_idle_mark = DEFAULT_IDLE_PERCENT;
  	poll_ival = DEFAULT_POLL_INTERVAL;
 +	steps_down = DEFAULT_STEPS_DOWN;
 +	steps_up = DEFAULT_STEPS_UP;
  	mjoules_used = 0;
  	vflag = 0;
  	apm_fd = -1;
 @@ -277,7 +282,7 @@
  	if (geteuid() != 0)
  		errx(1, "must be root to run");
  
 -	while ((ch = getopt(argc, argv, "a:b:i:n:p:P:r:v")) != EOF)
 +	while ((ch = getopt(argc, argv, "a:b:d:i:n:p:P:r:u:v")) != EOF)
  		switch (ch) {
  		case 'a':
  			parse_mode(optarg, &mode_ac, ch);
 @@ -285,6 +290,14 @@
  		case 'b':
  			parse_mode(optarg, &mode_battery, ch);
  			break;
 +		case 'd':
 +			steps_down = atoi(optarg);
 +			if (steps_down < 0) {
 +				warnx("%d is not a valid step count",
 +				    steps_down);
 +				usage();
 +			}
 +			break;
  		case 'i':
  			cpu_idle_mark = atoi(optarg);
  			if (cpu_idle_mark < 0 || cpu_idle_mark > 100) {
 @@ -314,6 +327,14 @@
  				usage();
  			}
  			break;
 +		case 'u':
 +			steps_up = atoi(optarg);
 +			if (steps_up < 0) {
 +				warnx("%d is not a valid step count",
 +				    steps_up);
 +				usage();
 +			}
 +			break;
  		case 'v':
  			vflag = 1;
  			break;
 @@ -470,7 +491,7 @@
  		}
  		if (idle < (total * cpu_running_mark) / 100 &&
  		    curfreq < freqs[0]) {
 -			i -= 2;
 +			i -= steps_up;
  			if (i < 0)
  				i = 0;
  			if (vflag) {
 @@ -483,7 +504,9 @@
  				    freqs[i]);
  		} else if (idle > (total * cpu_idle_mark) / 100 &&
  		    curfreq > freqs[numfreqs - 1]) {
 -			i++;
 +			i += steps_down;
 +			if (i > numfreqs - 1)
 +				i = numfreqs - 1;
  			if (vflag) {
  				printf("idle time > %d%%, decreasing clock"
  				    " speed from %d MHz to %d MHz\n",
State-Changed-From-To: open->closed 
State-Changed-By: mav 
State-Changed-When: Fri Jan 9 22:25:13 UTC 2009 
State-Changed-Why:  
New powerd algorithm does not depend on number of steps. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=115513 
>Unformatted:
