40GbE読み出しテスト
Esys 千代浩司
SiTCP-XGはSiTCPの10Gbps版である。Esys東海ではSiTCP-XG4台をネットワークスイッチで束ねて40GbE NICで読みだすテストをおこなった。
1. SiTCP 10GbE以前 (2015年ごろ)
10GbE NICが2個付いているPCを用意し、LANケーブルを接続しiperf3でテストを行った。そのままだとパケットはloデバイス上を流れワイヤーには全然パケットが流れないのでルーティングテーブルを設定しテストを行った。
テストはTCPオプションのWindow scale optionの有無、time stampオプションの有無の設定を行いスループットの測定を行った。
10GbEではwindow scale optionのサポートがないとスループットが出ないことが確認できた。(注)100Mbps, 1Gbps SiTCPはwindow scale optionサポートしていない。
2. SiTCP-XG (10GbE SiTCP)
2020年にSiTCP-XGのα版が出た。
接続時のSYN-ACK-SYNをtcpdumpでパケットキャプチャしwindow scale optionがサポートされていることを確認した。
3. AMANEQ (10GbE読み出しテスト)
AMANEQで10GbE読み出しテストを行い、スループットとしてほぼ性能限界の9.5Gbpsでることを確認した。
4. 10GbE x 4 = 40Gbps読み出しテスト
10GbEポートが20、40GbEポートが4個あるスイッチを準備し、AMANEQ 4台からのデータをスイッチで束ねて40GbEで読み出せるかどうかのテストを行った。読み出しプログラムとしてLinux epollを使って1プロセスで多重読み出しを行う方法、及びAMANEQ 1台に付いて1プロセスを割り当てるマルチプロセスの読み出し方法を試した。
4.1 Linux epollを使う方法
プロセスがCPUを100%使っても40Gbps読み出しができなかった。
4.2 マルチプロセスを使う方法
だいたいは40Gbps近くで読み出せるのだが、ときどきスループットが大幅に落ちる現象が起きた。tcpdumpでパケットキャプチャしてみると約0.5秒間データがこないことがあることがわかった。データがこない時間はほぼ正確に0.5秒であった。SiTCP-XG取り扱い説明書をみるとSiTCPの再送タイムアウトのデフォルト値が0.5秒であることがわかった。
再送が起きていることはわかったのでその原因を調べてみた。
まずスイッチでパケットが落ちているのではないかと思いスイッチの統計情報を取得してみたがパケットドロップカウンターはパケットドロップを記録していなかった。
続けてsoftirqに使うバッファが足りなくなっていないかどうか調べたが、足りなくなっている場合に増加するはずの統計情報はそのようなことはないことを示していた。
最後にNICの統計情報を取得してみるとNICでパケットを落としていることが確認できた。これはNICのリングバッファ数が足りていないのが原因である。が、NICのリングバッファ数を最大値に設定してみてもなおパケットドロップが確認できた。
NICドライバはリングバッファがいっぱいになりそうになるとPauseフレームを送出し、通信相手側が一定期間データの送信をやめるように依頼する。この機能が有効に働くためにはネットワークスイッチがpause frameをサポートしている必要がある。通常よく使われるネットワークスイッチではpause frameはデフォルトでサポートされているようになっていることが多い。今回使用したスイッチではデフォルではpause frameのサポートは無効になっていた。pause frameのサポートを有効にするとパケットドロップは発生しなくなり、ほぼ40Gbpsでの読み取りができるようになった。
5. プログラムからのpause frameの送出
Linuxではsocket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_PAUSE))を使うことでプログラムからpause frameを送出することが可能である。(注)このソケットのclose()には約8ミリ秒という桁外れの時間がかかる。原因は不明(注終わり)。
今回使用した40GbE NICでpause frameを送出するプログラムを走らせてみたがpause frameは全然送出されなかった。他のたとえば10GbE NICあるいは1GbE NICでは正常に送出されていることが確認できた。原因を探ってみると、ドライバ内に、ある脆弱性を利用した攻撃に対応するためユーザープログラムからはpause frameは送出できないようにするコードが入っていることが確認できた。このワークアラウンドを無効にしたドライバを作ってみると無事pause frameが送出できた。