***本記事にはプロモーションが含まれています。***
以前、準仮想化クロック(kvm-clock)は起動してからの時間とTSCの値をメモリに書き込んでいることがわかりました。
また、その書き込むタイミングはホストOSからゲストOSに制御が移る前だということもわかりました。
ただ、書き込む頻度についてはよくわかりませんでした。
そこで、LinuxのKVMのソースコードを読んで詳しく調べてみました。
ソースコードはarch/x86/kvm/x86.cで、kvm_guest_time_update()でシステムタイムとTSCのメモリの値を更新しています。
この関数は、vcpu_enter_guest()で呼ばれます。ホストOSからゲストOSに制御を移す関数です。
ただ、KVM_REQ_CLOCK_UPDATEという名前のリクエストがあったときのみkvm_guest_time_update()は呼ばれますので、どういう条件か探してみます。
わかったところを列挙すると次のようになります。
- システムが立ち上がったとき
- TSCの周波数が変更されたとき
- プロセスのCPU間での移動があったとき
- マイグレーションのとき
- MSR_KVM_SYSTEM_TIMEをセットしたとき
- CPUのホットプラグでロードされたとき
現在のパソコンのシステムを考えると、最初の3つくらいがよく起こることだと思います。でも、思いのほか準仮想化クロックの値の更新がなされません。Core iシリーズ以降の最近のCPUでは、CPUの周波数が変わったときでもTSCの周波数は変わらないです。プロセスの移動もそう頻繁にはないです。システムが起動してから、あまり頻繁には準仮想化クロックは更新されていないということがわかります。
実際に、ホストOSの時刻を変更してもゲストOSの時刻が同期して変わることはありません。
このことから準仮想化クロックは頻繁には更新されず、主にTSCによって現在時刻を計算していることがわかりました。