tcp: add tcp_min_snd_mss sysctl
[pandora-kernel.git] / net / ipv4 / tcp_cubic.c
index 34340c9..ed3d6d4 100644 (file)
@@ -93,6 +93,7 @@ struct bictcp {
        u32     ack_cnt;        /* number of acks */
        u32     tcp_cwnd;       /* estimated tcp cwnd */
 #define ACK_RATIO_SHIFT        4
+#define ACK_RATIO_LIMIT (32u << ACK_RATIO_SHIFT)
        u16     delayed_ack;    /* estimate the ratio of Packets/ACKs << 4 */
        u8      sample_cnt;     /* number of samples to decide curr_rtt */
        u8      found;          /* the exit point is found? */
@@ -203,8 +204,8 @@ static u32 cubic_root(u64 a)
  */
 static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
 {
-       u64 offs;
-       u32 delta, t, bic_target, max_cnt;
+       u32 delta, bic_target, max_cnt;
+       u64 offs, t;
 
        ca->ack_cnt++;  /* count the number of ACKs */
 
@@ -247,9 +248,11 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
         * if the cwnd < 1 million packets !!!
         */
 
+       t = (s32)(tcp_time_stamp - ca->epoch_start);
+       t += msecs_to_jiffies(ca->delay_min >> 3);
        /* change the unit from HZ to bictcp_HZ */
-       t = ((tcp_time_stamp + msecs_to_jiffies(ca->delay_min>>3)
-             - ca->epoch_start) << BICTCP_HZ) / HZ;
+       t <<= BICTCP_HZ;
+       do_div(t, HZ);
 
        if (t < ca->bic_K)              /* t - K */
                offs = ca->bic_K - t;
@@ -398,8 +401,12 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
        u32 delay;
 
        if (icsk->icsk_ca_state == TCP_CA_Open) {
-               cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
-               ca->delayed_ack += cnt;
+               u32 ratio = ca->delayed_ack;
+
+               ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT;
+               ratio += cnt;
+
+               ca->delayed_ack = clamp(ratio, 1U, ACK_RATIO_LIMIT);
        }
 
        /* Some calls are for duplicates without timetamps */
@@ -407,7 +414,7 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
                return;
 
        /* Discard delay samples right after fast recovery */
-       if ((s32)(tcp_time_stamp - ca->epoch_start) < HZ)
+       if (ca->epoch_start && (s32)(tcp_time_stamp - ca->epoch_start) < HZ)
                return;
 
        delay = (rtt_us << 3) / USEC_PER_MSEC;