<

Avoiding CPU speed scaling in modern Linux distributions. Running CPU at full speed Tips.

Published on
40,110 Points
33,610 Views
5 Endorsements
Last Modified:
Approved
If you have a server on collocation with the super-fast CPU, that doesn't mean that you get it running at full power.

Here is a preamble. When doing inventory of Linux servers, that I'm administering, I've found that some of them are running on lower CPU speed, then they could. This can be easily checked with this command:

grep -E '^model name|^cpu MHz' /proc/cpuinfo

Open in new window


What you can see:

model name      : Intel(R) Core(TM) i7 CPU         920  @ 2.67GHz
cpu MHz         : 1600.000
...

Open in new window

or
model name      : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz
cpu MHz          : 1596.000
...

Open in new window

or even
model name      : Intel(R) Core(TM)2 CPU          4400  @ 2.00GHz
cpu MHz         : 1000.000
model name      : Intel(R) Core(TM)2 CPU          4400  @ 2.00GHz
cpu MHz         : 600.000

Open in new window


Oops, we are paying for 2 Core 2Ghz CPU that runs on 600Mhz on one core and 1000Mhz on another!!!

There will be other lines for all the CPUs/cores/threads, probably with the same values.

This feature is nice, if we are running workstation, but what I've noticed, we do have the same CPU throttling on Ubuntu Server 10.04 builds and on CentOS 5.3, 5.4 and 5.5 builds (thus on RedHat too).

After hours of digging google, I've found that:
- this problem is very common
- there are several bug reports about this issue
- this is not BIOS settings problem, because on dual boot systems, CPU runs at full speed on Windows
- there are no 100% working solutions or they are too difficult to find
- this is not a bug, but a 'feature' of the new kernels, it is implemented differently on 2.6.18 (CentOS) and 2.6.32 (Ubuntu).

Here is a tip how to disable it on running system:

1) Check that 'kondemand' thread is running, run as root:  "pgrep -lf ondemand"

the output should be like:
[root@boston07 ~]# uname -a
Linux boston07 2.6.18-164.6.1.el5 #1 SMP Tue Nov 3 16:18:27 EST 2009 i686 i686 i386 GNU/Linux
[root@boston07 ~]# pgrep -lf ondemand
1444 kondemand/0
1445 kondemand/1

Open in new window


2) Check that current cpu speed differs from the maximum:

[root@boston07 ~]# grep -E '^model name|^cpu MHz' /proc/cpuinfo
model name      : Intel(R) Core(TM)2 CPU          6600  @ 2.40GHz
cpu MHz         : 1596.000
model name      : Intel(R) Core(TM)2 CPU          6600  @ 2.40GHz
cpu MHz         : 1596.000

Open in new window


3) Change CPU governor from 'ondemand' to 'performance' for all CPUs/cores, run as root:
for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do [ -f $CPUFREQ ] || continue; echo -n performance > $CPUFREQ; done

Open in new window


4) Check that your changes have been applied:

[root@boston07 ~]# grep -E '^model name|^cpu MHz' /proc/cpuinfo
model name      : Intel(R) Core(TM)2 CPU          6600  @ 2.40GHz
cpu MHz         : 2394.000
model name      : Intel(R) Core(TM)2 CPU          6600  @ 2.40GHz
cpu MHz         : 2394.000

Open in new window


5) If you are running 'cpuspeed', 'cpufreqd', 'powerd' or other daemons, that can control CPU stepping, just stop them, if you really need to run your system on 100% of the CPU speed.
On CentOS:
# service cpuspeed stop

Open in new window


6) On Linux 2.6.32 (On RedHat 6, and Oracle Unbreakable Linux 6) remove CPU scaling kernel modules:
# lsmod | grep ondemand
cpufreq_ondemand        8764  0 
freq_table              3751  2 cpufreq_ondemand,acpi_cpufreq
# rmmod cpufreq_ondemand acpi_cpufreq freq_table

Open in new window


Ensure that no 'kondemand' kernel threads are running:
# pgrep -lf kondemand
#

Open in new window


7) To make changes permanent (on reboot):

- On Ubuntu, modify /etc/init.d/ondemand script:

change this
echo -n ondemand > $CPUFREQ

Open in new window

to this:
echo -n performance > $CPUFREQ

Open in new window


OR ALTERNATIVELY just remove all references to ondemand from /etc/rc?.d/
rm -f /etc/rc?.d/S99ondemand

Open in new window

- On CentOS, just create a new script /etc/init.d/ondemand:
#! /bin/bash
#
# ondemand sets cpu govermor
#
# chkconfig: 2345 10 90
#
# description: Set the CPU Frequency Scaling governor to "performance"
#
### BEGIN INIT INFO
# Provides: $ondemand
### END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin

case "$1" in
    start)
        for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
        do
                [ -f $CPUFREQ ] || continue
                echo -n performance > $CPUFREQ
        done
        ;;
    restart|reload|force-reload)
        echo "Error: argument '$1' not supported" >&2
        exit 3
        ;;
    stop)
        ;;
    *)
        echo "Usage: $0 start|stop" >&2
        exit 3
        ;;
esac

Open in new window

then enable it:
chmod +x /etc/init.d/ondemand
chkconfig --add ondemand
service ondemand restart

Open in new window


I'm using 'ondemand' name of the script, this may be a little bit misleading (because really it is a 'performance'), but you may change it.

Here are some useful links (just FYI, don't try to install cpufreq-set, cpufreq-get or other utilities, they will also install themselves as daemons, that will control your cpu speed regardless of your cpu governor settings):

1.  http://www.redhat.com/docs/wp/performancetuning/powermanagement/cpufreq_governors.html

2. http://ego.randomwalk.in/blog/2008/04/04/cause-and-effect/


Regards,
Arty
5
Author:Arty
Ask questions about what you read
If you have a question about something within an article, you can receive help directly from the article author. Experts Exchange article authors are available to answer questions and further the discussion.
Get 7 days free