]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/tcp_highspeed.c
Merge branch '83xx' into for_paulus
[linux-2.6-omap-h63xx.git] / net / ipv4 / tcp_highspeed.c
index b72fa55dfb84d114484bf6f7d1b4751449d9c4e3..aaa1538c0692c2d842b244106e1f859817f28177 100644 (file)
@@ -6,7 +6,6 @@
  * John Heffner <jheffner@psc.edu>
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <net/tcp.h>
 
@@ -98,6 +97,10 @@ struct hstcp {
        u32     ai;
 };
 
+static int max_ssthresh = 100;
+module_param(max_ssthresh, int, 0644);
+MODULE_PARM_DESC(max_ssthresh, "limited slow start threshold (RFC3742)");
+
 static void hstcp_init(struct sock *sk)
 {
        struct tcp_sock *tp = tcp_sk(sk);
@@ -119,9 +122,23 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt,
        if (!tcp_is_cwnd_limited(sk, in_flight))
                return;
 
-       if (tp->snd_cwnd <= tp->snd_ssthresh)
-               tcp_slow_start(tp);
-       else {
+       if (tp->snd_cwnd <= tp->snd_ssthresh) {
+               /* RFC3742: limited slow start
+                * the window is increased by 1/K MSS for each arriving ACK,
+                * for K = int(cwnd/(0.5 max_ssthresh))
+                */
+               if (max_ssthresh > 0 && tp->snd_cwnd > max_ssthresh) {
+                       u32 k = max(tp->snd_cwnd / (max_ssthresh >> 1), 1U);
+                       if (++tp->snd_cwnd_cnt >= k) {
+                               if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+                                       tp->snd_cwnd++;
+                               tp->snd_cwnd_cnt = 0;
+                       }
+               } else {
+                       if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+                               tp->snd_cwnd++;
+               }
+       } else {
                /* Update AIMD parameters */
                if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
                        while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
@@ -135,7 +152,8 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt,
 
                /* Do additive increase */
                if (tp->snd_cwnd < tp->snd_cwnd_clamp) {
-                       tp->snd_cwnd_cnt += ca->ai;
+                       /* cwnd = cwnd + a(w) / cwnd */
+                       tp->snd_cwnd_cnt += ca->ai + 1;
                        if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
                                tp->snd_cwnd_cnt -= tp->snd_cwnd;
                                tp->snd_cwnd++;