仮想化: Virtio-Net の基礎

仮想化: Virtio-Net の基礎

[[397021]]

Virtio の基本

1. virtioの提案

システム仮想化技術は、クラウド コンピューティングの最も重要なコア技術の 1 つです。クラウド コンピューティング プラットフォームのリソース プーリング、統合リソース管理、およびそれに続く動的割り当てはすべて、システム仮想化テクノロジに基づいて可能になります。コンピュータ システムには、主にコンピューティング リソース、ストレージ リソース、ネットワーク リソースがあります。したがって、システム仮想化テクノロジは、コンピューティング仮想化、ストレージ仮想化、ネットワーク仮想化にさらに分類できます。ストレージデバイスやネットワークデバイスは、一般的に周辺機器の形で I/O バスを介して CPU に接続されるため、ストレージ仮想化とネットワーク仮想化は総称して I/O 仮想化技術として分類できます。ここで紹介する virtio は、最も人気のある I/O 仮想化テクノロジーです。

I/O 仮想化テクノロジーは、完全仮想化と準仮想化の 2 つのタイプに分けられます。

  • 完全仮想化: ゲスト OS は仮想マシンであることを認識しないため、ゲスト OS ドライバーを変更する必要はありません。これにより、ゲスト OS の移植性は高まりますが、仮想マシンの I/O パフォーマンスは高くありません。
  • 準仮想化: ゲスト OS は仮想マシンであることを認識し、フロントエンド ドライバーとバックエンドのシミュレートされたデバイスの連携を通じて IO 仮想化を実装します。完全仮想化と比較して、準仮想化テクノロジは仮想マシンの I/O パフォーマンスを大幅に向上させるのに役立ちます。現在、Linux 上の virtio の特定の実装はクラウド コンピューティング シナリオで広く使用されており、virtio は、Linux 以外のシステムにも適用できる仮想化 I/O テクノロジの抽象インターフェイス仕様および事実上の標準となっています。

2. Virtioの全体設計コンセプト

virtio の全体的な設計コンセプトは、直感的、効率的、標準化、拡張可能という 4 つのポイントに要約できます。

1) 直感的: Virtio デバイスは、以前のハードウェア デバイスと同じように設計されており、割り込みや DMA などの一般的なバス メカニズムをサポートしています。この設計により、ドライバー開発者は virtio デバイス ドライバーの開発をすぐに開始して完了することができます。

2) 効率性: Virtio デバイスは個別の入力チャネルと出力チャネルをサポートし、大量のデータを送信しても高い効率を維持できます。

3) 標準化: ハードウェアアーキテクチャやオペレーティングシステム環境に依存せず、複数の異なるバスの伝送メカニズムをサポートします(virtio仕様1.1では、PCI、MMIO、チャネルI/Oバスをサポートします。例えば、PCIをサポートしていない組み込み機器でも、MMIOを使用してvirtioを使用できます)。

4) スケーラビリティ: virtio デバイスの検出とデバイスの初期化中に、機能ビット識別子を導入することで動的適応ネゴシエーション メカニズムが実装され、virtio フロントエンド ドライバーとバックエンドのシミュレートされたデバイス間の互換性が確保されます。

3. virtioの基本原則

次に、最も広く使用されている QEMU/KVM シナリオを例にして、virtio の基本原理をさらに説明します。仮想マシンは物理ホスト上の QEMU プロセスであり、ユーザー モードで実行されます。仮想マシン内の virtio フロントエンド ドライバーによって要求されたキャッシュは、デバイス空間と QEMU のアドレス空間にマップされるため、QEMU は共有メモリを介してこれらのキャッシュを読み書きできます。これにより、virtio フロントエンド ドライバー (仮想マシン Linux カーネルのドライバー) とバックエンド シミュレート デバイス (QEMU バックエンド デバイス シミュレーション プログラム) 間のデータ転送のゼロ コピーが実現され、仮想マシンの I/O パフォーマンスが大幅に向上します。

  1. QEMU/KVM での virtio フロントエンドとバックエンドの実装

Virtio は、仮想マシン カーネルにフロントエンド ドライバーを実装し、QEMU にバックエンド シミュレーション デバイスを実装します。フロントエンドとバックエンドは、仮想キュー (Virtqueue) を介して通信し、データを交換します。 Virtio デバイスには、さまざまなバス メカニズムに対してさまざまな実装方法があります。 PCI デバイスは最も広く使用されているデバイスであるため、virtio の PCI ネットワーク カードを例にして説明します。 virtio-net フロントエンドとバックエンドの実装を図 2 に示します。

図[1] QEMU/KVM での virtio-net フロントエンドとバックエンドの実装

  • Virtio デバイスの検出と初期化

仮想マシンが起動すると、virtio フロントエンド ドライバーは、PCI 製造元識別子と PCI デバイス識別子を含めて、自身を PCI デバイスとして識別します。仮想マシンのカーネルは、この識別子に基づいてどのドライバーを使用するかを決定できます。仮想マシンの Linux カーネルにはすでに virtio ドライバーが含まれているため、virtio デバイスを初期化するために virtio ドライバーが呼び出されます。 virtio フロントエンド ドライバーは、PCI デバイスの通常の初期化操作を完了するだけでなく、初期化プロセス中にバックエンド デバイス エミュレーション プログラムと機能ビットをネゴシエートし、最終結果をデバイス ステータスに記録します。具体的な実装コードについては、図 2 に示すように、カーネル コード linux-3.10.0-957.1.3.el7/drivers/virtio/virtio.c の virtio_dev_probe() 関数を参照してください。

図2. Virtioデバイスの初期化、機能のネゴシエーション、デバイスステータスビットの最終設定

ここで紹介する必要がある重要なデータ構造が 2 つあります。

  • 機能ビットは、デバイスがサポートできる機能を示すために使用されます。 virtio デバイスが初期化されると、ドライバーは機能ビットを読み取り、デバイスが受け入れ可能な機能を通知します。バックエンド シミュレーション デバイスがアップグレードされ、新しい機能が有効になっていても、仮想マシンのドライバーがそれを認識できない場合、両者はその機能を通じてネゴシエートします。
  • デバイス ステータス: デバイスの現在のステータスを示すために使用されます。 virtio デバイスの検出、初期化、および機能ネゴシエーションのプロセス中に、デバイス ステータス ビットを表示することで、virtio デバイスのステータスを確認できます。たとえば、virtio_CONFIG_S_FEATURES_OK は機能ネゴシエーションが成功したことを示し、virtio_CONFIG_S_DRIVER_OK はドライバーが正常に構成されたことを示します。
  • Virtio ネットワーク カード送信データ処理プロセス

仮想キュー (Virtqueue) は、virtio フロントエンド ドライバーと virtio バックエンド シミュレート デバイス間の双方向データ転送に使用されるデータ構造です。各 virtio デバイスは 1 つ以上の仮想キューを維持します。 virtio ネットワーク デバイスを例にとると、少なくとも 2 つの仮想キューが維持されます。1 つは送信するデータを格納するためのもので、もう 1 つは受信した受信確認を格納するためのものです。各仮想キュー データ構造は、記述子テーブル、使用可能なリング、使用済みリングの 3 つの部分で構成されます。

  • 記述子テーブルはキャッシュのセットを記述するために使用され、virtio フロントエンド ドライバーによって作成されます。キャッシュに関連する情報は主に物理アドレスと長さです。キャッシュ配列の数はキューのサイズによって決まります。
  • 使用可能なリングは、virtio フロントエンド ドライバーによって、virtio バックエンドのシミュレートされたデバイスにデータを送信するために使われます。たとえば、仮想マシンが virtio-net デバイスを使用してデータを送信する場合、送信されたデータは最初にここにキャッシュされ、次に virtio バックエンドのシミュレートされたデバイスにそのデータを読み取るように通知されます。つまり、使用可能なリングのキャッシュは、フロントエンドによってのみ書き込まれ、バックエンドによってのみ読み取られます。
  • 使用されるリングは、virtio バックエンド シミュレーション デバイスによって、virtio フロントエンド ドライバーにデータを送信するために使用されます。たとえば、virtio バックエンド シミュレーション デバイスは、tap ネットワーク インターフェイスからデータを受信すると、受信したデータをここでキャッシュし、virtio フロントエンド ドライバーに通知します。つまり、使用されているリングのキャッシュは、バックエンドによってのみ書き込まれ、フロントエンドによってのみ読み取られます。

図3. Virtio仕様における仮想キューの定義

図4. virtio仕様における使用済みリングと使用可能リングの定義

次に、仮想マシンによるデータ送信を例に、Linux 3.10 と QEMU1.5 のコード実装を組み合わせて、QEMU/KVM シナリオにおける具体的な実装プロセスを詳しく説明します。

virtioフロントエンドドライバはデータパケットを埋めて通知を発行する

QEMU 仮想マシンの virtio ネットワーク カード ドライバーが初期化されると、他のネットワーク ドライバーと同様に送信関数 xmit_skb() が登録されます。具体的な実装は図 5 と 6 に示されています。したがって、仮想マシンの virtio ネットワーク カードがデータを送信すると、事前に登録された関数 xmit_skb() が呼び出されます。送信されるデータは、virtqueue_add_outbuf() を呼び出すことによって使用可能なリングに配置されます。最後に、virtqueue_add_outbuf() 関数内で、virtqueue_kick() 関数が呼び出され、さらに virtqueue_notify() 関数が呼び出されます。 virtqueue_notify() 関数では、図に示すように、virtio フロントエンドが実行されます。 7 は、I/O レジスタに書き込むことによって、virtio バックエンド シミュレーション デバイスに通知します。フロントエンド ドライバーのこの部分のコードは、drivers/virtio/virtio_ring.c にあります。

図5. Virtioデバイスがデータパケットを送信する

図6. virtioフロントエンドドライバがQEMUに通知する

図7. virtio通知関数は最終的にレジスタに書き込みます

KVMはI/Oをインターセプトし、バックエンドに通知します

仮想マシン virtio フロントエンド ドライバーが通知を送信する関数は、最終的に I/O 書き込み命令を実行します。 QEMU/KVM 環境では、仮想マシンが I/O 命令を実行すると、VMExit がトリガーされます。終了の理由は、KVM の VMExit コードで決定されます。 I/O操作に対応する処理関数はhandle_io()です。具体的なコードは、図 8 に示すように、linux-3.10.0-957.1.3.el7/arch/x86/kvm/vmx.c にあります。最後に、KVM は QEMU の virtio-net バックエンド シミュレーション デバイスに通知します。これには、KVM や eventfd などの通信メカニズムも含まれますが、スペースの制限により、ここでは詳細には説明しません。

図 8. KVM での I/O 操作の処理によって発生する VMExit コード

Virtio バックエンド シミュレーション デバイス処理通知

図に示すように、 8、KVMからの通知を受信した後、QEMUバックエンドデバイスエミュレーションプログラムはvirtio_queue_host_notifier_read()関数を呼び出し、次に事前登録された関数virtio_ioprt_write()を呼び出して、フロントエンドドライバーからのI/O書き込み操作を処理します。フロントエンドから通知を受信すると、処理のために virtio_queue_notify() 関数が呼び出されます。ネットワーク データ パケットを受信すると、virtio_queue_notify() は、virtio-net ネットワーク デバイスによって登録されたデータ パケット受信関数 virtio_net_handle_rx() をさらに呼び出します。図 9 に示すように、qemu_flush_queued_pa​​ckets() では、QEMU はデータを対応するキューにコピーし (QEMU のバックエンドに対応する異なるタップは異なるキューを維持します)、次に qemu_notify_event() を呼び出して virtio フロントエンドに通知し、最後に kvm_set_irq() を呼び出して vCPU 割り込みをトリガーし、virtio フロントエンドに通知します。

図9. virtioバックエンドデバイスによる通知受信後の処理

図10. Virtio-net事前登録データグラム受信機能

図11. virtioバックエンドデバイスはフロントエンドから送信されたデータパケットを処理する

参考リンク:

【1】Virtio ネットワークと vhost-net の詳細 (https://www.redhat.com/en/blog/deep-dive-virtio-networking-and-vhost-net)

この記事はWeChatの公開アカウント「Linux Reading Field」から転載したものです。以下のQRコードからフォローできます。この記事を転載する場合は、Linux Reading Field 公式アカウントまでご連絡ください。

孫磊氏は、レノボ研究所およびNEC研究所で上級研究員および研究開発マネージャーとして10年間勤務しました。

ソフトウェア定義ネットワーク(SDN)、クラウドネットワーキング(OpenStack)など、クラウドコンピューティングの基盤技術を担当。

データプレーンの高速化など

彼は2020年に起業し、北京寿志科技有限公司の創設者です。

<<:  Kafka 2.8.0 がリリースされ、正式に ZooKeeper から分離しました。

>>:  中国で唯一! Sangfor が Forrester クラウド セキュリティ ゲートウェイ レポートに選出

推薦する

インテリジェントエッジコンピューティングの継続的な開発

1970 年代に情報技術が初めて組織に広く導入されて以来、開発サイクルは、多くの人が振り子の揺れに例...

微博マーケティングの4大ブランド価値

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスデジタル時代の重要なマー...

この記事では、JVMパフォーマンスチューニングについて詳しく説明します。

1. JVMチューニングの概念データ型Java 仮想マシンでは、データ型はプリミティブ型と参照型の ...

おすすめ: 複数のブランドの Prometeus VPS スペシャル

プロメテウスは私たちにもう一つの驚きをもたらしました。今回、その3つのブランドが同時にセール対象とな...

virmach: 米国の VPS は年間 6.3 ドルから、オプションのデータ センターは 10 か所、Alipay/PayPal での支払いが可能

これは、virmach の今年最後の格安 VPS になるかもしれません。最低価格は年間 6.3 ドル...

中小企業がネットワークマーケティングを体系的に行うには(第3回) - コンテンツ

コンテンツとは、インターネット上で公開されるすべての情報を指します。コンテンツは、ユーザーが読んでニ...

クレイジーマン:SEOの関連性について

SEOは関連性が重要検索エンジンでキーワードを検索すると、通常、多数のページが返されます。これらのペ...

MySQL 大規模データ分散ストレージ

この記事は単なる概念です。ここで詳細に説明するには、具体的な構成が多すぎます。 1. 分散アプリケー...

マイクロVMはフルVMとコンテナの間のギャップを埋める

仮想マシン (VM) とコンテナは現在主流のテクノロジーですが、どちらにも欠点があり、モビリティの低...

ウェブマスター、Vanclから学んだ運用上の欠点について考えてみましょう

Vancl(別名VANCL)は、Joyo.comの創設者であるChen Nianの傑作です。 Van...

ラリー・エリソンがクラウド開発の未来を語る

Oracle OpenWorld のオープニング基調講演で、Oracle 会長兼 CTO の Lar...

ウェブページのキーワードを変更するときに検索エンジンを馬鹿にしてはいけない

著者はかつて多くのウェブマスターと同じでした。当初、ウェブサイトのポジショニングが不正確だったため、...

仕事と生活を効率的に統合:SEOが成長する唯一の方法

私は1年以上もSEOの道を黙々と歩んできました。最初の驚きと新鮮さから、その後の退屈と倦怠感、そして...

virtury: パキスタン VPS、月額 10 ドルから、帯域幅 100Mbps、メモリ 1G/コア 1 個/SSD 25g/トラフィック 1T

パキスタンのホスティングプロバイダーであるVirturyは、主に仮想ホスティング、VPS/クラウドサ...