Virtio の基本1. virtioの提案 システム仮想化技術は、クラウド コンピューティングの最も重要なコア技術の 1 つです。クラウド コンピューティング プラットフォームのリソース プーリング、統合リソース管理、およびそれに続く動的割り当てはすべて、システム仮想化テクノロジに基づいて可能になります。コンピュータ システムには、主にコンピューティング リソース、ストレージ リソース、ネットワーク リソースがあります。したがって、システム仮想化テクノロジは、コンピューティング仮想化、ストレージ仮想化、ネットワーク仮想化にさらに分類できます。ストレージデバイスやネットワークデバイスは、一般的に周辺機器の形で I/O バスを介して CPU に接続されるため、ストレージ仮想化とネットワーク仮想化は総称して I/O 仮想化技術として分類できます。ここで紹介する virtio は、最も人気のある I/O 仮想化テクノロジーです。 I/O 仮想化テクノロジーは、完全仮想化と準仮想化の 2 つのタイプに分けられます。
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 パフォーマンスが大幅に向上します。
Virtio は、仮想マシン カーネルにフロントエンド ドライバーを実装し、QEMU にバックエンド シミュレーション デバイスを実装します。フロントエンドとバックエンドは、仮想キュー (Virtqueue) を介して通信し、データを交換します。 Virtio デバイスには、さまざまなバス メカニズムに対してさまざまな実装方法があります。 PCI デバイスは最も広く使用されているデバイスであるため、virtio の PCI ネットワーク カードを例にして説明します。 virtio-net フロントエンドとバックエンドの実装を図 2 に示します。 図[1] QEMU/KVM での virtio-net フロントエンドとバックエンドの実装
仮想マシンが起動すると、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 つあります。
仮想キュー (Virtqueue) は、virtio フロントエンド ドライバーと virtio バックエンド シミュレート デバイス間の双方向データ転送に使用されるデータ構造です。各 virtio デバイスは 1 つ以上の仮想キューを維持します。 virtio ネットワーク デバイスを例にとると、少なくとも 2 つの仮想キューが維持されます。1 つは送信するデータを格納するためのもので、もう 1 つは受信した受信確認を格納するためのものです。各仮想キュー データ構造は、記述子テーブル、使用可能なリング、使用済みリングの 3 つの部分で構成されます。
図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_packets() では、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 年代に情報技術が初めて組織に広く導入されて以来、開発サイクルは、多くの人が振り子の揺れに例...
ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスデジタル時代の重要なマー...
1. JVMチューニングの概念データ型Java 仮想マシンでは、データ型はプリミティブ型と参照型の ...
プロメテウスは私たちにもう一つの驚きをもたらしました。今回、その3つのブランドが同時にセール対象とな...
これは、virmach の今年最後の格安 VPS になるかもしれません。最低価格は年間 6.3 ドル...
コンテンツとは、インターネット上で公開されるすべての情報を指します。コンテンツは、ユーザーが読んでニ...
SEOは関連性が重要検索エンジンでキーワードを検索すると、通常、多数のページが返されます。これらのペ...
現在から 6 月末まで、digital-vm はすべての VPS を 40% 割引 (40% の値下...
この記事は単なる概念です。ここで詳細に説明するには、具体的な構成が多すぎます。 1. 分散アプリケー...
仮想マシン (VM) とコンテナは現在主流のテクノロジーですが、どちらにも欠点があり、モビリティの低...
Vancl(別名VANCL)は、Joyo.comの創設者であるChen Nianの傑作です。 Van...
Oracle OpenWorld のオープニング基調講演で、Oracle 会長兼 CTO の Lar...
著者はかつて多くのウェブマスターと同じでした。当初、ウェブサイトのポジショニングが不正確だったため、...
私は1年以上もSEOの道を黙々と歩んできました。最初の驚きと新鮮さから、その後の退屈と倦怠感、そして...
パキスタンのホスティングプロバイダーであるVirturyは、主に仮想ホスティング、VPS/クラウドサ...