3

仮想マシン (VM) の TCP/UDP パフォーマンスを改善するためにいくつかの調査を行ったときに、いくつかの問題に遭遇しました。誰かが私の問題を処理するための助けや提案を提供できる場合は、非常に高く評価されます。

RPS と RFS は物理マシンではうまく機能しますが、VM では機能しない場合があります。たとえば、RFS は、対応する受信プロセスを実行している CPU に IRQ を送信することを目的としています。ただし、複数の vCPU が 1 つの物理 CPU (pCPU) を共有している場合、各 VM の仮想 CPU (vCPU) は常にオンラインになるとは限りません (ここでは、vCPU のスケジューリングがラウンドロビンであると簡単に想定できます)。したがって、IRQ をオフラインの vCPU に送信しても、ターゲット ユーザー レベルのプロセスが実行されていても意味がありません。理論的には、VM の実行中の vCPU に NIC IRQ を送信すると、NIC IRQ 処理のレイテンシが短縮され、TCP/UDP のパフォーマンスが向上します。そのため、ほぼ常にオンラインになっている仮想コプロセッサ (co-vCPU) を各 VM に割り当て、VM の NIC IRQ をこの co-vCPU に固定します。VM のゲスト OS のビューから、ユーザー プロセス (例: iperf) は 1 つのコアで実行され、eth0 の IRQ コンテキストは別のコアで実行されます。私の実験では、UDP ではうまく機能しますが、TCP では機能しません。

プロセス コンテキストと IRQ コンテキストの同期によるものとは思えません。Linux で TCP 層のソース コードを読んだときに、IRQ コンテキスト (net/ipv4/tcp_ipv4.c の tcp_v4_rcv() など) とユーザー コンテキスト (net/ipv4/tcp.c の tcp_recvmsg() など) の両方が見つかったからです。カーネル内のバッファ (receive_queue、backlog_queue、prequeue) にアクセスするときに lock_sock()/unlock_sock() を呼び出します。したがって、ユーザー レベルの受信プロセス (iperf サーバー) を実行する別の vCPU によってロックされた受信バッファーに IRQ がアクセスできず、ロックを保持しているこの vCPU が VM モニター (VMM) またはハイパーバイザーによってスケジュール解除されている場合があります。

私の問題を明確に説明したかどうかはわかりません。とにかく、それに関する提案を歓迎します。

4

0 に答える 0