Core2 Quad で VMware Server の時刻が進む件は解決した
VMware Server 1.0.4 on Core2Quad で guest の時刻が進みまくり - daily dayflowerという現象があったのですが,なんとか解決にこぎつけることができました。
原因
- NEC Express 5800 / 110Gd の BIOS が(EIST をきちんとサポートしていないためか)おかしな CPU frequency を返す
- EIST 無効時は Core2 Quad Q6600 は 2.4GHz で動いている
- ホスト側は(自力でキャリブレーションしているのか)2.4GHz であると認識している(∴ホストの時刻は狂わない)
- VMware Server は ACPI 経由で CPU frequency を取得している
- 先に上げたように ACPI 経由の CPU frequency 取得がおかしいので(フルパワー時)900MHz であると認識される
- VMware Server は guest も host も 900MHz で動いているとみなす
- 実際には 2.4GHz をベースとして割り込みが発生しているので 2.4GHz / 900MHz(≒2.67倍)の割り込みが guest に伝達する
- このため clocksource を何にしたところで,最悪 2.67 倍のスピードで時刻が進んでいく(実際には割り込みのとりこぼし lost ticks が発生するのでそこまで早くはならない)
対策
- host のクロック変動を避けるため host の cpuspeed サービスを停止しておく
- Host Power Management Causes Problems with Guest Timekeeping on Linux Hosts に従って
/etc/vmware/config
に正しい host CPU frequency を設定しておく - guest のカーネルパラメータに
notsc clocksource=pit
を追加し,guest の kernel サイドのアグレッシブな時刻補正を無効にしておく((お好みでnosmp noapic nolapic
等を追加することで,割り込みハードウェアを IO-APIC ではなく XT-PIC にして割り込み負荷を軽減させることもできます)) - guest に VMware Tools をインストールして
syncTime
を有効にする
以下調査経過が長々と続きます。
VMware Server 1.0.4 on Core2Quad で guest の時刻が進みまくり
今まで時刻が遅れるというのはよくあったんですが,x86_64 で CentOS 5.1 をインストールしたら時刻が進みまくりで困ってます。時には倍速近い。
host の vmware.log から
Dec 06 18:04:09: vmx| KHZEstimate 600000 Dec 06 18:04:09: vmx| MHZEstimate 600
guest の dmesg から
time.c: Using 3.579545 MHz WALL PM GTOD PM timer. time.c: Detected 600.041 MHz processor.
この辺がおかしいからかも。Q6600 @ 2.4GHz なので,いくらなんでも 600MHz ってことはないです。
VMware Tools を Server 添付のにしてないからかもしれません。いっそ x86_64 にきちんと対応してげな Server 2 Beta に移行しようか迷い中。こんなことなら Xen みたいな para-virt な vms にしておけばよかった。
ちなみに,
CentOS 5を入れていて気がついたのですが、CentOS 5のkernel-2.6.18-8.1.1.el5では(多分インストール時の2.6.18-8.el5でも)あらかじめタイマー割り込みの CONFIG_HZの値が100になっているので、カーネルの更新のたびに再コンパイルが必要なくなっていました。
include/asm-i386/param.h
- snip - #ifndef HZ #define HZ 100 #endif - snip -http://blog.hide-k.net/archives/2007/04/vmwarecentos_5.php
これは違う希ガス。
手元の CentOS 5.1 x86_64 ですが,
/usr/src/kernels/2.6.18-53.1.4.el5-x86_64/include/asm-x86_64/param.h
:
...... snip ...... #ifdef __KERNEL__ # define HZ CONFIG_HZ /* Internal kernel timer frequency */ # define USER_HZ 100 /* .. some user interfaces are in "ticks */ #define CLOCKS_PER_SEC (USER_HZ) /* like times() */ #endif #ifndef HZ #define HZ 100 #endif ...... snip ......
/usr/src/kernels/2.6.18-53.1.4.el5-x86_64/.config
:
# CONFIG_HZ_100 is not set # CONFIG_HZ_250 is not set CONFIG_HZ_1000=y CONFIG_HZ=1000
前述の /usr/include/asm-*/param.h
はユーザランドのプログラムのための HZ
で,たぶん歴史的経緯から 100 になっているんだと思います。他の環境が手元にないので断言はできませんが。