CPU負荷によってCPUスピードを調整して省電力化

linuxにはcpuspeedというものがあり、centosには標準で入っているので、chkconfigでonにしてあげれば動きます(/sbin/chkconfig cpuspeed on)
これは、CPU負荷が低い時には、CPUスピード(クロック数 Hz)を低くして、アイドル状態の消費電力を低くしてくれます。
またCPU負荷が高くなったときでも、3GHzのCPUで、2GHzまでしか使わないように抑制して負荷が高いときの電力消費も抑えることができます。

この設定ファイルはcentosの場合下記の場所にあります。

/etc/sysconfig/cpuspeed


このファイルの中のMAX_SPEEDやMIN_SPEEDに値を入れれば、その値のクロック数で動くようになります。
ただし、CPUに合った値を指定しないとうまく動かないので、

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

として出てきた数値の中から選択する必要があります。

うちのAMD 4850eでは

2500000 2400000 2200000 2000000 1800000 1000000

と出てきたので、1GHzから2.5GHzまで指定可能となります。

これで/etc/sysconfig/cpuspeedに下記の箇所を書き換えれば

MAX_SPEED=2000000

負荷が上がっても2GHzまでしかCPUを上げません。MIN_SPEEDの方はデフォルトで最低値(うちの環境なら1000000)になっているので特に値は変えてません。

自宅のファイルサーバは常時稼動ですが、カーネルコンパイルとかそいう時のみに負荷がMAXまで上がります。でも別に数分ぐらいの差であればコンパイルも待ってて問題ないので、省電力の方に倒して最大2GHzとしてます。


それで、負荷が高い場合と低い場合でCPUの状態を見ると、

負荷が低い場合
cat /proc/cpuinfo | grep Hz

cpu MHz         : 1000.000
cpu MHz         : 1000.000
負荷が高い場合
cat /proc/cpuinfo | grep Hz

cpu MHz         : 2000.000
cpu MHz         : 2000.000

見事、最大2GHzにおさえられています。

CentOSでCPU温度を測りたい

linuxでCPU温度を計測する際には、lm_sensorsというソフトを入れればいいんですが、yum install lm_sensorsとしてインストールしたけど、エラーでうまく動きませんでした。

というわけで最新版を下記からダウンロードしてコンパイルしてインストール(lm-sensors 3.0.3)
http://www.lm-sensors.org/

configureファイルがないので、いきなりmakeします

make 
make install

これで/usr/local/bin, /usr/local/sbin以下にlm_sensorsがインストールされます。

まずは/usr/local/sbin/sensors-detectを実行して、自分のハードウェア環境をスキャンして定義ファイルを作ります。
ほとんどリターンでOK

sensors-detectの完了画面で、下記のようにファイルを修正する指示があるので、そのようにする。ただし、下記の内容は各ハードウェアによって異なるので、sensors-detectが出力した結果をコピペすること(cut hereという文字があるのでそれを目印にコピペ)

vi /etc/modprobe.confで下記を追加

# I2C module options
alias char-major-89 i2c-dev
vi /etc/rc.localで下記を追加

# I2C adapter drivers
modprobe i2c-piix4
# I2C chip drivers
modprobe lm92
# sleep 2 # optional
/usr/bin/sensors -s # recommended


lm_sensorsデーモンが起動されるようにする

/sbin/chkconfig lm_sensors on


/etc/rc.d/init.d/lm_sensorsを編集して、sensorsコマンドのパスを書き換える

PSENSORS=/usr/local/bin/sensors


最後に、共有ライブラリにsensorsのライブラリを追加します。sensorsのライブラリは/usr/local/lib以下にあります。

vi /etc/ld.so.conf.d/local.confで下記を記載

/usr/local/lib

下記コマンドを実行して共有ライブラリパスに追加
/sbin/ldconfig

reboot

リブートしたら、/usr/local/bin/sensorsと打つと下記のように温度が出力される

k8temp-pci-00c3
Adapter: PCI adapter
Core0 Temp:   +0.0°C
Core0 Temp:   -1.0°C
Core1 Temp:   +0.0°C
Core1 Temp:  -11.0°C

ただ、カーネルを再構築する前は
上記の内容しか表示されなかったので、カーネルを最新のもので再構築したらうまく表示されるようになった。

k8temp-pci-00c3
Adapter: PCI adapter
Core0 Temp:   +0.0°C
Core0 Temp:   -1.0°C
Core1 Temp:   +0.0°C
Core1 Temp:  -11.0°C

it8718-isa-0228
Adapter: ISA adapter
in0:         +0.98 V  (min =  +0.00 V, max =  +4.08 V)
in1:         +1.94 V  (min =  +0.00 V, max =  +4.08 V)
in2:         +3.39 V  (min =  +0.00 V, max =  +4.08 V)
in3:         +3.02 V  (min =  +0.00 V, max =  +4.08 V)
in4:         +3.02 V  (min =  +0.00 V, max =  +4.08 V)
in5:         +3.26 V  (min =  +0.00 V, max =  +4.08 V)
in6:         +4.08 V  (min =  +0.00 V, max =  +4.08 V)   ALARM
in7:         +1.78 V  (min =  +0.00 V, max =  +4.08 V)
in8:         +3.07 V
fan1:        855 RPM  (min =    0 RPM)
fan2:          0 RPM  (min =    0 RPM)
fan3:          0 RPM  (min =    0 RPM)
fan4:          0 RPM  (min =    0 RPM)
temp1:       +31.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp2:       +20.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermal diode
temp3:       +29.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
cpu0_vid:   +1.550 V

CentOSカーネルコンパイルメモ

下記から最新カーネルダウンロード
ftp://ftp.kernel.org/pub/linux/kernel/v2.6/

/usr/src/kernels以下に展開

インストール時のconfigをコピー
cp /usr/src/kernels/2.6.18-92.el5-x86_64/.config /usr/src/kernels/linux-2.6.28/

インストール時のconfigを最新カーネルに引継ぎ
make oldconfig

カーネルオプションの選択
make menuconfig

2回目以降のコンパイルは下記を実行
make clean

カーネルインストール(&&で繋げると、エラーが発生したら以降のコマンドは実行されない)
make -j2 bzImage && make -j2 modules && make modules_install && make install

-j2で2コアを使うという意味です。クアッドコアの人は-j4で。


vi /etc/grub.conf
default=0
に変更して新カーネルがデフォルトでブートされるように変更

reboot

参考
http://www.geocities.jp/tatsus490824/kernel_rebuild.html

カーネル再構築後にiptablesでエラー

CentOS5.2のデフォルトカーネルカーネル2.6.18-92.el5-x86_64から最新カーネル2.6.28に変更してブートしたところ、iptablesで下記のエラーが発生。

iptables-restore: line 20 failed 

/etc/sysconfig/iptablesの中を見ると、20行目にCOMMITという文字が

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT

色々と調査したところ、下記の記事がヒット
http://www.djatlantic.net/?p=254
http://help.lockergnome.com/linux/iptables-restore-barfs-COMMIT--ftopict282705.html


COMMITが悪いんじゃなくて、その前にある-mオプションで読み込むモジュールがカーネルに組み込まれてないのが原因でした。

とりあえず、再度コンパイル
cd /usr/src/kernels/linux-2.6.28/

make menuconfig
を実行して下記のように遷移してモジュールを有効にしていきます。

Networking support → Networking options 
→ Network packet filtering framework (Netfilter)
→ Core Netfilter Configuration

<M> Netfilter connection tracking support 
 [*]   Connection tracking flow accounting
 [*]   Connection mark tracking support
 [*]   Connection tracking security mark support
 [*]   Connection tracking events

<M>   "state" match support

ここでstateを有効にしたので、iptablesで指定した-m stateで起こった問題が解決しました。


それと、/etc/sysconfig/iptables-configで下記のモジュールを呼んでいるので、それもカーネルに組み込みが必要でした。

 IPTABLES_MODULES="ip_conntrack_netbios_ns"

make menuconfigで下記も有効に

Networking support → Networking options 
→ Network packet filtering framework (Netfilter)
→ IP: Netfilter Configuration

<M> IPv4 connection tracking support (required for NAT)
<M>   Packet filtering    
<M>     REJECT target support
<M>   LOG target support     
<M>   ULOG target support    
<M>   Full NAT
  <M>     MASQUERADE target support
<M>   Security table


これで再度コンパイルしたらiptablesが無事に稼動しました。やれやれ。