Multiqueue Networking

PassthroughやマルチキューNIC仮想マシンボトルネックであるI/Oの性能をネイティブとほぼ同等にすることができる技術です.特にマルチキューNICは複数のVMのネットワーク性能を上げることができる(はず)の期待のハードウェア技術です.

VM向けのマルチキューNICはまだほとんど実装されていないですが(Intel 10GbE NICだけ?),送信キューを複数もつNICはすでに一般的になりつつあるようです.

以下では,linux-2.6.27-rc1でマージされたLinuxのマルチキューNICパッチに関する記事(Multiqueue networking [LWN.net])を少しだけ翻訳したものです.このパッチは送信キュー対応だけで,VMで重要になる受信キューに関してはまだ未対応のようですが,Linuxの機能を活用するKVMにとっては重要な一歩だと思います.

なお,翻訳は大雑把なので,正しい情報を得たい場合は,元記事を参照してください.

Multiqueue Networking

ネットワークサブシステムの基本的なデータ構造に個々のデバイスに割り当てられた送信キューがある。ドライバのhard_start_xmit()によりパケットが送信可能であることを知らせられたドライバは、そのパケットをハードウェアの送信キューに配置する。skbに格納されたパケットはデバイス毎のキューのようにも見えるが、実際のところそこまで単純ではない。(skbはフラグメントしたパケットを格納可能である。)ドライバはキュー内のskbからパケットを取り出してデバイスが処理可能な形にしなければならない。

この方法はしばらくの間はうまくいっていたが、最近根本的な問題が生まれた。すなわちその方法は複数の送信キューをもつデバイスにうまくパケットをマップすることができないのである。
そのようなデバイス、特に無線ネットワーク領域では年々一般的になりつつある。Wireless Multimedia Extensions規格を実装したデバイスは、4つのサービス種別をもつ。すなわちビデオ、音声、ベストエフォート、バックグラウンドである。ビデオと音声トラフィックは他のものより高いプライオリティをもち、優先的に送信され、多くの無線帯域を得ることができる。その代わり、そのようなトラッフィクは比較的短いキューをもつかもしれない。ビデオパケットが正しく必要な早さで送信されなければ、受信側はそのパケットが不要になるだろう。そのため、なかなか送信されないビデオパケットは単に破棄することが有効になるかもしれない。

一方、バックグラウンドのパケットは他に処理すべきパケットがない場合だけ送信される。これはBitTorrentやボスからのメール(笑)のような低いプライオリティのトラフィックによく合う。このようなバックグラウンドのパケットには、高いプライオリティのパケットの合間を有効活用するため、比較的長いキューを持つ方が良いだろう。

このようなデバイスは、それぞれのサービス種別毎に送信キューをもつ。このトラフィックの分離は、どのパケットを次に送信すれば良いかをハードウェアが選択することを簡単にするし、キュー毎に独立したキューサイズの制限をかけることができる。しかし、現在のネットワークサブシステムはまっとうなマルチキューデバイス対応がなされていない。いくつかのアドホックで最適化されていない方法がとられているだけである。とはいえ、この状況はDavid Millerのパッチで変わろうとしている。

現在のコードはネットワークデバイスは、送信パケットスケジューラによって管理される一つのユニットとして扱われている。Davidのパッチはこれをここのキューを独立して扱えるように変える。そのため、個々の送信キューの情報を隠すためのnetdev_queueデータ構造が新たに追加された。その結果、マルチキューデバイスはnetdev_queueの配列をもち、個々のnetdev_queueがskbをもつ構造になる。