netlink: fix for too early rmmod
[safe/jmp/linux-2.6] / net / ipv4 / tcp_highspeed.c
index 36c51f8..8b6caaf 100644 (file)
@@ -6,7 +6,6 @@
  * John Heffner <jheffner@psc.edu>
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <net/tcp.h>
 
@@ -15,8 +14,8 @@
  * with fixed-point MD scaled <<8.
  */
 static const struct hstcp_aimd_val {
-        unsigned int cwnd;
-        unsigned int md;
+       unsigned int cwnd;
+       unsigned int md;
 } hstcp_aimd_vals[] = {
  {     38,  128, /*  0.50 */ },
  {    118,  112, /*  0.44 */ },
@@ -98,9 +97,10 @@ struct hstcp {
        u32     ai;
 };
 
-static void hstcp_init(struct tcp_sock *tp)
+static void hstcp_init(struct sock *sk)
 {
-       struct hstcp *ca = tcp_ca(tp);
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct hstcp *ca = inet_csk_ca(sk);
 
        ca->ai = 0;
 
@@ -109,43 +109,49 @@ static void hstcp_init(struct tcp_sock *tp)
        tp->snd_cwnd_clamp = min_t(u32, tp->snd_cwnd_clamp, 0xffffffff/128);
 }
 
-static void hstcp_cong_avoid(struct tcp_sock *tp, u32 adk, u32 rtt,
-                            u32 in_flight, int good)
+static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 in_flight)
 {
-       struct hstcp *ca = tcp_ca(tp);
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct hstcp *ca = inet_csk_ca(sk);
 
-       if (in_flight < tp->snd_cwnd)
+       if (!tcp_is_cwnd_limited(sk, in_flight))
                return;
 
-       if (tp->snd_cwnd <= tp->snd_ssthresh) {
-               if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-                       tp->snd_cwnd++;
-       } else {
-               /* Update AIMD parameters */
+       if (tp->snd_cwnd <= tp->snd_ssthresh)
+               tcp_slow_start(tp);
+       else {
+               /* Update AIMD parameters.
+                *
+                * We want to guarantee that:
+                *     hstcp_aimd_vals[ca->ai-1].cwnd <
+                *     snd_cwnd <=
+                *     hstcp_aimd_vals[ca->ai].cwnd
+                */
                if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
                        while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
-                              ca->ai < HSTCP_AIMD_MAX)
+                              ca->ai < HSTCP_AIMD_MAX - 1)
                                ca->ai++;
-               } else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) {
-                       while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
-                              ca->ai > 0)
+               } else if (ca->ai && tp->snd_cwnd <= hstcp_aimd_vals[ca->ai-1].cwnd) {
+                       while (ca->ai && tp->snd_cwnd <= hstcp_aimd_vals[ca->ai-1].cwnd)
                                ca->ai--;
                }
 
                /* 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++;
                                tp->snd_cwnd_cnt -= tp->snd_cwnd;
+                               tp->snd_cwnd++;
                        }
                }
        }
 }
 
-static u32 hstcp_ssthresh(struct tcp_sock *tp)
+static u32 hstcp_ssthresh(struct sock *sk)
 {
-       struct hstcp *ca = tcp_ca(tp);
+       const struct tcp_sock *tp = tcp_sk(sk);
+       const struct hstcp *ca = inet_csk_ca(sk);
 
        /* Do multiplicative decrease */
        return max(tp->snd_cwnd - ((tp->snd_cwnd * hstcp_aimd_vals[ca->ai].md) >> 8), 2U);
@@ -164,7 +170,7 @@ static struct tcp_congestion_ops tcp_highspeed = {
 
 static int __init hstcp_register(void)
 {
-       BUG_ON(sizeof(struct hstcp) > TCP_CA_PRIV_SIZE);
+       BUILD_BUG_ON(sizeof(struct hstcp) > ICSK_CA_PRIV_SIZE);
        return tcp_register_congestion_control(&tcp_highspeed);
 }