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>