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 = 次世代のクラウド ネイティブ ランタイム?

推薦する

WeChat公開アカウントプロモーションのコメント欄でフォロワーを増やす方法!

公開アカウントを運営する人にとって、フォロワーを増やすことは第一のミッションです。公開アカウントのツ...

出会い系サイトの何が問題なのですか? 発展の余地は大きいが、完璧ではない

編集者注: この記事はかなり長いです。コメントする前にじっくり読んでいただくことをお勧めします。積極...

vpsdime: 年間 7 ドル、OpenVZ7、1G メモリ/1 コア/10g SSD/1T 帯域幅、ダラス データ センター

vpsdime の最後のプロモーションは 2018 年 7 月 22 日でした。現在、年間 20 ド...

ビットコイン価格が28%急落:中央銀行の声明がプレイヤーの信頼に打撃

新浪科技報、北京時間12月17日朝のニュースによると、中国人民銀行の最新の規制要求の影響を受けて、ビ...

VMware が IT チームの負担を軽減し、従業員のエクスペリエンスを向上させる新しい Anywhere Workspace 機能を発表

今日のハイブリッドな作業環境において、IT チームはさまざまな新たな課題に取り組んでいます。従業員は...

数十億のトラフィックがあるシステムで JVM を使用する方法

[[340168]]この記事はWeChatの公開アカウント「Shooter Teacup」から転載し...

hostodo-4Gメモリ高構成OVZの簡単なテスト、効果はちょっと驚きです!

一昨日、hostodo についての記事を書きました。最新の KVM 仮想 VPS についての記事で、...

検索エンジン最適化 (I): フォーラム署名値分析

ウェブサイトの外部リンクを最適化する方法は無数にありますが、最も簡単な最適化方法は「フォーラム署名」...

おすすめ: 無料申請 - 交通銀行クレジットカード

私は2008年に交通銀行のクレジットカードを使い始めました。当時、劉翔ビザカードを取得しました。当時...

なぜウェブマスターはBaiduを批判したがるのでしょうか?

Baidu は検索分野とテクノロジーに非常に強い企業であり、今後さらに発展していくことは間違いありま...

中国本土の住民は米国株と香港株をどのように購入するのでしょうか?

国内資金が海外に投資する場合、最も人気のある投資市場は香港株と米国株です。多くの投資家は香港株に精通...

企業のビジネスをクラウド プラットフォーム間で移行するのはどれほど難しいのでしょうか?

企業が自社のアプリケーションとサービス、そして各クラウド プロバイダーが提供するサービスについて十分...

dedipath - 安価なクラスターサーバー/512IP/E3-1270/32g メモリ/1Gbps 帯域幅

IPv4 の価格が高騰しているため、最近では安価なクラスター サーバーが少なくなっています。SEO ...

Webmaster.com からの毎日のレポート: 多くのリベート ウェブサイトが崩壊し、JD.com は再び上級幹部を失った

1. 30近くのリベートサイトが次々と崩壊:電子商取引がねずみ講に変貌太平洋直購ネットワークが河南省...