連載
» 2007年04月28日 08時00分 公開

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

[高橋浩和(VA Linux Systems Japan),ITmedia]
前のページへ 1|2       

ドメインディスパッチャの実装

 ドメインディスパッチャの本体は、リスト1に示すcontext_switch関数です。prevで指定された仮想CPUから、nextで指定された仮想CPUへの切り替えを行います(図4)。コードの詳細は後述するとして、まずは(図4)を基に、動作の概要を説明しましょう。

図4 図4 コンテキストの切り替え手順(前半)

 ドメインディスパッチャを開始するとき、これから実行権を奪われるドメインの仮想CPU(prev)は、すでにゲストOSのコードを実行していません。ゲストOS実行時のコンテキストの一部は、ハイパーバイザースタックに待避済みです(図4の1)

 ドメインディスパッチャは、ハイパーバイザースタックに待避されているコンテキストを仮想CPU prev用のvcpu構造体内に転送し(図4の2)、ハイパーバイザースタックに待避していなかった実CPUに残るコンテキストを、prev用のvcpu構造体内に待避します(図4の3)

図5 図5 コンテキストの切り替え手順(後半)

 次に、ドメインディスパッチャは、next用のvcpu構造体に保存されたドメインのコンテキストを復帰させます。next用のvcpu構造体内に保存されたコンテキストの一部をハイパーバイザースタックの底に転送し(図5の4)、残りを実CPUに読み込みます(図5の5)。ハイパーバイザースタックの底に転送したコンテキストは、Xenのコードから復帰するとき、実CPUに読み込まれます(図5の6)

コンテキスト切り替えの工夫

 コンテキストの切り替えに当たっては、少しでもその処理を高速化できるように努めています。そのための工夫の1つが、切り替えないで済むものを、できるだけ切り替えないで済ませることです。書き換えないコンテキストは復帰処理だけ行って待避処理を行わないようにし、ドメイン間で共通する部分の切り替えも省略しています。

切り替え処理の遅延

 また、もう1つの工夫として、切り替え処理を遅延させています。ドメインディスパッチャが呼び出されたときにすぐ切り替えず、切り替え要求があったことを示す印を付けておき、本当に必要になったときに切り替える方式です。これによって、実際の切り替えを行わなくても良くなることを期待します。

 具体的には、ドメインディスパッチャは、この遅延切り替えを、2つのことに利用しています。

  • 浮動小数点演算レジスタ

 浮動小数点演算レジスタの切り替えに関しては、Linuxカーネルとまったく同じ方法を採用しています(実際、コードもLinuxカーネルから移植されたものを利用しています)。浮動小数点演算レジスタは本数も多く、また一つ一つのレジスタ長も大きいので、レジスタ値の保存や復帰には大きなコストがかかります。このため、浮動小数点演算レジスタの保存・復帰を回避することで、性能を稼げるわけです。

 このために行われているのが、浮動小数点演算レジスタの遅延切り替えです。この方法では、浮動小数点演算レジスタの利用が局所的であることを利用しています(この特性は、整数演算用のレジスタとかなり異なります)。しばらく浮動小数点演算を行わないことも珍しくないため、「ドメインがスケジューリングされてから、またCPUを奪い取られるときまでに浮動小数点演算を行っていなければ、浮動小数点レジスタの切り替えは必要ない」という前提を利用しています。

 x86用のXenでは、ドメインを再スケジューリングするときに浮動小数点演算レジスタへのアクセスを禁止しておき、浮動小数点演算を行ったときに発生する例外を利用して、浮動小数点レジスタの切り替えの必要性を検出しています(図6(a)、b))

図6 図6 コンテキストの切り替え
  • アイドルドメインとの切り替え

 実行可能なドメインが存在しなくなる瞬間が存在します。その場合、最後に動作していたドメイン(仮にドメインAとします)からアイドルドメインへの切り替えが行われます。このとき、ドメインのコンテキスト切り替えを遅延します。アイドルドメインは、1つ前に動作していたドメインAのコンテキストを借りて動作(何もしない命令を実行)します。

 なぜ、このようなことをすると思いますか? すぐに同じドメインAが動作を再開し、再スケジューリングされたときのことを考えると、理解できると思います。この場合、ドメインのコンテキスト切り替えをせずに、アイドルドメインからドメインAに実行権を渡せます。この遅延切り替えの方式を採用することで、ドメイン切り替えを2回省略可能です。実際、1つの実CPUには、1つから多くても数個程度の仮想CPUしか割り当てられないことが大部分であり、またすべての仮想CPUが常に動作しているとは限らないため、思っている以上にこの機能が働いていそうです(図7)

図7 図7 アイドルドメインとの切り替え

 もちろん、アイドルドメインから異なるドメインBに切り替えが発生したときには、ドメインAのコンテキストを待避し、仮想CPUからドメインBのコンテキストを復帰することになります。

 Linuxカーネルにも良く似た仕組みがあります。通常プロセスとアイドルプロセスとの切り替えでは、プロセス空間情報に関するコンテキストの切り替えを遅延します。また、アイドルプロセスだけでなく、カーネルスレッドに対しても同様に遅延切り替えの対象にしています。アイドルプロセスやカーネルスレッドは、1つ前に動作したプロセスの空間を借りて動作します。

次回は

 ドメインの切り替え【後編】では、ここまで解説したことをふまえた上でドメインディスパッチャのコードをのぞいてみることにしましょう。

本記事は、オープンソースマガジン2006年5月号「仮想マシンモニタ Xen 3.0解読室」を再構成したものです。


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

注目のテーマ