PowerNowd

(c) 2003-2011 John Clemens, <clemej @ alum . rpi . edu>

This program is in no way affiliated with, or endoursed by Advanced Micro Devices

NEW! (6/4/2018) Repository moved to GitLab**
(5/9/2011) public Git repository and autotools (1/27/2008) Version 1.00 Final release
(2/12/2006) Version 0.97 (“Lets try to make SMP work right this time”)
(5/8/2005) Version 0.96 (threads_per_core fix)
(2/5/2005) Version 0.95
(2/8/04) Version 0.90, see the “ChangeLog” section for details

What’s New (6/4/2018) I’ve migrated the primary powernowd repo from GitHub to GitLab:

$ git clone https://gitlab.com/clemej/powernowd.git

The github repository is not longer the authoritative copy, but I may keep it as either an archived version or a mirror of gitlab.

What’s New (5/9/2011) I’ve finally put powernowd under git and posted a repository on github. In doing so I also fixed a few harmless bugs, and created a new ‘autotools’ branch as an excuse to teach myself autotools. You can look for the latest code at:

$ git clone git://github.com/clemej/powernowd.git

What’s New (1/27/2008)
Took me long enough, but this is the final release of powernowd. The ondemand kernel governor seems to be the wave of the future, and “good enough for me”. I do still use it on older kernels, and it’s been rock steady for years. v1.00 is just a couple of small cleanups, and running it through valgrind to clean a couple of pedantic memory issues. PowerNowd does everything it set out to do, and is small, efficient, and complete. Barring any brown-paper-bag style bugs, this will be the final release.

What’s New (2-12-06)
There were quite a few minor SMP bugs in powernowd 0.96. It would work, but not suite optimally. Especially on multi-socket, multi-core systems. Now that I have an Athlon X2, I was able to see what was wrong myself and fix it. There may still be a few bugs, but things should work much better now. I also changed the thread detection logic to use the cpufreq ‘affected_cpus’ file. This should be a lot more reliable.

(5/8/2005)
Just a quick update to 0.96. This fixes the Centrino problem, where the automatic HT detection made Pentium-M systems think they had 0 threads, instead of 1. With this update you should no longer need to run with ‘-c 1’ explicitly set on the command line on those systems. Let me know if there are further issues. For the record, we just default to 1 if we get a weird number. I can’t test this locally, but it looks solid. Also fixed a bug with the new table based code broke on systems without scaling_available_frequencies (eg, PPC). If you had problems with 0.95, please upgrade. 0.96 should return powernowd to the simple “run and forget” daemon it was in 0.90.

(2/5/2005):
Well, it’s been almost exactly a year since 0.90 came out, which was a very solid release. 0.95 represents some major tinkering with the code. I’ve moved to using a table-based approach for everything now..the table of available speeds is either gotten from scaling_available_frequencies, or it’s constructed from min, max, and step. 0.95 should also handle Intel HT (and other multi threaded / multi-cored processors) correctly. I’ve had most of this done since June, and have been using it locally and it’s been working fine, but i don’t have any HT systems to test, so caveat emperor, and any testers, please let me know.

I’ve decided against adding upper and lower limits, because there’s no way to do it intuitively in all cases. CPUFreq drivers always round up to the next available speed, and for drivers that don’t support scaling_available_frequencies, there’s no way to know what that is. For example, my PPC has 2 states, 400 and 900Mhz. PPC doesn’t have the s_a_f file, so powernowd guesses. If i were to limit the upper speed to say, 401Mhz, the system would in reality still toggle between 400 and 900Mhz, because 400 would be the low, but telling the driver to use 401Mhz will round up to 900Mhz. It’s easy to solve with the s_a_f file, and i may do that for 1.0, but 0.95 doesn’t have it. Feel free to hack away yourself if you like.

I’m also here to say that this past year has proven to me that I’m a horrible maintainer :). I will take powernowd to it’s 1.0 release, and then other than a bugfix release or two, I won’t be taking it any further. If anyone wishes to build upon powernowd, you’re not only legally free to do so thanks to the GPL, but you also have my blessing. My only request is that you call your work v2.0, and that you give me some credit buried somewhere in a readme :).

Finally, I’d like to thank all the people who have sent me patches and support over the past 2 years, many of whom I never had time to respond to, so please consider this my deepest thanks. I may not agree with all the ideas, but keep ‘em coming, I do read and think about each one. 0.95 is out, let me know if it works for you!

Overview:

This is a very simple program that will adjust the speed of your CPU depending on system load. It works as a client of the CPUFreq driver. It is designed for use with CPU’s supporting AMD’s PowerNow power management scheme, as it’s algorithm works better if there are more then two CPU speeds available. (aka, ARM, AMD K6/K7, Via C3, and Crusoe as opposed to traditional Intel and Ultrasparc).

This program is essentially a simple client to the CPUFreq sysfs interface. This means that you -need- to be running Linux v2.5 or later that includes the sysfs interface. This daemon will -not- work with the CPUFreq driver interface included in Linux v2.4. Feel free to write your own daemon to support that if you like; you can even use this as a starting point. If there’s enough clamoring for it, then maybe I’ll whip up something. You also need a CPU that supports frequency scaling and supports the CPUFreq interface. This code has been tested on various AMD and PPC processors

I have been running this daemon on my AMD laptop for over 2 years with no problems to report, and it’s nice that my laptop remains cool unless I’m really doing something intensive, like watching DivX movies, without me having to manually intervene and set the speed. I just recently bought an Apple iBook G3, and powernowd-0.80 worked flawlessly on it right out of the box.

Features

This daemon’s goal is simplicity and speed. It doesn’t try and make too many decisions for you. That’s its beauty, but it may not be what everyone’s looking for. Some of the features this daemon has:

  • One, simple heuristic to determine CPU load: “user + sys” time.
  • Ignore “niced” programs (setiathome, itself, etc). In my mind this is consistent with what is meant when someone ‘nice’s a program to begin with. (configurable in v0.85+)
  • Designed for CPU’s that support more then two speed states, but works well with anything.
  • Very fast, low overhead /proc/stat gathering (method stolen from procps).
  • Supports SMP
  • Will automatically switch to ‘userspace’ governor.
  • Care taken to make the code non-root exploitable (but please audit for yourself first!)
  • Frequency step size is configurable (default to 100MHz/step)
  • 4 different behavioral modes to choose from (SINE, AGGRESSIVE, PASSIVE, LEAPS), which determine the behavior when the load changes. Configurable from the command line.
  • Written in C for speed and simplicity.
  • Logging to stdout or syslog
  • Configurable Polling frequency in milliseconds (defaults to 1s)
  • Configurable highwater/lowwater marks for CPU usage. (defaults 80/20%)

Many similar daemons use other methods to determine what speed to use, such as battery status, AC status, temperature, fan status, etc. They all have their place. I however feel that in the grand scheme of things none of the above matters. When I’m not using my CPU, I don’t care if it’s running at a slower speed. When I -am- using my CPU, I only need it to be fast enough to handle the task at hand without hiccuping. And when I’m taxing my CPU, I want it running full speed. That’s all this daemon does, monitor CPU load and adjust the speed accordingly. Since in all reality my CPU is idle 99% of the time (or playing mp3’s which it can easily do at it’s lowest speed rating), this by definition leads to low power usage, low temperatures, low speed fans, and better battery life.

Getting and Installing PowerNowd:

You can download powernowd from here:

LATEST: powernowd-1.00.tar.gz

Older releases:
v0.97: powernowd-0.97.tar.gz
v0.96: powernowd-0.96.tar.gz
v0.95: powernowd-0.95.tar.gz
v0.90: powernowd-0.90.tar.gz
v0.85: powernowd-0.85.tar.gz
v0.80: powernowd-0.80.tar.gz
v0.75: powernowd-0.75.c

Extract the archive, and read the README file for more info. However, a quick “make”, and (as root) “make install” should be all you need.

Because powernowd needs to access device files in sysfs, it needs to be run as root. Some care has been taken to make the daemon non-exploitable, but I’m sure it might be somehow. So don’t use his on any valuable servers until you do your own auditing of the code!

To run with the defaults, simply log in as root and type:

# /usr/sbin/powernowd

Usage

powernowd -h’ will print out some usage information:

As root:

    powernowd <options>

Available Options:
        -h      Print this help message
        -d      Don't detach from terminal (default is to
                detach and run in the background)
        -v      Increase output verbosity, can be used more than once.
        -q      Quiet mode, only emergency output.
        -n      Include 'nice'd processes in calculations
        -m #    Modes of operation, can be 0, 1, 2, or 3:
                0 = SINE, 1 = AGGRESSIVE (default),
                2 = PASSIVE, 3 = LEAPS
        -s #    Frequency step in kHz (default = 100000)
        -p #    Polling frequency in msecs (default = 1000)
        -c #    Specify number of threads per power-managed core
        -u #    CPU usage upper limit percentage [0 .. 100, default 80]
        -l #    CPU usage lower limit percentage [0 .. 100, default 20]

The defaults are what work best on my machine (see specs here).

ChangeLog

(7-13-03)
v0.75   Initial Release

(8-9-03)
v0.80   Better error reporting/handling (some ideas from Warren Togami 
      <warren@togami.com>)
    Added syslog output support
    Added Makefile, README, LICENSE, etc.
    Remove find_mount() function (sysfs is supposed to be in /sys)
    Added -s and -p options to override default frequency step and polling
      frequency.
    Added -u and -l options to override high/low water marks.
    Fixed bug where we were defaulting to SINE, not AGGRESSIVE.

(11-30-03)
v0.85   Better error text, more helpful then "couldn't open file".
    Fixed a few memory initialization bugs reported by users. 
    Added -n option to force inclusion of niced processes.
    Added -b option and SIGUSR1/2 support for pausing/restarting the
      daemon.  See README, section 'PAUSING'.
    Added code to handle buggy Athlons, but ifdef'd out because i think
      the bug has been fixed, so it isn't needed anymore. 
      Fixed up a few of my more egregious spelling mistakes.

(2-8-04)
v0.90   Added support for drivers (longhaul) which report speed values in 
          MHz instead of KHz.
        Removed -b option and PAUSING support.
    Removed dead code to work around buggy Athlon bios's, the driver now
          does this correctly.
        Added sample powernowd init script to show how to emulate old PAUSE
          behavior. 
        Spell checked the README and web page, finally ;)
    Added LEAPs mode and verbosity patches from Hans Ulrich Niedermann.
    Fixed up verbosity mode/printf/syslog infrastructure.

(2-5-05)
v0.95   It's been an unacceptably long time between updates, my apologies..
        it's been an interesting year.

        Added support for scalaing_available_frequencies, and moved to a
          table based approach (driver not supporting s_a_f will have a
          table built internally based upon detected min/max and step).
        Proper infrastructure for handling HT (and other SMT/CMP procs).  
          UNTESTED.  I hope it works.  Consider this part Beta.

(5-8-05)
v0.96   Fixed the Centrino (and a few others) bug about "ncpus not a multiple 
          of threads_per_core!".. We now just default to 1 if that's the case.
        Fixed bug on drivers that don't support scaling_available_frequencies
          (PPC). 
        Cleaned up error reporting a bit more.

(2-12-06)
v0.97   Better handling of multi-core/HT cpus.
        Uses affected_cpus file sysfs file.  
        Fix Segfault on exit on SMP systems.
        Documentation updates.

(1-27-08)
v1.00   Cleanups for the 1.00 release.
    Use strtoll instead of strtol when reading cputime. (from Debian)
    Valgrind clean.
    Added 'make clean' target.

Todo

  • Nothing left

More Info

Hans Ulrich Niedermann has been working on better algorithms for CPU management. Some throughts can be found here.

You can download the latest version of powernowd from http://www.deater.net/ john/powernowd.html

You can find out more information about me at http://www.deater.net/john/, and my view my Resume.

I welcome comments and contributions.