Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 1 Jul 2008 19:25:32 +0900 (JST)
From:      Yoshisato YANAGISAWA <osho@pcc-software.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/125141: change request of /usr/sbin/powerd to adapt SMP environment.
Message-ID:  <200807011025.m61APWdl041147@ai.pcc-software.org>
Resent-Message-ID: <200807011050.m61Ao4CD070948@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         125141
>Category:       bin
>Synopsis:       change request of /usr/sbin/powerd to adapt SMP environment.
>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:   Tue Jul 01 10:50:03 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Yoshisato YANAGISAWA
>Release:        FreeBSD 7.0-RELEASE amd64
>Organization:
>Environment:
System: FreeBSD ai.pcc-software.org 7.0-RELEASE FreeBSD 7.0-RELEASE #3: Wed May 21 22:36:46 JST 2008 osho@ai.pcc-software.org:/usr/obj/usr/src/sys/AI amd64


	
>Description:
	Since an idle time got by "sysctl kern.cp_time" is the average
	idle time of all the CPUs, powerd will not increase frequency
	when one of the CPUs is busy and the others are not.
	I guess many people will recognize this problem if they uses
	the system that has more than 4 CPUs because the default
	value of the -r option is 65.

	
>How-To-Repeat:
	Just run powerd on the system which has more than 4 CPUs,
	and make one of the CPUs busy while the others are idle.
	
>Fix:

	
	Consider the number of CPUs.  I made a following patch to recognize
	the number of CPUs.

	Another approach to solve this problem is using idle time of
	the process [idle:cpu0], [idle:cpu1], [idle:cpu2], and [idle:cpu3]
	instead of sysctl kern.cp_time.  However, since it requires drastic
	change of code, I avoided it.

--- powerd.c.bak	2007-06-14 04:05:11.000000000 +0900
+++ powerd.c	2008-07-01 19:04:41.000000000 +0900
@@ -190,6 +190,16 @@
 }
 
 static int
+read_ncpu(int *ncpu)
+{
+	size_t len = sizeof(*ncpu);
+	if (sysctlbyname("hw.ncpu", ncpu, &len, NULL, 0))
+		return (-1);
+
+	return (0);
+}
+
+static int
 set_freq(int freq)
 {
 
@@ -366,7 +376,7 @@
 {
 	struct timeval timeout;
 	fd_set fdset;
-	int nfds;
+	int nfds, ncpu;
 	struct pidfh *pfh = NULL;
 	const char *pidfile = NULL;
 	long idle, total;
@@ -453,6 +463,9 @@
 	if (read_freqs(&numfreqs, &freqs, &mwatts))
 		err(1, "error reading supported CPU frequencies");
 
+	if (read_ncpu(&ncpu))
+		err(1, "error reading # of cpus");
+
 	/* Run in the background unless in verbose mode. */
 	if (!vflag) {
 		pid_t otherpid;
@@ -592,7 +605,8 @@
 			if (freqs[i] == curfreq)
 				break;
 		}
-		if (idle < (total * cpu_running_mark) / 100 &&
+		if (idle < ((total - total / ncpu) + 
+			(total * cpu_running_mark) / (100 * ncpu)) &&
 		    curfreq < freqs[0]) {
 			i -= 2;
 			if (i < 0)
@@ -605,7 +619,8 @@
 			if (set_freq(freqs[i]))
 				warn("error setting CPU frequency %d",
 				    freqs[i]);
-		} else if (idle > (total * cpu_idle_mark) / 100 &&
+		} else if (idle > ((total - total / ncpu) + 
+			(total * cpu_idle_mark) / (100 * ncpu)) &&
 		    curfreq > freqs[numfreqs - 1]) {
 			i++;
 			if (vflag) {
>Release-Note:
>Audit-Trail:
>Unformatted:



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