TCPタイムアウトの変更(1)

Linux kernelの2.6.18のTCPのタイムアウト時間を変更したいため、kernel実装を見つめる。

RTO(Retransmission TimeOut)が関係していることは分かっていたので、grep。RTOについてはたtcp_input.cが一番多く出てきた。見てみると、ACK受信時の処理やRTT、RTOの計算などTCPの入力系が書かれる。

中でも気になったのはTCP_RTO_MINで、includeのnet/tcp.cの中で、

#define TCP_RTO_MAX ((unsigned)(120*HZ))
#define TCP_RTO_MIN ((unsigned)(HZ/5))
#define TCP_TIMEOUT_INIT ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value */

と定義されている。TCP_RTO_MINがHZ/5ということはすなわち、1s / 5 = 200ms。Omicron TCP/RTOにて

Linux の tcp_set_rto を見る限り,”RTO = SRTT + 4 * RTTVAR” になっている気がするけど.最小値(TCP_RTO_MIN)は 200ms,最大値(TCP_RTO_MAX)は 120s.

と書かれているので、ほぼ間違いないだろう。さらに

最小が 200ms なのは,TCP/遅延ACKタイマが 200ms だから,これ以上小さくすると不必要な再送が増えるため.で,遅延 ACK はなぜ 200ms なのかというと…

とも言及している。確かに遅延ACKが200msだと遅延ACKが入る前にタイムアウト再送してしまう…。遅延ACKについて調べてみると、

#define TCP_DELACK_MAX ((unsigned)(HZ/5)) /* maximal time to delay before sending an ACK */
#if HZ >= 100
#define TCP_DELACK_MIN ((unsigned)(HZ/25)) /* minimal time to delay before sending an ACK */
#define TCP_ATO_MIN ((unsigned)(HZ/25))
#else
#define TCP_DELACK_MIN 4U
#define TCP_ATO_MIN 4U
#endif

TCP_DELACK_MAXはHZ/5でTCP_RTO_MINと同じ。ほうほう。

ちなみにOmicronさんのTCP/RTOページにはLinux kernelのpatchが置いてあって、ページ内でそのできることに言及はしていないが、実はsysctlで動的にTCP_RTO_MAXとTCP_RTO_MINを変更できるコードが書いてある。素晴らしい…

もし遅延ACKが問題になるようであれば、TCP_DELACK_MIN / MAXともに変更できるようにpatchを変更しよう。そこまでやれば後は現在のTCP_RTO_MINである200msより下限なRTOがRTTによって適切に決められることだろう。

TCP における確認応答と再送制御 – The all-round Dictionary of Network Terms技術フェチ日誌(2006-11-02)が参考になるかもしれない。もし、RTOが上限と下限を決めても上手く動作しない場合は、RTOのインスタンス値であるtp->mdevの計算ロジックを変更する必要がありそうだ。

後、調べておくべきことはタイマの粒度だが、タイマの粒度を調べるには、”いつRTO(tp->mdev)が待ち時間と「比較」されて再送ロジックに入っているのか”を調べればいいだろうと思っている。しかし、再送ロジックに入るところがまだ探せて確定できてない。もしタイマの粒度が最低200msだったら嫌だなと思っているが、遅延ACKの最低値がHZ/25(40ms)なので、そこまでなら大丈夫な気がしている。

ここまで調べておけば何とかなるか。

noch について

無線LANをこよなく愛する虚言者。
カテゴリー: TCP, プログラミング, 未分類 パーマリンク

コメントを残す

メールアドレスが公開されることはありません。