From nobody@FreeBSD.org  Fri Mar 26 16:55:06 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 965261065674
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 26 Mar 2010 16:55:06 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 84D9D8FC18
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 26 Mar 2010 16:55:06 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o2QGt6kL004586
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 26 Mar 2010 16:55:06 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o2QGt6Ud004585;
	Fri, 26 Mar 2010 16:55:06 GMT
	(envelope-from nobody)
Message-Id: <201003261655.o2QGt6Ud004585@www.freebsd.org>
Date: Fri, 26 Mar 2010 16:55:06 GMT
From: Boris Kochergin <spawk@acm.poly.edu>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [powerd] [patch] Add -m and -M (minimum and maximum frequency) options to powerd
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         145063
>Category:       bin
>Synopsis:       [patch] powerd(8): Add -m and -M (minimum and maximum frequency) options to powerd
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    brucec
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Mar 26 17:00:09 UTC 2010
>Closed-Date:    Sat Sep 11 14:48:07 UTC 2010
>Last-Modified:  Sat Sep 11 14:50:02 UTC 2010
>Originator:     Boris Kochergin
>Release:        8.0-RELEASE-p2
>Organization:
Polytechnic Institute of NYU
>Environment:
FreeBSD peer 8.0-RELEASE-p2 FreeBSD 8.0-RELEASE-p2 #2: Mon Feb 22 23:18:53 EST 2010     root@peer:/usr/obj/usr/src/sys/PEER  i386
>Description:
This patch implements the -m and -M (minimum and maximum frequency, respectively) options for powerd. It has been tested on 7.2, 8.x, and 9.x.
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

--- powerd.c.orig	2010-03-25 15:48:09.000000000 -0400
+++ powerd.c	2010-03-26 12:31:17.000000000 -0400
@@ -84,7 +84,8 @@
 #define DEVCTL_MAXBUF	1024
 
 static int	read_usage_times(int *load);
-static int	read_freqs(int *numfreqs, int **freqs, int **power);
+static int	read_freqs(int *numfreqs, int **freqs, int **power,
+		    int minfreq, int maxfreq);
 static int	set_freq(int freq);
 static void	acline_init(void);
 static void	acline_read(void);
@@ -174,10 +175,10 @@
 }
 
 static int
-read_freqs(int *numfreqs, int **freqs, int **power)
+read_freqs(int *numfreqs, int **freqs, int **power, int minfreq, int maxfreq)
 {
 	char *freqstr, *p, *q;
-	int i;
+	int i, j;
 	size_t len = 0;
 
 	if (sysctl(levels_mib, 4, NULL, &len, NULL, 0))
@@ -201,19 +202,30 @@
 		free(*freqs);
 		return (-1);
 	}
-	for (i = 0, p = freqstr; i < *numfreqs; i++) {
+	for (i = 0, j = 0, p = freqstr; i < *numfreqs; i++) {
 		q = strchr(p, ' ');
 		if (q != NULL)
 			*q = '\0';
-		if (sscanf(p, "%d/%d", &(*freqs)[i], &(*power)[i]) != 2) {
+		if (sscanf(p, "%d/%d", &(*freqs)[j], &(*power)[i]) != 2) {
 			free(freqstr);
 			free(*freqs);
 			free(*power);
 			return (-1);
 		}
+		if (((*freqs)[j] >= minfreq || minfreq == -1) &&
+		    ((*freqs)[j] <= maxfreq || maxfreq == -1))
+			j++;
 		p = q + 1;
 	}
 
+	*numfreqs = j;
+	if ((*freqs = realloc(*freqs, *numfreqs * sizeof(int))) == NULL) {
+		free(freqstr);
+		free(*freqs);
+		free(*power);
+		return (-1);
+	}
+
 	free(freqstr);
 	return (0);
 }
@@ -422,7 +434,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 %%] [-m freq] [-M freq] [-n mode] [-p ival] [-r %%] [-P pidfile]\n");
 	exit(1);
 }
 
@@ -435,6 +447,7 @@
 	struct pidfh *pfh = NULL;
 	const char *pidfile = NULL;
 	int freq, curfreq, initfreq, *freqs, i, j, *mwatts, numfreqs, load;
+	int minfreq = -1, maxfreq = -1;
 	int ch, mode, mode_ac, mode_battery, mode_none;
 	uint64_t mjoules_used;
 	size_t len;
@@ -452,7 +465,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:i:m:M:n:p:P:r:v")) != -1)
 		switch (ch) {
 		case 'a':
 			parse_mode(optarg, &mode_ac, ch);
@@ -468,6 +481,22 @@
 				usage();
 			}
 			break;
+		case 'm':
+			minfreq = atoi(optarg);
+			if (minfreq < 0) {
+				warnx("%d is not a valid CPU frequency",
+				    minfreq);
+				usage();
+			}
+			break;
+		case 'M':
+			maxfreq = atoi(optarg);
+			if (maxfreq < 0) {
+				warnx("%d is not a valid CPU frequency",
+				    maxfreq);
+				usage();
+			}
+			break;
 		case 'n':
 			parse_mode(optarg, &mode_none, ch);
 			break;
@@ -515,8 +544,10 @@
 	/* Check if we can read the load and supported freqs. */
 	if (read_usage_times(NULL))
 		err(1, "read_usage_times");
-	if (read_freqs(&numfreqs, &freqs, &mwatts))
+	if (read_freqs(&numfreqs, &freqs, &mwatts, minfreq, maxfreq))
 		err(1, "error reading supported CPU frequencies");
+	if (numfreqs == 0)
+		errx(1, "no CPU frequencies in user-specified range");
 
 	/* Run in the background unless in verbose mode. */
 	if (!vflag) {
@@ -551,6 +582,49 @@
 	freq = initfreq = get_freq();
 	if (freq < 1)
 		freq = 1;
+
+	/*
+	 * If we are in adaptive mode and the current frequency is outside the
+	 * user-defined range, adjust it to be within the user-defined range.
+	 */
+	acline_read();
+	if (acline_status > SRC_UNKNOWN)
+		errx(1, "invalid AC line status %d", acline_status);
+	if ((acline_status == SRC_AC &&
+	    (mode_ac == MODE_ADAPTIVE || mode_ac == MODE_HIADAPTIVE)) ||
+	    (acline_status == SRC_BATTERY &&
+	    (mode_battery == MODE_ADAPTIVE || mode_battery == MODE_HIADAPTIVE)) ||
+	    (acline_status == SRC_UNKNOWN &&
+	    (mode_none == MODE_ADAPTIVE || mode_none == MODE_HIADAPTIVE))) {
+		/* Read the current frequency. */
+		len = sizeof(curfreq);
+		if (sysctl(freq_mib, 4, &curfreq, &len, NULL, 0) != 0) {
+			if (vflag)
+				warn("error reading current CPU frequency");
+		}
+		if (curfreq < freqs[numfreqs - 1]) {
+			if (vflag) {
+				printf("CPU frequency is below user-defined "
+				    "minimum; changing frequency to %d "
+				    "MHz\n", freqs[numfreqs - 1]);
+			}
+			if (set_freq(freqs[numfreqs - 1]) != 0) {
+				warn("error setting CPU freq %d",
+				    freqs[numfreqs - 1]);
+			}
+		} else if (curfreq > freqs[0]) {
+			if (vflag) {
+				printf("CPU frequency is above user-defined "
+				    "maximum; changing frequency to %d "
+				    "MHz\n", freqs[0]);
+			}
+			if (set_freq(freqs[0]) != 0) {
+				warn("error setting CPU freq %d",
+				    freqs[0]);
+			}
+		}
+	}
+
 	/* Main loop. */
 	for (;;) {
 		FD_ZERO(&fdset);
--- powerd.8.orig	2010-03-26 12:37:50.000000000 -0400
+++ powerd.8	2010-03-26 12:41:06.000000000 -0400
@@ -35,6 +35,8 @@
 .Op Fl a Ar mode
 .Op Fl b Ar mode
 .Op Fl i Ar percent
+.Op Fl m Ar freq
+.Op Fl M Ar freq
 .Op Fl n Ar mode
 .Op Fl p Ar ival
 .Op Fl P Ar pidfile
@@ -79,6 +81,10 @@
 Specifies the CPU load percent level when adaptive
 mode should begin to degrade performance to save power.
 The default is 50% or lower.
+.It Fl m Ar freq
+Specifies the minimum frequency to throttle down to.
+.It Fl M Ar freq
+Specifies the maximum frequency to throttle up to.
 .It Fl n Ar mode
 Selects the
 .Ar mode


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-acpi 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Tue Mar 30 13:52:32 UTC 2010 
Responsible-Changed-Why:  
Submitter has requested review from acpi group. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=145063 
Responsible-Changed-From-To: freebsd-acpi->brucec  
Responsible-Changed-By: brucec 
Responsible-Changed-When: Sat Aug 7 21:08:26 UTC 2010 
Responsible-Changed-Why:  
Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=145063 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/145063: commit references a PR
Date: Tue, 17 Aug 2010 09:11:47 +0000 (UTC)

 Author: brucec
 Date: Tue Aug 17 09:11:38 2010
 New Revision: 211415
 URL: http://svn.freebsd.org/changeset/base/211415
 
 Log:
   Add -m and -M options to control the minimum and maximum frequency.
   
   PR:	bin/145063
   Submitted by:	Boris Kochergin <spawk at acm.poly.edu>
   Reviewed by:	cperciva
   Approved by:	rrs (mentor)
   MFC after: 2 weeks
 
 Modified:
   head/usr.sbin/powerd/powerd.8
   head/usr.sbin/powerd/powerd.c
 
 Modified: head/usr.sbin/powerd/powerd.8
 ==============================================================================
 --- head/usr.sbin/powerd/powerd.8	Tue Aug 17 09:08:28 2010	(r211414)
 +++ head/usr.sbin/powerd/powerd.8	Tue Aug 17 09:11:38 2010	(r211415)
 @@ -35,6 +35,8 @@
  .Op Fl a Ar mode
  .Op Fl b Ar mode
  .Op Fl i Ar percent
 +.Op Fl m Ar freq
 +.Op Fl M Ar freq
  .Op Fl n Ar mode
  .Op Fl p Ar ival
  .Op Fl P Ar pidfile
 @@ -79,6 +81,10 @@ to use while on battery power.
  Specifies the CPU load percent level when adaptive
  mode should begin to degrade performance to save power.
  The default is 50% or lower.
 +.It Fl m Ar freq
 +Specifies the minimum frequency to throttle down to.
 +.It Fl M Ar freq
 +Specifies the maximum frequency to throttle up to.
  .It Fl n Ar mode
  Selects the
  .Ar mode
 
 Modified: head/usr.sbin/powerd/powerd.c
 ==============================================================================
 --- head/usr.sbin/powerd/powerd.c	Tue Aug 17 09:08:28 2010	(r211414)
 +++ head/usr.sbin/powerd/powerd.c	Tue Aug 17 09:11:38 2010	(r211415)
 @@ -84,7 +84,8 @@ const char *modes[] = {
  #define DEVCTL_MAXBUF	1024
  
  static int	read_usage_times(int *load);
 -static int	read_freqs(int *numfreqs, int **freqs, int **power);
 +static int	read_freqs(int *numfreqs, int **freqs, int **power,
 +		    int minfreq, int maxfreq);
  static int	set_freq(int freq);
  static void	acline_init(void);
  static void	acline_read(void);
 @@ -174,10 +175,10 @@ read_usage_times(int *load)
  }
  
  static int
 -read_freqs(int *numfreqs, int **freqs, int **power)
 +read_freqs(int *numfreqs, int **freqs, int **power, int minfreq, int maxfreq)
  {
  	char *freqstr, *p, *q;
 -	int i;
 +	int i, j;
  	size_t len = 0;
  
  	if (sysctl(levels_mib, 4, NULL, &len, NULL, 0))
 @@ -201,19 +202,30 @@ read_freqs(int *numfreqs, int **freqs, i
  		free(*freqs);
  		return (-1);
  	}
 -	for (i = 0, p = freqstr; i < *numfreqs; i++) {
 +	for (i = 0, j = 0, p = freqstr; i < *numfreqs; i++) {
  		q = strchr(p, ' ');
  		if (q != NULL)
  			*q = '\0';
 -		if (sscanf(p, "%d/%d", &(*freqs)[i], &(*power)[i]) != 2) {
 +		if (sscanf(p, "%d/%d", &(*freqs)[j], &(*power)[i]) != 2) {
  			free(freqstr);
  			free(*freqs);
  			free(*power);
  			return (-1);
  		}
 +		if (((*freqs)[j] >= minfreq || minfreq == -1) &&
 +		    ((*freqs)[j] <= maxfreq || maxfreq == -1))
 +			j++;
  		p = q + 1;
  	}
  
 +	*numfreqs = j;
 +	if ((*freqs = realloc(*freqs, *numfreqs * sizeof(int))) == NULL) {
 +		free(freqstr);
 +		free(*freqs);
 +		free(*power);
 +		return (-1);
 +	}
 +
  	free(freqstr);
  	return (0);
  }
 @@ -422,7 +434,7 @@ usage(void)
  {
  
  	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 %%] [-m freq] [-M freq] [-n mode] [-p ival] [-r %%] [-P pidfile]\n");
  	exit(1);
  }
  
 @@ -435,6 +447,7 @@ main(int argc, char * argv[])
  	struct pidfh *pfh = NULL;
  	const char *pidfile = NULL;
  	int freq, curfreq, initfreq, *freqs, i, j, *mwatts, numfreqs, load;
 +	int minfreq = -1, maxfreq = -1;
  	int ch, mode, mode_ac, mode_battery, mode_none, idle, to;
  	uint64_t mjoules_used;
  	size_t len;
 @@ -452,7 +465,7 @@ main(int argc, char * argv[])
  	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:i:m:M:n:p:P:r:v")) != -1)
  		switch (ch) {
  		case 'a':
  			parse_mode(optarg, &mode_ac, ch);
 @@ -468,6 +481,22 @@ main(int argc, char * argv[])
  				usage();
  			}
  			break;
 +		case 'm':
 +			minfreq = atoi(optarg);
 +			if (minfreq < 0) {
 +				warnx("%d is not a valid CPU frequency",
 +				    minfreq);
 +				usage();
 +			}
 +			break;
 +		case 'M':
 +			maxfreq = atoi(optarg);
 +			if (maxfreq < 0) {
 +				warnx("%d is not a valid CPU frequency",
 +				    maxfreq);
 +				usage();
 +			}
 +			break;
  		case 'n':
  			parse_mode(optarg, &mode_none, ch);
  			break;
 @@ -515,8 +544,10 @@ main(int argc, char * argv[])
  	/* Check if we can read the load and supported freqs. */
  	if (read_usage_times(NULL))
  		err(1, "read_usage_times");
 -	if (read_freqs(&numfreqs, &freqs, &mwatts))
 +	if (read_freqs(&numfreqs, &freqs, &mwatts, minfreq, maxfreq))
  		err(1, "error reading supported CPU frequencies");
 +	if (numfreqs == 0)
 +		errx(1, "no CPU frequencies in user-specified range");
  
  	/* Run in the background unless in verbose mode. */
  	if (!vflag) {
 @@ -552,6 +583,49 @@ main(int argc, char * argv[])
  	i = get_freq_id(curfreq, freqs, numfreqs);
  	if (freq < 1)
  		freq = 1;
 +
 +	/*
 +	 * If we are in adaptive mode and the current frequency is outside the
 +	 * user-defined range, adjust it to be within the user-defined range.
 +	 */
 +	acline_read();
 +	if (acline_status > SRC_UNKNOWN)
 +		errx(1, "invalid AC line status %d", acline_status);
 +	if ((acline_status == SRC_AC &&
 +	    (mode_ac == MODE_ADAPTIVE || mode_ac == MODE_HIADAPTIVE)) ||
 +	    (acline_status == SRC_BATTERY &&
 +	    (mode_battery == MODE_ADAPTIVE || mode_battery == MODE_HIADAPTIVE)) ||
 +	    (acline_status == SRC_UNKNOWN &&
 +	    (mode_none == MODE_ADAPTIVE || mode_none == MODE_HIADAPTIVE))) {
 +		/* Read the current frequency. */
 +		len = sizeof(curfreq);
 +		if (sysctl(freq_mib, 4, &curfreq, &len, NULL, 0) != 0) {
 +			if (vflag)
 +				warn("error reading current CPU frequency");
 +		}
 +		if (curfreq < freqs[numfreqs - 1]) {
 +			if (vflag) {
 +				printf("CPU frequency is below user-defined "
 +				    "minimum; changing frequency to %d "
 +				    "MHz\n", freqs[numfreqs - 1]);
 +			}
 +			if (set_freq(freqs[numfreqs - 1]) != 0) {
 +				warn("error setting CPU freq %d",
 +				    freqs[numfreqs - 1]);
 +			}
 +		} else if (curfreq > freqs[0]) {
 +			if (vflag) {
 +				printf("CPU frequency is above user-defined "
 +				    "maximum; changing frequency to %d "
 +				    "MHz\n", freqs[0]);
 +			}
 +			if (set_freq(freqs[0]) != 0) {
 +				warn("error setting CPU freq %d",
 +				    freqs[0]);
 +			}
 +		}
 +	}
 +
  	idle = 0;
  	/* Main loop. */
  	for (;;) {
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched  
State-Changed-By: brucec 
State-Changed-When: Tue Aug 17 09:53:35 UTC 2010 
State-Changed-Why:  
Fixed in r211415. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=145063 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/145063: commit references a PR
Date: Sat, 11 Sep 2010 14:34:24 +0000 (UTC)

 Author: brucec
 Date: Sat Sep 11 14:34:16 2010
 New Revision: 212472
 URL: http://svn.freebsd.org/changeset/base/212472
 
 Log:
   MFC r211415:
   
   Add -m and -M options to control the minimum and maximum frequency.
   
   PR:		bin/145063
   Submitted by:	Boris Kochergin <spawk at acm.poly.edu>
   Approved by:	rrs (mentor)
 
 Modified:
   stable/8/usr.sbin/powerd/powerd.8
   stable/8/usr.sbin/powerd/powerd.c
 Directory Properties:
   stable/8/usr.sbin/powerd/   (props changed)
 
 Modified: stable/8/usr.sbin/powerd/powerd.8
 ==============================================================================
 --- stable/8/usr.sbin/powerd/powerd.8	Sat Sep 11 14:29:31 2010	(r212471)
 +++ stable/8/usr.sbin/powerd/powerd.8	Sat Sep 11 14:34:16 2010	(r212472)
 @@ -35,6 +35,8 @@
  .Op Fl a Ar mode
  .Op Fl b Ar mode
  .Op Fl i Ar percent
 +.Op Fl m Ar freq
 +.Op Fl M Ar freq
  .Op Fl n Ar mode
  .Op Fl p Ar ival
  .Op Fl P Ar pidfile
 @@ -79,6 +81,10 @@ to use while on battery power.
  Specifies the CPU load percent level when adaptive
  mode should begin to degrade performance to save power.
  The default is 50% or lower.
 +.It Fl m Ar freq
 +Specifies the minimum frequency to throttle down to.
 +.It Fl M Ar freq
 +Specifies the maximum frequency to throttle up to.
  .It Fl n Ar mode
  Selects the
  .Ar mode
 
 Modified: stable/8/usr.sbin/powerd/powerd.c
 ==============================================================================
 --- stable/8/usr.sbin/powerd/powerd.c	Sat Sep 11 14:29:31 2010	(r212471)
 +++ stable/8/usr.sbin/powerd/powerd.c	Sat Sep 11 14:34:16 2010	(r212472)
 @@ -80,7 +80,8 @@ const char *modes[] = {
  #define DEVCTL_MAXBUF	1024
  
  static int	read_usage_times(int *load);
 -static int	read_freqs(int *numfreqs, int **freqs, int **power);
 +static int	read_freqs(int *numfreqs, int **freqs, int **power,
 +		    int minfreq, int maxfreq);
  static int	set_freq(int freq);
  static void	acline_init(void);
  static void	acline_read(void);
 @@ -170,10 +171,10 @@ read_usage_times(int *load)
  }
  
  static int
 -read_freqs(int *numfreqs, int **freqs, int **power)
 +read_freqs(int *numfreqs, int **freqs, int **power, int minfreq, int maxfreq)
  {
  	char *freqstr, *p, *q;
 -	int i;
 +	int i, j;
  	size_t len = 0;
  
  	if (sysctl(levels_mib, 4, NULL, &len, NULL, 0))
 @@ -197,19 +198,30 @@ read_freqs(int *numfreqs, int **freqs, i
  		free(*freqs);
  		return (-1);
  	}
 -	for (i = 0, p = freqstr; i < *numfreqs; i++) {
 +	for (i = 0, j = 0, p = freqstr; i < *numfreqs; i++) {
  		q = strchr(p, ' ');
  		if (q != NULL)
  			*q = '\0';
 -		if (sscanf(p, "%d/%d", &(*freqs)[i], &(*power)[i]) != 2) {
 +		if (sscanf(p, "%d/%d", &(*freqs)[j], &(*power)[i]) != 2) {
  			free(freqstr);
  			free(*freqs);
  			free(*power);
  			return (-1);
  		}
 +		if (((*freqs)[j] >= minfreq || minfreq == -1) &&
 +		    ((*freqs)[j] <= maxfreq || maxfreq == -1))
 +			j++;
  		p = q + 1;
  	}
  
 +	*numfreqs = j;
 +	if ((*freqs = realloc(*freqs, *numfreqs * sizeof(int))) == NULL) {
 +		free(freqstr);
 +		free(*freqs);
 +		free(*power);
 +		return (-1);
 +	}
 +
  	free(freqstr);
  	return (0);
  }
 @@ -418,7 +430,7 @@ usage(void)
  {
  
  	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 %%] [-m freq] [-M freq] [-n mode] [-p ival] [-r %%] [-P pidfile]\n");
  	exit(1);
  }
  
 @@ -431,7 +443,8 @@ main(int argc, char * argv[])
  	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, idle;
 +	int minfreq = -1, maxfreq = -1;
  	uint64_t mjoules_used;
  	size_t len;
  
 @@ -448,7 +461,7 @@ main(int argc, char * argv[])
  	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:i:m:M:n:p:P:r:v")) != -1)
  		switch (ch) {
  		case 'a':
  			parse_mode(optarg, &mode_ac, ch);
 @@ -464,6 +477,22 @@ main(int argc, char * argv[])
  				usage();
  			}
  			break;
 +		case 'm':
 +			minfreq = atoi(optarg);
 +			if (minfreq < 0) {
 +				warnx("%d is not a valid CPU frequency",
 +				    minfreq);
 +				usage();
 +			}
 +			break;
 +		case 'M':
 +			maxfreq = atoi(optarg);
 +			if (maxfreq < 0) {
 +				warnx("%d is not a valid CPU frequency",
 +				    maxfreq);
 +				usage();
 +			}
 +			break;
  		case 'n':
  			parse_mode(optarg, &mode_none, ch);
  			break;
 @@ -511,8 +540,10 @@ main(int argc, char * argv[])
  	/* Check if we can read the load and supported freqs. */
  	if (read_usage_times(NULL))
  		err(1, "read_usage_times");
 -	if (read_freqs(&numfreqs, &freqs, &mwatts))
 +	if (read_freqs(&numfreqs, &freqs, &mwatts, minfreq, maxfreq))
  		err(1, "error reading supported CPU frequencies");
 +	if (numfreqs == 0)
 +		errx(1, "no CPU frequencies in user-specified range");
  
  	/* Run in the background unless in verbose mode. */
  	if (!vflag) {
 @@ -547,6 +578,50 @@ main(int argc, char * argv[])
  	freq = initfreq = get_freq();
  	if (freq < 1)
  		freq = 1;
 +	
 +	/*
 +	 * If we are in adaptive mode and the current frequency is outside the
 +	 * user-defined range, adjust it to be within the user-defined range.
 +	 */
 +	acline_read();
 +	if (acline_status > SRC_UNKNOWN)
 +		errx(1, "invalid AC line status %d", acline_status);
 +	if ((acline_status == SRC_AC &&
 +	    (mode_ac == MODE_ADAPTIVE || mode_ac == MODE_HIADAPTIVE)) ||
 +	    (acline_status == SRC_BATTERY &&
 +	    (mode_battery == MODE_ADAPTIVE || mode_battery == MODE_HIADAPTIVE)) ||
 +	    (acline_status == SRC_UNKNOWN &&
 +	    (mode_none == MODE_ADAPTIVE || mode_none == MODE_HIADAPTIVE))) {
 +		/* Read the current frequency. */
 +		len = sizeof(curfreq);
 +		if (sysctl(freq_mib, 4, &curfreq, &len, NULL, 0) != 0) {
 +			if (vflag)
 +				warn("error reading current CPU frequency");
 +		}
 +		if (curfreq < freqs[numfreqs - 1]) {
 +			if (vflag) {
 +				printf("CPU frequency is below user-defined "
 +				    "minimum; changing frequency to %d "
 +				    "MHz\n", freqs[numfreqs - 1]);
 +			}
 +			if (set_freq(freqs[numfreqs - 1]) != 0) {
 +				warn("error setting CPU freq %d",
 +				    freqs[numfreqs - 1]);
 +			}
 +		} else if (curfreq > freqs[0]) {
 +			if (vflag) {
 +				printf("CPU frequency is above user-defined "
 +				    "maximum; changing frequency to %d "
 +				    "MHz\n", freqs[0]);
 +			}
 +			if (set_freq(freqs[0]) != 0) {
 +				warn("error setting CPU freq %d",
 +				    freqs[0]);
 +			}
 +		}
 +	}
 +
 +	idle = 0;
  	/* Main loop. */
  	for (;;) {
  		FD_ZERO(&fdset);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed  
State-Changed-By: brucec 
State-Changed-When: Sat Sep 11 14:47:51 UTC 2010 
State-Changed-Why:  
Merged to stable/7 and stable/8. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=145063 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/145063: commit references a PR
Date: Sat, 11 Sep 2010 14:40:00 +0000 (UTC)

 Author: brucec
 Date: Sat Sep 11 14:39:53 2010
 New Revision: 212473
 URL: http://svn.freebsd.org/changeset/base/212473
 
 Log:
   MFC r211415:
   
   Add -m and -M options to control the minimum and maximum frequency.
   
   PR:		bin/145063
   Submitted by:	Boris Kochergin <spawk at acm.poly.edu>
   Approved by:	rrs (mentor)
 
 Modified:
   stable/7/usr.sbin/powerd/powerd.8
   stable/7/usr.sbin/powerd/powerd.c
 Directory Properties:
   stable/7/usr.sbin/powerd/   (props changed)
 
 Modified: stable/7/usr.sbin/powerd/powerd.8
 ==============================================================================
 --- stable/7/usr.sbin/powerd/powerd.8	Sat Sep 11 14:34:16 2010	(r212472)
 +++ stable/7/usr.sbin/powerd/powerd.8	Sat Sep 11 14:39:53 2010	(r212473)
 @@ -35,6 +35,8 @@
  .Op Fl a Ar mode
  .Op Fl b Ar mode
  .Op Fl i Ar percent
 +.Op Fl m Ar freq
 +.Op Fl M Ar freq
  .Op Fl n Ar mode
  .Op Fl p Ar ival
  .Op Fl P Ar pidfile
 @@ -78,6 +80,10 @@ to use while on battery power.
  Specifies the CPU load percent level when adaptive
  mode should begin to degrade performance to save power.
  The default is 50% or lower.
 +.It Fl m Ar freq
 +Specifies the minimum frequency to throttle down to.
 +.It Fl M Ar freq
 +Specifies the maximum frequency to throttle up to.
  .It Fl n Ar mode
  Selects the
  .Ar mode
 
 Modified: stable/7/usr.sbin/powerd/powerd.c
 ==============================================================================
 --- stable/7/usr.sbin/powerd/powerd.c	Sat Sep 11 14:34:16 2010	(r212472)
 +++ stable/7/usr.sbin/powerd/powerd.c	Sat Sep 11 14:39:53 2010	(r212473)
 @@ -79,7 +79,8 @@ const char *modes[] = {
  #define DEVCTL_MAXBUF	1024
  
  static int	read_usage_times(int *load);
 -static int	read_freqs(int *numfreqs, int **freqs, int **power);
 +static int	read_freqs(int *numfreqs, int **freqs, int **power,
 +		    int minfreq, int maxfreq);
  static int	set_freq(int freq);
  static void	acline_init(void);
  static void	acline_read(void);
 @@ -168,10 +169,10 @@ read_usage_times(int *load)
  }
  
  static int
 -read_freqs(int *numfreqs, int **freqs, int **power)
 +read_freqs(int *numfreqs, int **freqs, int **power, int minfreq, int maxfreq)
  {
  	char *freqstr, *p, *q;
 -	int i;
 +	int i, j;
  	size_t len = 0;
  
  	if (sysctl(levels_mib, 4, NULL, &len, NULL, 0))
 @@ -195,19 +196,30 @@ read_freqs(int *numfreqs, int **freqs, i
  		free(*freqs);
  		return (-1);
  	}
 -	for (i = 0, p = freqstr; i < *numfreqs; i++) {
 +	for (i = 0, j = 0, p = freqstr; i < *numfreqs; i++) {
  		q = strchr(p, ' ');
  		if (q != NULL)
  			*q = '\0';
 -		if (sscanf(p, "%d/%d", &(*freqs)[i], &(*power)[i]) != 2) {
 +		if (sscanf(p, "%d/%d", &(*freqs)[j], &(*power)[i]) != 2) {
  			free(freqstr);
  			free(*freqs);
  			free(*power);
  			return (-1);
  		}
 +		if (((*freqs)[j] >= minfreq || minfreq == -1) &&
 +		    ((*freqs)[j] <= maxfreq || maxfreq == -1))
 +			j++;
  		p = q + 1;
  	}
  
 +	*numfreqs = j;
 +	if ((*freqs = realloc(*freqs, *numfreqs * sizeof(int))) == NULL) {
 +		free(freqstr);
 +		free(*freqs);
 +		free(*power);
 +		return (-1);
 +	}
 +
  	free(freqstr);
  	return (0);
  }
 @@ -410,7 +422,7 @@ usage(void)
  {
  
  	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 %%] [-m freq] [-M freq] [-n mode] [-p ival] [-r %%] [-P pidfile]\n");
  	exit(1);
  }
  
 @@ -424,6 +436,7 @@ main(int argc, char * argv[])
  	const char *pidfile = NULL;
  	int freq, curfreq, initfreq, *freqs, i, j, *mwatts, numfreqs, load;
  	int ch, mode, mode_ac, mode_battery, mode_none;
 +	int minfreq = -1, maxfreq = -1;
  	uint64_t mjoules_used;
  	size_t len;
  
 @@ -440,7 +453,7 @@ main(int argc, char * argv[])
  	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:i:m:M:n:p:P:r:v")) != -1)
  		switch (ch) {
  		case 'a':
  			parse_mode(optarg, &mode_ac, ch);
 @@ -456,6 +469,22 @@ main(int argc, char * argv[])
  				usage();
  			}
  			break;
 +		case 'm':
 +			minfreq = atoi(optarg);
 +			if (minfreq < 0) {
 +				warnx("%d is not a valid CPU frequency",
 +				    minfreq);
 +				usage();
 +			}
 +			break;
 +		case 'M':
 +			maxfreq = atoi(optarg);
 +			if (maxfreq < 0) {
 +				warnx("%d is not a valid CPU frequency",
 +				    maxfreq);
 +				usage();
 +			}
 +			break;
  		case 'n':
  			parse_mode(optarg, &mode_none, ch);
  			break;
 @@ -503,8 +532,10 @@ main(int argc, char * argv[])
  	/* Check if we can read the load and supported freqs. */
  	if (read_usage_times(NULL))
  		err(1, "read_usage_times");
 -	if (read_freqs(&numfreqs, &freqs, &mwatts))
 +	if (read_freqs(&numfreqs, &freqs, &mwatts, minfreq, maxfreq))
  		err(1, "error reading supported CPU frequencies");
 +	if (numfreqs == 0)
 +		errx(1, "no CPU frequencies in user-specified range");
  
  	/* Run in the background unless in verbose mode. */
  	if (!vflag) {
 @@ -539,6 +570,49 @@ main(int argc, char * argv[])
  	freq = initfreq = get_freq();
  	if (freq < 1)
  		freq = 1;
 +
 +	/*
 +	 * If we are in adaptive mode and the current frequency is outside the
 +	 * user-defined range, adjust it to be within the user-defined range.
 +	 */
 +	acline_read();
 +	if (acline_status > SRC_UNKNOWN)
 +		errx(1, "invalid AC line status %d", acline_status);
 +	if ((acline_status == SRC_AC &&
 +	    (mode_ac == MODE_ADAPTIVE || mode_ac == MODE_HIADAPTIVE)) ||
 +	    (acline_status == SRC_BATTERY &&
 +	    (mode_battery == MODE_ADAPTIVE || mode_battery == MODE_HIADAPTIVE)) ||
 +	    (acline_status == SRC_UNKNOWN &&
 +	    (mode_none == MODE_ADAPTIVE || mode_none == MODE_HIADAPTIVE))) {
 +		/* Read the current frequency. */
 +		len = sizeof(curfreq);
 +		if (sysctl(freq_mib, 4, &curfreq, &len, NULL, 0) != 0) {
 +			if (vflag)
 +				warn("error reading current CPU frequency");
 +		}
 +		if (curfreq < freqs[numfreqs - 1]) {
 +			if (vflag) {
 +				printf("CPU frequency is below user-defined "
 +				    "minimum; changing frequency to %d "
 +				    "MHz\n", freqs[numfreqs - 1]);
 +			}
 +			if (set_freq(freqs[numfreqs - 1]) != 0) {
 +				warn("error setting CPU freq %d",
 +				    freqs[numfreqs - 1]);
 +			}
 +		} else if (curfreq > freqs[0]) {
 +			if (vflag) {
 +				printf("CPU frequency is above user-defined "
 +				    "maximum; changing frequency to %d "
 +				    "MHz\n", freqs[0]);
 +			}
 +			if (set_freq(freqs[0]) != 0) {
 +				warn("error setting CPU freq %d",
 +				    freqs[0]);
 +			}
 +		}
 +	}
 +
  	/* Main loop. */
  	for (;;) {
  		FD_ZERO(&fdset);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
