11

パケットがNICによってキャプチャされた後に何が起こるかについて読んでいますが、読むほど混乱します。

まず、従来、パケットがNICによってキャプチャされた後、カーネルスペースのメモリブロックにコピーされ、次にパケットデータを処理するアプリケーションのユーザースペースにコピーされることを読みました。次に、DMAについて読みました。ここでは、NICがCPUをバイパスしてパケットをメモリに直接コピーします。では、NIC->カーネルメモリ->ユーザースペースのメモリフローはまだ有効ですか?また、ほとんどのNIC(Myricomなど)はDMAを使用してパケットキャプチャレートを向上させていますか?

次に、RSS(Receive Side Scaling)はWindowsシステムとLinuxシステムの両方で同様に機能しますか?RSSがどのように機能するかについての詳細な説明はMSDNの記事でしか見つけることができません。そこでは、RSS(およびMSI-X)がWindows Server 2008でどのように機能するかについて説明しています。しかし、RSSとMSI-Xの同じ概念はLinuxシステムにも当てはまります。 ?

ありがとうございました。

よろしく、レイン

4

2 に答える 2

18

このプロセスがどのように実行されるかは、主にドライバーの作成者とハードウェア次第ですが、私が調べたり書いたりしたドライバーと私が使用したハードウェアの場合、通常は次のように動作します。

  1. ドライバーの初期化時に、いくつかのバッファーが割り当てられ、NIC に渡されます。
  2. パケットが NIC によって受信されると、NIC はバッファのリストから次のアドレスを引き出し、データをそこに直接 DMA し、割り込みを介してドライバに通知します。
  3. ドライバは割り込みを受け取り、バッファをカーネルに渡すか、新しいカーネル バッファを割り当ててデータをコピーします。「ゼロ コピー ネットワーキング」は前者であり、明らかにオペレーティング システムによるサポートが必要です。(これについては以下で詳しく説明します)
  4. ドライバーは、新しいバッファーを割り当てる必要があります (ゼロコピーの場合)、またはバッファーを再利用します。いずれの場合も、バッファは将来のパケットのために NIC に返されます。

カーネル内のゼロコピー ネットワークはそれほど悪くありません。ユーザーランドまでゼロコピーするのははるかに困難です。ユーザーランドはデータを取得しますが、ネットワーク パケットはヘッダーとデータの両方で構成されています。少なくとも、ユーザーランドまでの真のゼロコピーには、NIC からのサポートが必要です。これにより、パケットを個別のヘッダー/データ バッファーに DMA できるようになります。カーネルがパケットを宛先にルーティングし、チェックサムを検証すると、ヘッダーはリサイクルされます (TCP の場合、NIC がサポートしている場合はハードウェアで、サポートしていない場合はソフトウェアで、カーネルがチェックサム自体を計算する必要がある場合は、同様に、データをコピーすることもできます。データを参照するとキャッシュ ミスが発生し、チューニングされたコードを使用すると、データを別の場所にコピーできます)。

すべての星が揃っていると仮定しても、データがシステムによって受信されたとき、実際にはユーザー バッファーにはありません。アプリケーションがデータを要求するまで、カーネルはそれがどこに行き着くかを知りません。Apache のようなマルチプロセス デーモンの場合を考えてみましょう。多くの子プロセスがあり、すべてが同じソケットでリッスンしています。また、接続を確立することもできfork()、両方のプロセスがrecv()データを受信できます。

インターネット上の TCP パケットは、通常 1460 バイトのペイロードです (1500 の MTU = 20 バイトの IP ヘッダー + 20 バイトの TCP ヘッダー + 1460 バイトのデータ)。1460 は 2 の累乗ではなく、どのシステムのページ サイズとも一致しません。これにより、データ ストリームの再構成に問題が生じます。TCP はストリーム指向であることを思い出してください。送信側の書き込みには区別がなく、受信側で待機している 2 つの 1000 バイトの書き込みは、2000 バイトの読み取りで完全に消費されます。

これをさらに進めて、ユーザー バッファーについて考えてみましょう。これらはアプリケーションによって割り当てられます。ゼロコピーに最後まで使用するには、バッファをページに合わせて配置し、そのメモリ ページを他のものと共有しないようにする必要があります。理論的にはrecv()、カーネルは古いページをデータを含むページに再マップして所定の位置に「フリップ」することができますが、連続するパケットが別々のページにあるため、上記の再構成の問題によって複雑になります。カーネルは、各パケットのペイロードに返すデータを制限できますが、これは、多くの追加のシステム コール、ページの再マッピング、および全体的なスループットの低下を意味します。

私は本当にこのトピックの表面をなぞっているだけです。私は 2000 年代初頭にいくつかの企業で働き、ゼロコピーの概念をユーザーランドにまで拡張しようとしました。ユーザーランドに TCP スタックを実装し、スタックを使用するアプリケーションのためにカーネルを完全に回避しましたが、それ自体が一連の問題を引き起こし、決して製品品質ではありませんでした。解決するのは非常に難しい問題です。

于 2010-04-27T17:16:18.313 に答える
-1

この論文を見てください

于 2010-04-26T20:21:45.350 に答える