Linux 仮想化 KVM-Qemu 分析 Vhost-Net

Linux 仮想化 KVM-Qemu 分析 Vhost-Net

[[397740]]

この記事はWeChatの公開アカウント「LoyenWang」から転載したもので、著者はLoyenWangです。この記事を転載する場合は、LoyenWang公式アカウントまでご連絡ください。

背景

  • ソースコードを読んでみろよ! --魯迅著
  • 一枚の写真は千の言葉に値する。 --ゴーリキー著

例:

  • KVM バージョン: 5.9.1
  • QEMU バージョン: 5.0.0
  • ツール: Source Insight 3.5、Visio
  • この記事はブログガーデンで同期されています: https://www.cnblogs.com/LoyenWang/

1. 概要

まず、問題の概要を見てみましょう。以前の virtio シリーズの記事では、ネットワーク仮想化のフレームワークを次の図に示しました。

  • Qemu での virtio-net デバイス データ パケットの送受信は、ユーザー モードで tap デバイスにアクセスすることによって完了します。
  • 送受信プロセスには、ゲスト OS、KVM、Qemu の virtio-net デバイス、ホストのネットワーク プロトコル スタックなどの相互作用が関係します。パスが長く、多くのスイッチが関係するため、パフォーマンスが低下します。
  • vhost-net の導入により、vitio-net バックエンド デバイスのデータ処理モジュールがカーネルに組み込まれ、全体的な効率が向上します。

vhost-net のフレームワーク図は次のとおりです。

  • 図からわかるように、ゲストのネットワーク データのやり取りは vhost-net カーネル モジュールによって直接処理され、Qemu プロセスでの処理のためにカーネル状態からユーザー状態に切り替える必要はありません。
  • 前回の記事では、virtio デバイスとドライバーを分析しました。データ転送は virtio プロトコルに従うため、vhost-net に virtqueue 関連のメカニズムを実装する必要があります。

この記事では、vhost-net の原理を分析し、重要な点のみに焦点を当てて要点を述べます。

2. データ構造

vhost-net カーネル モジュールの階層構造は次のとおりです。

  • struct vhost_net: Vhost-Net デバイスを記述するために使用されます。いくつかの重要なフィールドが含まれています: 1) struct vhost_dev、一般的な vhost デバイス。これは、struct device 構造と同様に、他の特定のデバイスの構造に埋め込むことができます。 2) struct vhost_net_virtqueue は、実際には struct vhost_virtqueue をカプセル化し、ネットワーク パケットのデータ転送に使用されます。 3) struct vhost_poll は、データ パケットの受信時および送信時にタスクをスケジュールするためのソケット ポーリングに使用されます。
  • struct vhost_dev: struct vhost_net、struct vhost_scsi などの vhost メカニズムに基づく他のデバイス構造に埋め込むことができる一般的な vhost デバイスを記述します。主要なフィールドは次のとおりです。1) データ転送に対応する、割り当てられた struct vhost_virtqueue を指す vqs ポインター。 2) work_list、vhost_worker カーネル スレッドで実行する必要があるタスクを配置するために使用されるタスク リスト。 3) ワーカー。タスク リスト内のタスクを実行するために作成されたカーネル スレッドを指すために使用されます。
  • struct vhost_virtqueue: デバイスに対応する virtqueue を記述するために使用されます。この部分については、virtqueue メカニズムの以前の分析を参照してください。本質的には、Qemu の virtqueue 処理メカニズムはカーネルに組み込まれています。キー フィールドは次のとおりです: 1) struct vhost_poll、eventfd に対応するファイルをポーリングするために使用されます。処理要求が満たされない場合は、eventfd に対応する待機キューに追加されます。起動されると、構造体内の struct vhost_work (実行関数は、送信を例にとると handle_tx_kick に初期化されます) がカーネル スレッドに配置されて実行されます。

構造の中核はデータと通知のメカニズムを中心に展開され、データは vhost_virtqueue に反映され、通知は主に vhost_poll を通じて実装されます。具体的な内容については後述します。

3. プロセス分析

3.1 初期化

vhost-net は、misc デバイスとして登録されたカーネル モジュールです。 Qemu はシステム コール インターフェイスを通じてカーネルと対話します。 Qemu での初期化は次のとおりです。

  • Qemu でのタップ デバイスの初期化は net_init_tap で完了します。ここで、net_init_tap_one はカーネルの vhost-net と対話するために vhost-net デバイス ファイルを開きます。
  • vhost_set_backend_type: vhost のバックエンド タイプと vhost 操作関数のセットを設定します。現在、2 つの vhost バックエンドがあります。1 つはカーネル モードで実装された virtio バックエンドで、もう 1 つはユーザー モードで実装された virtio バックエンドです。
  • kernel_ops: いくつかのコールバック関数の実装である vhost カーネル操作関数セットは、最終的には vhost_kernel_call-->ioctl-->vhost-net.ko パスを通じて構成されます。

ioctl システム コールとドライバーの相互作用は、簡単に 3 つのカテゴリに分けることができます。以下にいくつかの重要な設定を示します。

vhost ネット設定

  • VHOST_SET_OWNER: 最下層は、上記のデータ構造の vhost_worker に対応する、呼び出し元のカーネル スレッドを作成します。同時に、呼び出し元スレッドのメモリ空間データ構造も vhost_dev 構造に保存されます。
  • VHOST_NET_SET_BACKEND: vhost-net がタップ デバイスと直接通信できるように、Qemu からカーネル状態に渡されるタップ デバイスに対応する fd などの vhost-net のバックエンド デバイスを設定します。

vhost-dev 設定

ゲスト OS の仮想アドレスからホストの最終的な物理アドレスへのマッピング関係を上の図に示します。ゲスト OS でデータを送信する場合は、ゲスト OS に関する物理アドレス レイアウト情報を Qemu に渡すだけで済みます。さらに、VHOST_SET_OWNER 中に渡されたメモリ空間情報と組み合わせることで、マッピング関係に従ってホスト上の物理アドレスに対応するゲスト OS 内のデータを見つけ、最終的な転送を完了できます。

  • VHOST_SET_MEM_TABLE: Qemu 内の仮想マシンの物理アドレスレイアウト情報をカーネルに渡します。この問題を明確に説明するために、メモリ仮想化の以前の図を見てみましょう。

vhost vring 設定

  • VHOST_SET_VRING_KICK: vhost-net モジュールのフロントエンドの virtio ドライバーが通知を送信し、最終的に handle_kick 関数の実行をトリガーするときにトリガーされる eventfd と通知メカニズムを設定します。
  • VHOST_SET_VRING_CALL: vhost-net バックエンドから仮想マシン virtio フロントエンドへの割り込み通知を設定します。前の記事の irqfd メカニズムを参照してください。
  • また、vring デバイスには、vring のサイズ、アドレス情報なども含まれます。

上記の設定のプロセス パスは次のようになります (クリティカル パスのみが描画されています)。

  • ゲスト OS の virtio-net ドライバーが初期化を完了すると、vp_set_status を介してステータスを設定し、バックエンド ドライバーに準備が完了したことを通知します。これにより、例外処理のために VM が終了して KVM に入り、最終的に Qemu にルーティングされます。
  • Qemu の vcpu スレッド監視が異常です。 KVM_EXIT_MMIO が検出されると、virtio_pci_common_write 関数など、IO 領域に登録されている読み取りおよび書き込み関数がコールバックされ、最終的に vhost_net_start 関数がレベルごとに呼び出されます。
  • vhost_net_start では、最終的に kernel_ops 関数セットを使用して、基盤となるレイヤーをセットアップし、対話します。

初期化が完了したら、データの送受信を見てみましょう。全体のプロセスを明確に表現するために、全体の図をいくつかのステップに分割して説明します。

3.2 データ転送

1)

送信前のブロック図は以下のとおりです。

  • ゲスト OS の virtio-net ドライバーは、送信用と受信用の 2 つの virtqueue を維持します。
  • 図のデータグラムは送信する必要のあるデータを表します。
  • KVM モジュールは通知メカニズムとして ioeventfd と irqfd を提供します。
  • タスクを処理するために、vhost-net モジュール内に vhost_worker カーネル スレッドが作成されます。

2)

  • データ パケットの準備が整うと、kick fd がトリガーされ、vhost_worker カーネル スレッドが起動して handle_tx_kick が呼び出され、データが送信されます。
  • Tap/Tun が送信準備ができていない場合、vhost_worker はソケットをポーリングし、Tap/Tun が起動するまで待機します。起動すると、handle_tx_net を呼び出して送信できます。
  • 最後の handle_tx は特定の送信を完了します。

3)

  • vhost_get_vq_desc 関数は、vritqueue で使用可能なバッファーを検索し、アクセスを向上させるためにその情報を iov に保存します。
  • sock->ops->sendmsg() 関数は実際には tun_sendmsg 関数を呼び出し、その中で skb 構造体が割り当てられ、iov[] 内の情報が渡されます。最後に、図に示すようにデータがコピーされて送信され、NIC を介して送信されます。

4)

  • データが送信された後、irqfd メカニズムを通じて vcpu に通知されます。

3.3 データ受信

データの受信はデータの送信の逆のプロセスであり、プロセスは同じです。

1)

初期化部分は送信プロセスと一致しています。

Tap/Tun ドライバーは NIC からデータ パケットを受信し、それを vhost-net に送信する準備をします。

2)

  • vhost-net の vhost_worker スレッドも、送信側と同様に 2 つの fd をポーリングします。
  • kick fd で信号がトリガーされると、最終的に handle_rx_kick 関数が呼び出されます。 Tap/Tun に対応するソケットで信号がトリガーされると、handle_rx_net 関数が呼び出されます。
  • 最後に、handle_rx を使用して実際の受信を完了します。

3)

  • 受信プロセス中、vhost_get_vq_desc は virtqueue 内の使用可能なバッファを取得し、その情報を iov[] に格納します。
  • sock->ops->recvmsg() 関数は実際には tun_recvmsg 関数を指しており、ここでデータ転送が最終的に完了します。

4)

データが受信されると、irqfd メカニズムを介して vcpu に渡され、ゲスト OS で処理されます。

vhost-net の全体的な内容は非常に大きく、上から下までの詳細は非常に扱いにくいです。短い記事ですべてを網羅するのは難しいので、概要だけ紹介します。

とりあえずここでやめておきましょう。

参照する

virtio-networking と vhost-net の紹介

Virtio ネットワークと vhost-net の詳細

Vhost-net デバイス IOTLB

<<:  分散フレームワークを読んで、知っておくべきNIOの基本的な知識

>>:  WebAssembly + Dapr = 次世代のクラウド ネイティブ ランタイム?

推薦する

ウェブサイトの最適化中にウェブサイトのランキングをより効果的に向上させる方法

SEO 最適化担当者の心の中では、最適化されていない Web サイトは、どれほど美しくてもゴミです。...

クラウド アプリケーション コンテナの左向き監視アプローチ

弾力性のあるコンテナ化された環境では、非効率的なコードは非常にコストがかかります。左監視アプローチと...

Demi Cloud - VPS 60% 割引、サイト全体にユニバーサル、ロサンゼルス C3/香港/福州/貴州などの複数のデータセンター

西安賴菲雲科技有限公司のブランドである Demi Cloud は、企業形式で運営されており、仮想ホス...

Mituo テンプレート: ハードウェア製品の Web サイト テンプレートの推奨

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますハードウェ...

pqhosting: イスラエルの VPS、苦情に強い、1Gbps の帯域幅、無制限のトラフィック、月額 3.77 ユーロから

モルドバに登録されている pq.hsoting は、世界中の複数のデータセンターで VPS を提供し...

分散ストレージのパフォーマンスが不十分ですか?どうすれば改善できますか?

ストレージに関して言えば、ほとんどの人はスマートフォンやパソコンに情報を保存することに慣れています。...

オンラインショッピングモールのSEOと運営戦略の共有

現在、電子商取引はあらゆる主要産業を席巻しており、新興産業が火薬なしでこの戦争に参戦しただけでなく、...

ウェブゲームの爆発的な普及の裏側:トラフィックプロバイダーが下流の利益獲得に向けて変革

ネットイーステクノロジーは2月26日夜、奇虎が発表したばかりの2011年第4四半期の財務報告で、同社...

有名ブロガーから学ぶウェブサイトの直帰率を下げる方法

誰もが Lu Songsong を知っていると思います。彼のブログは、中国で最も優れた個人ブログの ...

新旧のオンライン商人がオンラインで医薬品の購入に殺到。開心人は数千万ドルの資金を受け取る

半年にわたる静かな準備期間を経て、その高い収益性から新旧のオンライン小売業者から長い間切望されてきた...

ユーザー エクスペリエンスは外部リンクの構築から始まります。効果的なクリックが生成されて初めて、外部リンクは高品質になります。

現在、すべてのウェブマスターとSEO担当者は、外部リンクの構築に多大な注意を払っています。彼らは、リ...

中国本土で米国株に投資する個人向けガイド

中国本土の居住者の投資チャネルは比較的狭い。銀行は低金利で預金を集め、株式市場は長期の弱気相場にあり...

テンセントクラウドTStackと中標麒麟が相互認証を取得

最近、Tencent Cloud TStack は Kylin アドバンス サーバー オペレーティン...

SFエクスプレスの成長は困難:電子商取引のブルーオーシャンに直接「参入」するのは難しい

国慶節の連休1週間前、順義区にあるSFエクスプレスの北京配送センターは、連休前の業務量の増加により忙...