]
トップ «前の日記(2009-04-15) 最新 次の日記(2009-04-23)» 編集

Yukiharu YABUKI の tDiary



このtDiaryを検索します。

2009-04-17 [長年日記]

_ tcp_cong.c

TCPの輻輳制御を、入れ替え可能にするモジュールについて扱う。Debian GNU/Linux Etch にある、kernel 2.6.18 を参照しつつ記録したが、自分のために書いているので、利用するときにはソースコードをみてチェックしてその通りか確認した方がよい。。

static struct tcp_congestion_ops *tcp_ca_find(const char *name)
リニアサーチで、"hybla","bic"などの輻輳回避のアルゴリズム(Congestion AvoidanceなのでCAかと)を選択する。
static tcp_register_congestion_control(struct tcp_congestion_ops *ca)
輻輳制御の関数というかモジュールをリストへ登録する。この関数で、輻輳回避のモジュール内に、スロースタートの閾値を決定する関数および輻輳回避の処理を行う関数がない場合はエラーとしている。スピンロックでかけて list_add_rcu を呼び出して、処理リストに繋いでる。
なおこの関数は、EXPORT_SYMBOL_GPLでシンボルを公開している。
tcp_unregister_congestion_control(struct tcp_congestion_ops *ca)
輻輳制御の関数というかモジュールをリストから削除する。スピンロックをかけてリストから処理を削除している。この関数も EXPORT_SYMBOL_GPL でシンボルを公開している。
void tcp_init_congestion_control(struct sock *sk)
tcp_congestion_ops構造体の定義にもあるように、
        /* initialize private data (optional) */
        void (*init)(struct sock *sk);
 
で登録された関数を実行する部分。関数の1行コメントには、Assign choice of congestion control.とある。if (try_module_get(ca->owner))){の部分に関しては、あとでチェック
void tcp_cleanup_congestion_control (struct sock *sk)
tcp_congestion_ops構造体の定義にもあるように、
        /* cleanup private data  (optional) */
        void (*release)(struct sock *sk);
で登録された関数を実行する部分。module_put(icsk->icsk_caops->owner);についてはあとでチェック。関数の一行コメントには、Manage refcounts on socket close. とある。
int tcp_set_default_congestion_control(const char *name)
関数の一行コメントには、Used by sysctl to change default congestion controlとある。CONFIG_KMODで条件コンパイルされている部分があるが、その場合、スピンロックを外して request_moduleを発行する。tcp_%sって表記しているので、モジュール名はtcp_をつけるのは必須だ。
void tcp_get_default_congestion_ops(char *name)
BUG_ONっていう関数か、マクロかは後で調べる。TCP_BICがある場合にはTCP_BICがデフォルトになるが、最悪はTCP_RENOがあるので、値がないという事態は発生しない。
void tcp_set_congestion_control(struct sock *sk, cont char *name)
関数の一行コメントには、Change congestion control for socket とある。見た感じでは、リストの中から指定の輻輳制御を見つけて、組み込みの分か、モジュールになっている分をとりだします。モジュールを呼び出すときには、付け替える前にtcp_cleanup_congestion_control(sk)を呼んでから、tcp輻輳制御の初期化処理を呼び出す。
void tcp_slow_start(struct tcp_sock *tp)
スロースタートの部分、sysctl_tcp_abc man 7 tcpのtcp_abc (Integer; default: 0; Linux 2.6.15 以降) に関係する。RFC3465 - TCP Congestion Control with Appropriate Byte Counting (ABC)に関係する。この関数は、EXPORT_SYMBOL_GPLである。
void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 rtt, u32 in_flight, int flag)
TCP Renoの輻輳回避/輻輳制御 SIGCOMM '88のp328を参照。ここでもsysctl_tcp_abcの影響あり。安全なエリアから危険なエリアへ、線形上(リニア)に送信輻輳ウィンドウを広げる。この関数もEXPORT_SYMBOL_GPLである。
u32 tcp_reno_sshresh(struct sock *sk)
max(tp->snd_cwnd >> 1U, 2U); となっている。送信輻輳ウィンドウが半分の値または、2の大きい方だから最小値が2だ。この関数もEXPORT_SYMBOL_GPLである。
u32 tcp_reno_min_cwnd(const struct sock *sk)
送信用スロースタートの閾値を半分にする。関数の一行コメントは、Lower bound on congestion window with halvingである。この関数もEXPORT_SYMBOL_GPLである。
構造体 tcp_congestion_ops の tcp_reno
ここで、TCPのオリジナルである tcp_reno について定義している。
構造体 tcp_congestion_ops の tcp_init_congestion_ops
この部分は、コメントによるとSYNパケットを受け取るまでの初期状態の輻輳制御なんだけど、要確認。