株式会社ネットワールドのエンジニアがお届けする技術情報ブログです。
各製品のエキスパートたちが旬なトピックをご紹介します。

カーネル vs ユーザーモード

本記事の原文はもともとPernixData社のTechnical Support Engineer (TSE)で、現在はPernixData社のNutanix社による買収でNutanix社のSr. Systems Reliability Engineerとして活動を継続しているGuido Hagemann氏によるものです。

VMworld EMEAに参加した際に初めてお会いしましたが、Guidoさんはサポート担当ですので、時間によってはサポートコールを取ってくれて話やメールをした間柄です。

原文を参照したい方はKernel vs. Usermodeをご確認ください。情報は原文の投稿時のままの情報ですので、現時点では投稿時の情報と製品とで差異が出ている場合があります。

当社のNutanix社製品についてはこちら

私の生まれて初めてのブロク記事へようこそ! この記事はとても前に、ブロクを始めようと思った際に書いたものですが、その時にはいろいろな事情で公開しませんでした。 :) でも、ほら、ようやく公開することが出来ました。記事の内容についてはとても昔の内容から初まります。「ITインフラストラクチャ」という名前の大学の講義で、私がOSのカーネルの深みに初めて踏み入り、CPU内のキャッシュやCPUが実際にどのように計算を行っているとか、もちろんもっと多くの事を知った際の話からです。その時私はOSカーネルの中が非常なめらかで、その一方で非常に複雑であり、時には危険だということに驚きました。例えばメモリの上書き、C言語でのプログラミングで手続き上のオブジェクトが存在しないなどです。もちろん、あらゆるOSのハードウェアを利用するためのドライバーはRing 0で動作しています。ですから、複雑さは実際にはカーネル内で動作しているソフトウェアの機能によって大きく異なります。もちろん、品質についても同じです。さぁ、前置きはこれぐらいにして、記事の中身に入っていきましょう。

オペレーティングシステムは通常は非常に大きなプログラムで、コアコンポーネントカーネルと呼ばれます。カーネルは全てのハードウェアリソースを司るオーナーでもっとも深いソフトウェアレイヤで動作しており、ハードウェアに直接アクセスを行うことが出来ます。カーネルが行っていることは:

  • アプリケーションへのインターフェイス(API)
  • CPU(中央演算装置)、ハードウェアデバイス、メモリ(スケジューラ、ドライバ、メモリ管理)のコントロール
  • リソースのスケジューリング 例 :アプリケーションの処理時間
  • リソースの構成 例 : ディスクのようなブロック指向のデバイスファイルシステムへのマッピング
  • リソース競合の解消 例: リソースのキューイング、CPUリソースのロック
  • リソース~プロセッサ(をプロセスへ)、ディスク(をファイルへ)、メモリ(を仮想化メモリへ)~の仮想化
  • ファイルやデバイスのアクセスコントロールの監視

Exokernel、モノリシックカーネル、レイヤードカーネルなどのように、異なる目的に対して非常に多くの種類の異なるカーネルがありますが、それらの詳細の違いについて踏み入ることはしません。今日もっとも利用されている種類のカーネルマイクロカーネルと呼ばれるものです。マイクロカーネルはすべてのWindowsワークステーション・サーバそして、LinuxをベースとしたOSやVMware ESXiでも利用されています。OSを様々なプロセスに分割、分けていく理由はクライアントが他のOSやアプリケーションでも良くしようというためです。ですからクライアントがリクエストを適切なサーバにメッセージを送信することで実行し、サーバは処理を実行します。マイクロカーネルは結果をクライアントに返します。以下の図にそれを示しました:

Fig026マイクロカーネル

マイクロカーネル固有の特性の幾つかは:

  • OSの一部を容易に置き換え可能
  • ドライバはユーザモードでもカーネルモードでも動作する
  • 理I/Oアクセスの実装が難しい
  • コンテクストスイッチ(時にはタスクスイッチやプロセススイッチとも呼ばれる。単一のプロセスやプロセスのスレッドが別のCPUへと切り替わること)

ユーザーモード (ユーザープログラムで言う非特権モード) :

全てのユーザープログラムはこのモードで実行されます。ユーザーモードはメモリやハードウェアへの直接のアクセスを行いません。この理由はすべてのプログラムがそれぞれでメモリを書き換えると他のプログラム用のメモリを上書きしてしまい、衝突が起きてしまうからです。ユーザーモードのプログラムは通常はカーネルの観点からは信頼性のないソフトウェアとして取り扱われます。もし、ハードウェアリソースへのリソースが必要な場合にはその下のAPI(システムコール)を経由して手続きが行われます。

カーネルモード (システムモードとも呼ばれる):

このモードは全てのカーネルプログラムで利用されています。カーネルモードではプロセスがその下のすべてのハードウェアに直接アクセスを行います。CPUだけがカーネルユーザーモードを同時に実行することが出来ます。ユーザーからカーネルモードへのスイッチは自動的に行われ、その際には割り込みが発生します。

マイクロカーネルの詳細への踏み込みはおこなわず、ここでは少々コンテクストスイッチにフォーカスしたいと思います。すべてのプロセスは単一、又は複数のスレッドで実行されます。プログラムはスレッドを利用して事実上の並立実行時間を設け、1つ以上のCPUで実行されます。上で述べたように、マイクロカーネルは全てのリソースを司ります。ですから、もしもプロセスがCPUで動作しようとするととても大きなオーバーヘッドが生じます。既存でCPU上で動作していた環境は以下によって抑制がかかります :

  • プロセスのステータス
  • プログラムカウンタ
  • スタックポインタ
  • ファイルのオープン状態
  • メモリ管理 : 実際の実行環境へのポインタ

メインメモリへの一回のアクセスの全てのステップで、CPU内のこのプロセスのキャッシュは全てが廃棄されます。これはもはや正しいキャッシュではなく、将来的にキャッシュのミスを引き起こすからです。すべてのプロセスがCPUを利用しようとする度にOSのスケジューラーはいつそのプロセスがCPUを利用するかを決め、実際にCPUを利用させるのです。

Fig027プロセスの状態

コンテクストスイッチはカーネル内でしか発生しません。ですから、もしアプリケーションがCPUのプロセスを利用したい場合には、ユーザーモードからカーネルモードへシステムコール経由で移行しなければなりません。ですから、ユーザーからカーネルモードへ恒久的にスイッチするということは非常にコストが高く、多くのCPUサイクルを利用します。カーネル内で直接動作するソフトウェアはオーバーヘッドを著しく減らし、パフォーマンスが向上します。仮想化の世界でのカーネル実装の2つの例は:

さぁ、まとめに入りましょう。アプローチの方法はその目的によって様々ですが、一般的には以下が言えるでしょう:

  • カーネルモードのドライバ/ソフトウェアは実際にOSのコアで動作する点や、加えてプログラムの方法も限定されているため非常に複雑ですが、実現できればパフォーマンス面からは非常に大きなメリットが有ります。セキュリティの面から考えても、カーネル内からは外からそれを行うよりはるかに簡単です。
  • ユーザーモードのソフトウェアは非常に強力で、それは安定性の実装が簡単であり、プログラミングフレームワークを数多く選べることからのメリットもあります。ユーザーモードカーネルモードのソフトウェアを組み合わせた実装も目にすることが有ります。これはカーネルモジュールとのやり取りを必要とするようなケースがあるからです。これはユーザーモードで動作しているコアOS自身のデーモンプロセスなどで見られます。

記事担当者: マーケティング本部 三好哲生 (@pernixdata_netw)

いかがでしたでしょうか? OSの中身まで奥深く分け入らない、と言いながらもCPUの中で何が起きているか、などまで解説していますのでなかなかわかりにくいかもしれませんが、一昔前にある種の「宗教戦争」として勃発したインカーネル対仮想化ストレージアプライアンスをこれ以上ないぐらい低いレイヤからみた話としてご紹介しました。まとめのところにあるように、カーネル実装は強力ですが、複雑で、実装も難しい、けれどもパフォーマンスの観点からは大きくベネフィットが有ります。ユーザーモード実装はフレームワークを様々に選択できるため実装が簡単です。裏返しとしてコンテクストスイッチの発生の際にはCPUのキャッシュを廃棄したり、スケジューラーのサイクルを待たなくてはならないこともあります。また、私がとても気になったのは「ハイブリッド」の実装もあるよ、という一文です。

買収直後の記事ですし、深読みしてしまうところもありますが、宗教戦争のような絶対的な決着があるわけではなく、目的によってカーネルユーザーモードを使い分けるのが正しいということを覚えておいてください。そして、カーネルモードの実装例として上げられているPernixData FVPは現在はユーザーモードの実装例の代表格であるNutanix社の手の中にあるのです。さぁ、将来が楽しみですね。Guidoさんの記事は非常に深いレイヤからの知識を教えてくれ、いろいろな意味で面白いので今後も翻訳の対象にしていきます。お楽しみに!