連載
» 2007年07月11日 00時42分 UPDATE

仮想マシンモニタ Xen 3.0解読室:ドメインの切り替え【後編】 (1/2)

Xenにおいて、ドメインの実行を制御する機能であるドメインスケジューラと、ドメインの実行を切り替える機能をドメインディスパッチャと呼びます。前回に引き続きこれらの動作について解説します。

[高橋浩和(VA Linux Systems Japan),ITmedia]

ディスパッチャのコードをのぞいてみよう

ドメインディスパッチャの本体部分

 前回までの内容を踏まえた上で、今回はドメインディスパッチャのコードをのぞいてみることにしましょう(リスト1)。参照するのは、Xen 3.0.1 x86用のコードです。

編集部注:リスト1には多くの注釈線が含まれているため、画像として用意しました。上記アイコンをクリックいただくことでご覧いただけます

コンテキスト切り替え処理の大枠

 この部分は、複数のドメイン(ゲストOS)を切り替える心臓部です。ドメイン切り替え処理の大部分は割り込み禁止状態で行います(リスト1のA3、A6、A8)。まず、スーパーバイザースタックの底に置かれているcurrent変数が、次に動作する仮想CPU nextを指すようにします(A4)

 このとき、もし同じ仮想CPU同士で切り替えを指定された場合は(つまり、prevとnextが同じ場合は)、当然コンテキストを切り替える必要がありません(A5)。さらに、次に動作する仮想CPUがアイドルドメインのものである場合も、ここではコンテキストの切り替えを行いません(A5)。先ほど説明したように、実際の切り替え処理を遅延させます。

 ドメイン同士の場合、通常はコンテキストの切り替えを行います。コンテキスト切り替えの大部分は、__context_switch関数(A7)で行います(__context_switch関数については、この後すぐに説明します)。割り込みを許可した状態で操作可能なコンテキストは、割り込みを許可(A85)した後に切り替えます。

 __context_switch関数から戻った後に行っているコンテキスト切り替え処理は、完全仮想化ドメインと準仮想化ドメインで異なります。

 完全仮想化ドメインの場合は、vmx_restore_msrs関数を呼び出し(A9)、x86のVT機能で追加された仮想マシン環境を制御するテーブルの切り替えを行います(詳しくは「完全仮想化の回」でお話します)。なお、vmx_restore_msrs関数は32ビットモードでは空関数(何もしない関数)になっています。

 準仮想化ドメインの場合は、LDT(Local Descriptor Table)とセグメントレジスタの切り替え(A10、A11)を行っています。vmx_load_msrs関数(A12)は、32ビットモードでは空関数です。

 最後に、context_saved関数を呼び出し、prevが走行状態になった印(_VCPU_running)をつけて終了です(A13)

BUG()文の秘密

 context_switch関数の最後にBUG()文が置かれている(A15)のを、奇異に感じている方もおられるのではないでしょうか? 関数の途中にreturn文がないため必ずこのBUG()文が実行され、Xenが停止してしまうように見えます。秘密は、その前にあるschedule_tail関数の呼び出し(A14)にあります。

 Cライブラリ関数のsetjmp()、longjmp()を利用されたことはありますか? 前記のschedule_tail関数は、longjmp()のように動作します。schedule_tail関数は、通常、ドメインに対してはXenの出口であるret_from_intrというシンボルのコードに制御を移します(C3)。このコードは、ハイパーバイザースタック上に待避されている仮想CPU nextのコンテキストを実CPUに復帰します。それによって、仮想CPU nextが行っていたドメイン処理の中断個所から実行を再開することになります。完全仮想化ドメインの場合は、それとは異なるパスでコンテキストの復帰を行います*

 一方、アイドルドメインのときはidle_loop関数に制御を移します(C2)。idle_loop関数は、hlt命令を実行することでCPUの動作を停止します。

実CPUの割り当て

 最後に、(A1)(A2)の文を考えてみることにします。現在のXenの実装では、ある仮想CPUが割り当てられる実CPUは、基本的に固定しています。明示的に割り当ての変更を行わない限り、(A1)の条件文が成り立つことはありません。仮想CPU nextが以前と異なる実CPU上に割り当てられ動作する場合、その仮想CPU nextが遅延切り替えの対象になっていることがあります(以前に動作していた実CPU上で、アイドルドメインと切り替わった直後に移動するとそのような状態になっています)。

 この場合、flush_tlb_mask関数を呼び出し(A2)、IPI(プロセッサ間割り込み)を利用して、もともと動いていた実CPUにTLBのフラッシュ要求を行います*。実は、IPI割り込みを受けた実CPUは、TLBのフラッシュに加えて、コンテキストの切り替えも実行します。これによって、はじめて仮想CPU nextと元の実CPUとの関係を完全に精算し、ほかの実CPU上でも実行可能な状態になります。

このページで出てきた専門用語

完全仮想化ドメインの場合は、それとは異なるパスでコンテキストの復帰を行います

これについては「完全仮想化」の回で解説する予定。

もともと動いていた実CPUにTLBのフラッシュ要求を行います

TLBのフラッシュに関しては、「メモリ管理」の回のどこかで解説する予定。


関連キーワード

カーネル | Linux | オープンソース | 仮想化 | Xen


       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

ピックアップコンテンツ

- PR -

注目のテーマ