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 になっているんだと思います。他の環境が手元にないので断言はできませんが。