[翻訳] QEMU内部機構:バーチャルホスト・アーキテクチャ

オリジナルリンク: http://www.cnblogs.com/qxxnxxFight/p/11046855.html

シリーズ:

  1. [翻訳] QEMU内部機構:マクロアーキテクチャとスレッディングモデル
  2. [翻訳] QEMU内部機構:バーチャルホスト・アーキテクチャ(紙)
  3. [ 翻訳] QEMU内部機構:トップレベルの概要を
  4. [翻訳] QEMU内部機構:メモリ

オリジナル住所:のhttp://blog.vmsplice.net/2011/09/qemu-internals-vhost-architecture.html

オリジナル日:2011年9月7日

著者:ブロック層QEMUプロジェクト、ネットワークサブシステムおよびトレースサブシステムの開発と保守を担当するのRed Hatからのステファン・Hajnoczi仮想チーム、。

本研究でQEMUにおけるマルチコアデバイスエミュレーションとVSOCKを使用してホスト/ゲストファイル共有は、ディスクイメージフォーマット、ストレージ移行およびI / Oパフォーマンスの最適化に従事して過去に、あります

QEMU内部メカニズム:バーチャルホストのアーキテクチャ

この記事では、バーチャルホストのメカニズムは、KVMカーネルレベルのためのvirtio機器のサポートを提供する方法を明らかにする。
私自身の最近の研究のvhost-SCSI、およびioeventfd、irqfdとバーチャルホスト関連について多くの質問に答えたので、私は誰もがQEMU内部機構は非常に便利です、この記事を理解すると思います。

説明バーチャルホスト
Linuxでは、バーチャルホストドライバは、カーネルレベルのvirtioデバイスシミュレーションを提供します。
これに先立ち、あるvirtioは、一般的にシミュレーションにバックエンドプロセスQEMUのユーザ空間で駆動されます。
バーチャルホストのバックエンドドライバのvirtioカーネルで達成、ユーザ状態QEMUのvirtio機構から除去されます。
これは、ユーザーせずにシステムから呼び出すことによって、デバイスシミュレーションコードは直接カーネル・サブシステムの状態関数を呼び出すことができます。

バーチャルホストを実装するための最も初期の形であり、唯一のLinuxのメインドライブに受け入れられているIO関連するカーネルモードシミュレートネットワークカード、でのバーチャルホストネットのドライバ。一方、バーチャルホスト-BLKとのvhost-SCSIのプロジェクトも開発中です。

バーチャルホストのコード・ドライバ/バーチャルホスト/中のLinuxカーネルv3.0の。

すべての機器はVRINGのVMとの対話ハンドラのすべてのデバイスが含まれている一般的なコードのvirtioドライバ配置/バーチャルホスト/ vhost.cで使用されています。

バーチャルホストネットドリブンコードのドライバ/バーチャルホスト/ net.cインチ

バーチャルホスト駆動型モデル
のvhost-netのドライバがホストデバイス上の/ dev /バーチャルホストネットキャラクター作成され、デバイスは、インタフェースのvhost-netのインスタンスです。
QEMUプロセスは、タップを-netdevする場合は、バーチャルホスト=パラメータの起動時に、初期化のvhost-netのインスタンスを達成するために、ioctl呼び出しは/ dev /バーチャルホストネットを使用しています。

バーチャルホストネットドライブに渡される物理メモリマッピングVMのネゴシエーションのvirtio特性のために準備するために、そのインスタンスのバーチャルホストネットアップに関連付けられたQEMUプロセス:この操作は3つの役割を有しています。

初期化中に、バーチャルホストドライバがイベントを処理し、IOデバイスのエミュレーションを実行し、「バーチャルホストのワーカースレッド」と呼ばれる糸のvhost- $ pid_of_qemuと呼ばれるカーネルスレッドを作成します。

本番環境qemu- KVMプロセスパラメータ:
QEMU 2726347  。1 -netdev TAPは/ usr / libexecに/ QEMU、KVM、FD = 40、ID = hostnet0、バーチャルホスト= ON、vhostfd = 42であり
、対応するカーネル・スレッド:
ルート2726349  2 [vhost- 2726347 ]

カーネルモードのしくみ
バーチャルホストは完全なのvirtio PCIアダプターをシミュレートしていない、それが唯一の処理virtqueueのために使用されています。
バーチャルホストのメカニズムでは、我々はまだ、そのような交渉、ライブマイグレーションやその他の操作などのvirtio特性にQEMUを使用します。
すなわち、独立した駆動バーチャルホストのvirtioデバイス実装、制御プレーンは、カーネルモードにある間、それはデータプレーンの処理を実装することにより、ユーザ・モード・プロセスではありません。

「バーチャルホストのワーカースレッドは、」キックのvirtqueueを待って、その後、virtqueueにデータバッファを処理します。
バーチャルホスト-netは、それを駆動するために、パケットから削除され、ファイルディスクリプタタップデバイスにそれらvirtqueue TXを送信します。

ファイルディスクリプタはまたのための「バーチャルホストの労働者」責任があるタップするポーリング機器を覚ます、スレッドはタップにパケット内のデバイス、およびパケットに到着します(この場合には、それはFDを監視するのepollメカニズムを使用していることです) VMが受信できるようにRX virtqueue配置。

動作原理の「バーチャルホストワーカースレッド」
魔法のバーチャルホストのアーキテクチャは、それが唯一のKVMのために設計されていないということです。バーチャルホストは、ユーザ空間へのインタフェースを提供し、KVMカーネルモジュールに完全に依存しています。
これは、他のユーザーにも、理論的には、例えば、あなたが便利で効率的なIOインターフェースのlibpcapが必要な場合(tcpdumpのライブラリを使用)スペースコードバーチャルホストデバイスを使用できることを意味します。[どのようなシーン?]

、VMがキックをホストするためのイベント、今回virtqueue、メカニズムは「バーチャルホストワーカースレッド」を通知するために必要なときにバッファがVMを配置しているときに実行する新しいタスクがあります。

KVMモジュールとのバーチャルホストが独立しているため、直接それらの間の相互作用はありません。バーチャルホストの例は、起動時にファイルディスクリプタのeventfdが割り当てられます、「バーチャルホストのワーカースレッドは、」のeventfdを聞きます。KVMはioeventfd機構が呼び出されており、それは、特定のイベント(I / O操作のためのVM、バーチャルマシン出口戻るVMMに制御をCPUのVMによって)のIO出口VMへのeventfdフック(フック)とすることができます。イベントはioeventfdを登録virtqueue QEMUのユーザ空間プロセスがVIRTIO_PCI_QUEUE_NOTIFYハードウェアレジスタへのアクセスを開始しました。

このように、「バーチャルホストのワーカースレッドは、」KVMモジュールは、VM virtqueueを起動したときに通知することができるようになります。

帰りは、「バーチャルホストのワーカースレッドは、」同様の方法でVMを中断し始めました。バーチャルホストは「irqfd」ファイルディスクリプタを受け入れ、VMをキックするためにデータを書き込みます。
KVMはirqfdメカニズムはのeventfdのVMが割り込みを開始するために呼び出されました。QEMUのユーザ空間プロセスのvirtio PCIデバイスがirqfd割り込みレジスタ、およびバーチャルホストインスタンスを通知しました。
このように、「バーチャルホストのワーカースレッドは、」中止VMを開始することができます。

要するに、バーチャルホストの例は、VMのメモリマップおよびコールバックのためのeventfdとirqfdの開始のための1つの知覚します。

参照コード:
ドライバ/バーチャルホスト/ vhost.c -バーチャルホストデバイスは、汎用コードを使用します
ドライバー/バーチャルホスト/ net.cを- vhost-駆動
ioeventfdとirqfd -のvirt / KVM / eventfd.cを

:コードは、インスタンスのバーチャルホストQEMUのユーザ空間初期化するために使用される
-バーチャルホスト機器の一般的な初期化コードHW / vhost.c
HW / vhost_net.c -バーチャルホストネットドライバの初期化コードを

=== ===注目コメント
コメント1:
方法は、QEMUに、プロセスへのDMAアクセスを示したが
何の初期化ここでDMA-転送である例示することができる
だけの物理的なNICドライバがその中に缶:私は理解していますDMA操作がでRX / TXバッファを行い、
バーチャルホスト自体がサポートされていません。
そして、ソケットを介して物理NICドライババーチャルホストは、それを伝えるために?
だから、RX / TXバッファの送信は、それ通常のmemcpyを使用していますか?
1返信:
:メモリ・コピーおよびDMAについて
のvhost-NETサポートゼロコピー伝送モード。すなわち、直接RAMマッピングされたDMA VM物理NICを介して達成するためにあります。
受信パスでは、まだのVMカーネルモードのソケットバッファRAM(これまでのプロセスによってマッピングされたRAM QEMUのユーザ空間)へのホストからのメモリコピー処理の必要性。
あなたはhandle_txのドライバー/バーチャルホスト/ net.c()とhandle_rx()関数を参照することができます。
物理NIC上のソケットとバーチャルホスト通信
バーチャルホスト-NETドライバは、物理NICと直接通信せず、唯一のtunデバイス(タップ又はmacvtap)駆動取引。
タップデバイスは、一般に、物理NICにデータを送信するために、ブリッジに入れました。
バーチャルホストネット構造は、カーネルモードのソケットインタフェースを使用して、だけドライブをTUNの例で動作します。これは、従来のソケットファイルディスクリプタを使用することを拒否します。ドライバー/バーチャルホスト/ net.cを参照することができます:get_tap_socket( )
注意:それはカーネルだけで使用されているようTUN駆動ソケットは、AF_PACKETソケットユーザ空間として、ユーザ空間へのソケットファイルディスクリプタの形式で公開されていません。

 

 

これは次のように読み取ります。

QEMUの内部:バーチャルホストのアーキテクチャ

この投稿は、バーチャルホストはカーネル内KVM用のvirtioデバイスを提供する方法について説明します。私はバーチャルホスト-SCSIにハッキングされており、最近ioeventfd、irqfd、およびバーチャルホストについての質問に答えてきたので、私は、これは便利なQEMUの内部ポストだろうと思いました。

バーチャルホストの概要

Linuxでのバーチャルホストドライバはカーネル内のvirtioデバイスのエミュレーションを提供します。通常、QEMUのユーザ空間プロセスは、I / Oがゲストからのアクセスをエミュレートします。バーチャルホストは、絵のうち、QEMUのユーザースペースを取って、カーネルにvirtioをエミュレーションコードを置きます。これは、デバイスのエミュレーションコードを直接代わりにユーザ空間からのシステムコールを実行するカーネル・サブシステムを呼び出すことを可能にします。

バーチャルホストネットドライバがホストカーネル内のvirtio-netのネットワークカードをエミュレートします。バーチャルホスト-netは、最も古いバーチャルホストデバイスとメインラインのLinuxで利用可能な唯一のものです。実験のvhost-BLKとのvhost-SCSIデバイスも開発されています。

Linuxの3.0でバーチャルホストコードはに住んでいる  ドライバー/バーチャルホスト/すべてのデバイスで使用される一般的なコードはである  ドライバー/バーチャルホスト/ vhost.cこれは、すべてのvirtioデバイスがゲストと通信するために必要なアクセス機能をVRINGのvirtioを含んでいます。バーチャルホストネットコードがに住んでいる  ドライバー/バーチャルホスト/ net.c

バーチャルホストドライバモデル

バーチャルホストネットドライバが作成されます  の/ dev /バーチャルホストネット  ホスト上のキャラクタデバイスを。このキャラクタデバイスは、バーチャルホスト-netのインスタンスを設定するためのインタフェースとして機能します。

QEMUを用いて起動すると  -netdevタップ、バーチャルホスト上=  が開く  の/ dev /バーチャルホストネットを  、いくつかとバーチャルホストネットインスタンスを初期化する  のioctl(2)  を呼び出します。これらは、バーチャルホストネットインスタンスとQEMUプロセスを関連付けるのvirtio機能ネゴシエーションの準備、およびバーチャルホストネットドライバにゲスト物理メモリマッピングを通過する必要があります。

初期化中にバーチャルホストドライバは、$ pidはQEMUのプロセスpidでvhost- $ pidのと呼ばれるカーネルスレッドを作成します。このスレッドは、「バーチャルホストのワーカースレッド」と呼ばれています。ワーカースレッドの仕事は、I / Oイベントを処理し、デバイスエミュレーションを実行することです。

カーネル内のvirtioエミュレーション

Vhost does not emulate a complete virtio PCI adapter. Instead it restricts itself to virtqueue operations only. QEMU is still used to perform virtio feature negotiation and live migration, for example. This means a vhost driver is not a self-contained virtio device implementation, it depends on userspace to handle the control plane while the data plane is done in-kernel.

The vhost worker thread waits for virtqueue kicks and then handles buffers that have been placed on the virtqueue. In vhost-net this means taking packets from the tx virtqueue and transmitting them over the tap file descriptor.

File descriptor polling is also done by the vhost worker thread. In vhost-net the worker thread wakes up when packets come in over the tap file descriptor and it places them into the rx virtqueue so the guest can receive them.

Vhost as a userspace interface

One surprising aspect of the vhost architecture is that it is not tied to KVM in any way. Vhost is a userspace interface and has no dependency on the KVM kernel module. This means other userspace code, like libpcap, could in theory use vhost devices if they find them convenient high-performance I/O interfaces.

When a guest kicks the host because it has placed buffers onto a virtqueue, there needs to be a way to signal the vhost worker thread that there is work to do. Since vhost does not depend on the KVM kernel module they cannot communicate directly. Instead vhost instances are set up with an eventfd file descriptor which the vhost worker thread watches for activity. The KVM kernel module has a feature known as ioeventfd for taking an eventfd and hooking it up to a particular guest I/O exit. QEMU userspace registers an ioeventfd for the VIRTIO_PCI_QUEUE_NOTIFY hardware register access which kicks the virtqueue. This is how the vhost worker thread gets notified by the KVM kernel module when the guest kicks the virtqueue.

同様のアプローチが使用されているゲストを中断するバーチャルホストのワーカースレッドからの帰りで。バーチャルホストは、ゲストをキックするために、に書きます「と呼んで」ファイルディスクリプタを取ります。KVMのカーネルモジュールはのeventfdは、ゲスト割り込みをトリガすることができますirqfdと呼ばれる機能があります。QEMUのユーザ空間は、のvirtio PCIデバイスの割り込みのirqfdを登録し、バーチャルホストインスタンスにそれを渡します。これは、バーチャルホストのワーカースレッドがゲストを中断することができる方法です。

最終的にはバーチャルホストインスタンスは、ゲストメモリマッピング、キックのeventfd、およびコールのeventfdについて知っています。

どこより多くを見つけるために

ここでは、コードを模索し始めるための主なポイントは以下のとおりです。
  • ドライバー/バーチャルホスト/ vhost.c  -共通のバーチャルホストドライバコード
  • ドライバー/バーチャルホスト/ net.c  -バーチャルホストネットドライバ
  • virt / KVM / eventfd.c  - ioeventfdとirqfd
QEMUのユーザ空間のコードでは、バーチャルホストインスタンスを初期化する方法を示しています。
  • HW / vhost.c  -共通のバーチャルホストの初期化コード
  • HW / vhost_net.c  -バーチャルホスト、ネットの初期化

ます。https://www.cnblogs.com/qxxnxxFight/p/11046855.htmlで再現

おすすめ

転載: blog.csdn.net/weixin_30193897/article/details/95295500