HOWTO PowerNow!

From Gentoo Linux Wiki

Jump to: navigation, search
This article is part of the HOWTO series.
Installation Kernel & Hardware Networks Portage Software System X Server Gaming Non-x86 Emulators Misc


Contents

[edit] Introduction

PowerNow! or Cool'n'Quiet are marketing names for technology supported by newer AMD processors which allows you to decrease the CPU's clock speed and VCore when your system is idle or under low load. This can lead to less CPU dissipated heat, lower fan speed, and lower noise levels. This will likely decrease power consumption too.

To check if your currently running kernel supports PowerNow!, do dmesg | grep powernow

Example output:

powernow-k8: Found 1 AMD Athlon 64 / Opteron processors (version 1.00.09e)
powernow-k8:    0 : fid 0xc (2000 MHz), vid 0x2 (1500 mV)
powernow-k8:    1 : fid 0xa (1800 MHz), vid 0x6 (1400 mV)
powernow-k8:    2 : fid 0x2 (1000 MHz), vid 0x12 (1100 mV)

or

powernow-k8: Found 1 AMD Athlon 64 / Opteron processors (version 1.50.4)
powernow-k8:    0 : fid 0x2 (1000 MHz), vid 0x12 (1100 mV)
powernow-k8:    1 : fid 0xa (1800 MHz), vid 0x6 (1400 mV)
powernow-k8:    2 : fid 0xc (2000 MHz), vid 0x2 (1500 mV)


Note: Your frequency and voltage output may vary depending on your processor type (Example is a AMD 3000+ socket 754)


Note: If you do not get any result, it is still possible that your processor supports PowerNow! In this case follow the guide and check later whether CPU frequency really changes.


If you get an error like this:

powernow-k8: BIOS error - no PSB or ACPI _PSS objects

Then probably you either:

  • Don't have a BIOS that supports Cool'n'Quiet/PowerNow!
    • check for BIOS updates
  • Don't have the Cool'n'Quiet enabled in the BIOS.
  • Have Cool'n'Quiet enabled, but you are overclocking. It seems that some (possibly all) BIOSes disable CnQ when you overclock, as CnQ involves freq-voltage combinations.
    • Try with BIOS defaults. Even User-Define with stock values causes a problem in some systems.

People have also reported that they get this error even if the option is set correctly. You should ensure your BIOS has support for the feature, since the linux driver needs frequency tables (PSB) or ACPI methods (_PSS) to work. Then try if upgrading your BIOS solves the issue. If you have this error, make sure that you have ACPI Processor support enabled in your kernel, the non-ACPI ways is disabled on SMP bioses (including those that support X2 processors) and deprecated by AMD.

[edit] Step 1 - Make sure you have the right options in the kernel

Linux Kernel Configuration: CPU Frequency scaling for AMD64
Power management options  --->
 CPU Frequency scaling  --->
  [*] CPU Frequency scaling
   [*] ACPI Processor P-States driver
   <*> 'conservative' cpufreq governor 
   <*> AMD Opteron/Athlon64 PowerNow!
   


Note: ACPI Processor P-States driver is required for the powernow driver to be able to fallback to ACPI methods if your BIOS does not contain the PSB frequency tables. Check this option if you got the "BIOS error - no PSB or ACPI _PSS objects" message in the kernel log.


Note: if conservative governor is not available, you can use ondemand instead. Desktop users should stick to ondemand as it will scale CPU levels hard (e.g., 50% to 100%), conservative scales CPU softer (e.g., 50% to 70% to 85% to 100%).


Of course you have to recompile your kernel.

After rebooting your new kernel check the available governors:

 cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors

Example output (both ondemand and conservative compiled into kernel):

ondemand conservative powersave performance

Edit: I had to load in the modules manually:

modprobe cpufreq_ondemand
modprobe cpufreq_userspace
modprobe cpufreq_powersave
modprobe cpufreq_conservative

To load them automaticaly run as root:

echo cpufreq_ondemand >> /etc/modules.autoload.d/kernel-2.6

Example output (only performance compiled into kernel):

ondemand performance

For sempron users: currently you must apply the kernel patch at the ubuntu forums for frequency scaling to work. (Fixed in 2.6.11-rc2)

[edit] Step 2 - Set it up in one line

First temporarily set up "conservative" (or where not available, "ondemand") as the cpufreq governor:

# echo conservative > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

Now have a look at your processor's frequency:

# cat /proc/cpuinfo
Code: Example output of cat /proc/cpuinfo
processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 15
model           : 12
model name      : AMD Athlon(tm) 64 Processor 3000+
stepping        : 0
cpu MHz         : 1999.950
cache size      : 512 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 1
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush 
mmx fxsr sse sse2 pni syscall nx mmxext lm 3dnowext 3dnow
bogomips        : 1982.46

Kind of a bad example - What you should see is that "cpu MHz" is at the lowest available freqency from the dmesg-output above. On my computer the cpu-frequency does not change in /proc/cpuinfo - but have a look at the bogomips.
On modern computers the bogomips is expected to be at least twice as high as the cpu-frequency in MHz.
You can also take a look with

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq

to watch the current frequency of your cpu.

Let's test the cpu-behaviour under load. To do that open another shell and type cat /dev/urandom > /dev/null which should bring your processor to 100% load.

Note: you may have to wait for some time until the frequency will increase.

Again have a look at your processor's frequency:

processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 15
model           : 12
model name      : AMD Athlon(tm) 64 Processor 3000+
stepping        : 0
cpu MHz         : 1999.950
cache size      : 512 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 1
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush
mmx fxsr sse sse2 pni syscall nx mmxext lm 3dnowext 3dnow
bogomips        : 3568.43

What you should see is that "cpu MHz" is at the highest available value from the dmesg-output. Here in this example the only hint that something has changed is the bogomips value which has roughly doubled.
I'll take this as a "works for me" :)
When stopping the "cat" command from above your cpu-frequency should reach it's minimum value within a few seconds.

To make the governor setup permanent add the following line to your /etc/conf.d/local.start

File: /etc/conf.d/local.start
echo conservative > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

[edit] Shell Script

I hacked up in ten minutes a shell script to check and set the governor status. It is minimal and tailored out on my configuration, but it could be rapidly expanded.

#!/bin/sh
 
SYSPATH=/sys/devices/system/cpu/cpu0/cpufreq
AVAL_GOV=$(<$SYSPATH/scaling_available_governors)

if [ -z "$1" ]; then
    echo "Current governor:    "$(<$SYSPATH/scaling_governor)
    echo "Current frequency:   "$(expr $(<$SYSPATH/scaling_cur_freq) / 1000)" MHz"
    echo
    echo "Available governors: "$AVAL_GOV
else
    if [ "$1" = "--help" ]; then 
        echo "Usage: coolnquiet [ set [governor] | stats [times|trans] ]"
    elif [ "$1" = "set" ]; then
        if [ -z "$2" ]; then
            echo "Specify the new governor."
            echo "Available governors: "$AVAL_GOV
        else
            VALID=0
            for i in $AVAL_GOV; do
                if [ "$2" = "$i" ]; then
                    echo $i > $SYSPATH/scaling_governor
                    echo "Set governor \"$i\"."
                    VALID=1
                    break
                fi
            done
            if [ $VALID = 0 ]; then
                echo "Governor unavailable."
            fi
        fi
    elif [ "$1" = "stats" ]; then 
        if [ -z "$2" ]; then 
            echo "Command \"stats\" requires an argument."
        elif [ "$2" = "time" ]; then
            echo "Freq.   Time"
            cat $SYSPATH/time_in_state
        elif [ "$2" = "trans" ]; then
            echo "Transitions: "$(<$SYSPATH/stats/total_trans)
        fi
    fi
fi
exit 0

[edit] Extras

[edit] Nice processes

By default, the kernel will not consider processes running niced when calculating CPU load - so if you nice a process, such as distccd or the MythTV job queue, your CPU won't increase its clock speed even for a very CPU-intensive task.

You can override default setting with command below (change <governor_name> to governor that is being used: e.g., .../cpu0/cpufreq/ondemand/ignore_nice).

Code:
 echo 1 > /sys/devices/system/cpu/cpu0/cpufreq/<governor_name>/ignore_nice
Note: The name has changed in gentoo-sources-2.6.16-r7!

Its now: /sys/devices/system/cpu/cpu0/cpufreq/<governor_name>/ignore_nice_load It must be set to 0 for the same effect!

Note: if this change does not take effect, try switching to ondemand governor.
Note: Using userspace governor you can't set ignore_nice_load.


This setting will not survive system reboot, so add this line to /etc/conf.d/local.start.

Please note that this only affects the in-kernel governor. Some userspace daemons, such as CPUDyn, provide the same facility. Check your CPU governors' documentation. Also note that as of kernel 2.6.16, the ondemand governor no longer honours the ignore_nice flag, substituting it with the ignore_nice_load flag. This is actually an inversion of previous ondemand functions, and echoing 1 to this file will actually cause clock speed not to rise when the system comes under load from a niced process. The upshot of this all is that if you're running 2.6.16 or later, you can ignore this whole subsection :)

[edit] Too frequent frequency changes

If your frequency changes too frequently, put greater number (number of seconds * 10^6) in /sys/devices/system/cpu/cpu0/cpufreq/<governor_name>/sampling_rate. Example (15 s):

Code:
echo "15000000" > /sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate

Happy energy-saving!

[edit] More info

http://forums.gentoo.org/viewtopic.php?p=1970584 - this article has been created based on this forum thread http://finkalinux.blogspot.com/2007/07/howto-powernow-un-dia-como-otro.html - An approximated translation to spanish of this howto

[edit] PowerNow! on X2 dual core CPU(s) - socket 939

Works, but likely won't work without compiling the following into the kernel (among other options as mentioned above):

Linux Kernel Configuration: CPU Frequency scaling for AMD64
[*] ACPI Processor P-States driver

For this, the ACPI Processor module, available from the ACPI configuration page also needs to be compiled in - having that as a loadable module would only permit you to compile the ACPI Processor P-States driver as a module as well and that does not seem to be sufficient for a fallback.

Note: X2 CPU frequency scaling was tested on an ASUS A8N-E with a 2.6.16.1 kernel.

Also note that Processor 1 gets symlinked to Processor 0 for the scaling, so of course any frequency changes will apply to both CPU cores, i.e. independent scaling is asking too much and all the examples that mention cpu0 will apply to an X2 dual core setup as well.

[edit] Alternative

Powerthend is another tool for automatically changing the cpu frequency. It's based on the powernow daemon, but has a tuned algorithm.

PowerNowd (sys-power/powernowd), a simple and fast tool. [1]

CPUFreq Utils (sys-power/cpufrequtils) is a package to set the governor at boot or via command line. Has some problems with hanging the CPU during reboot on some AMD systems


[edit] Weblink

  • http://powerthend.scheissname.de/ ----> this worked for me only had to change some defaults settings like 100% on limits and the control of niceness process as is said in this howto, other than that great app. --by Greboide
Note: I'm using PowerThend daemon, and do not need to set ignore_nice_load because PowerThend is in userspace and that parameter can't be set! (I'm using gentoo-2.6.19-r5 kernel)
Personal tools