Merge tag 'v3.10.76' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / ipv4 / tcp_input.c
index a8be45e4d34fcb0b4e577dd59a58f6269961752c..ab151653c0502a8d20fb071b7028095d88d5717b 100644 (file)
@@ -68,6 +68,7 @@
 #include <linux/module.h>
 #include <linux/sysctl.h>
 #include <linux/kernel.h>
+#include <linux/reciprocal_div.h>
 #include <net/dst.h>
 #include <net/tcp.h>
 #include <net/inet_common.h>
@@ -87,7 +88,7 @@ int sysctl_tcp_adv_win_scale __read_mostly = 1;
 EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
 
 /* rfc5961 challenge ack rate limiting */
-int sysctl_tcp_challenge_ack_limit = 100;
+int sysctl_tcp_challenge_ack_limit = 1000;
 
 int sysctl_tcp_stdurg __read_mostly;
 int sysctl_tcp_rfc1337 __read_mostly;
@@ -98,6 +99,7 @@ int sysctl_tcp_thin_dupack __read_mostly;
 
 int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
 int sysctl_tcp_early_retrans __read_mostly = 3;
+int sysctl_tcp_default_init_rwnd __read_mostly = TCP_DEFAULT_INIT_RCVWND;
 
 #define FLAG_DATA              0x01 /* Incoming frame contained data.          */
 #define FLAG_WIN_UPDATE                0x02 /* Incoming ACK was a window update.       */
@@ -351,14 +353,14 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb)
 static void tcp_fixup_rcvbuf(struct sock *sk)
 {
        u32 mss = tcp_sk(sk)->advmss;
-       u32 icwnd = TCP_DEFAULT_INIT_RCVWND;
+       u32 icwnd = sysctl_tcp_default_init_rwnd;
        int rcvmem;
 
        /* Limit to 10 segments if mss <= 1460,
         * or 14600/mss segments, with a minimum of two segments.
         */
        if (mss > 1460)
-               icwnd = max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2);
+               icwnd = max_t(u32, (1460 * icwnd) / mss, 2);
 
        rcvmem = SKB_TRUESIZE(mss + MAX_TCP_HEADER);
        while (tcp_win_from_space(rcvmem) < mss)
@@ -1868,6 +1870,7 @@ void tcp_clear_retrans(struct tcp_sock *tp)
 void tcp_enter_loss(struct sock *sk, int how)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
+       struct inet_connection_sock *icsk1 = inet_csk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *skb;
        bool new_recovery = false;
@@ -1881,7 +1884,40 @@ void tcp_enter_loss(struct sock *sk, int how)
                tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk);
                tcp_ca_event(sk, CA_EVENT_LOSS);
        }
+       if (icsk->icsk_MMSRB == 1)
+       {
+               #ifdef CONFIG_MTK_NET_LOGGING 
+           printk("[mtk_net][mmspb] tcp_enter_loss snd_cwnd=%u, snd_cwnd_cnt=%u\n", tp->snd_cwnd, tp->snd_cwnd_cnt);
+        #endif
+            if (tp->mss_cache != 0)
+                tp->snd_cwnd = (tp->rcv_wnd / tp->mss_cache);
+            else
+            {
+                tp->snd_cwnd = (tp->rcv_wnd / tp->advmss);
+            }
+               
+            if (tp->snd_ssthresh > 16)
+            {
+                tp->snd_cwnd = tp->snd_ssthresh / 2;//set snd_cwnd is half of default snd_ssthresh
+            }
+            else
+            {
+                tp->snd_cwnd = tp->snd_ssthresh / 2 + 4;
+            }
+            #ifdef CONFIG_MTK_NET_LOGGING 
+            printk("[mtk_net][mmspb] tcp_enter_loss update snd_cwnd=%u\n", tp->snd_cwnd);
+            #endif
+            icsk1->icsk_MMSRB = 0;
+            #ifdef CONFIG_MTK_NET_LOGGING 
+            printk("[mtk_net][mmspb] tcp_enter_loss set icsk_MMSRB=0\n");
+            #endif
+       }
+        else
+        {
        tp->snd_cwnd       = 1;
+        }      
+  
+       //tp->snd_cwnd     = 1;
        tp->snd_cwnd_cnt   = 0;
        tp->snd_cwnd_stamp = tcp_time_stamp;
 
@@ -1944,7 +1980,7 @@ static bool tcp_check_sack_reneging(struct sock *sk, int flag)
                icsk->icsk_retransmits++;
                tcp_retransmit_skb(sk, tcp_write_queue_head(sk));
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
-                                         icsk->icsk_rto, TCP_RTO_MAX);
+                                         icsk->icsk_rto, sysctl_tcp_rto_max);
                return true;
        }
        return false;
@@ -1993,7 +2029,7 @@ static bool tcp_pause_early_retransmit(struct sock *sk, int flag)
                return false;
 
        inet_csk_reset_xmit_timer(sk, ICSK_TIME_EARLY_RETRANS, delay,
-                                 TCP_RTO_MAX);
+                                 sysctl_tcp_rto_max);
        return true;
 }
 
@@ -2981,7 +3017,7 @@ void tcp_rearm_rto(struct sock *sk)
                                rto = delta;
                }
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, rto,
-                                         TCP_RTO_MAX);
+                                         sysctl_tcp_rto_max);
        }
 }
 
@@ -3211,8 +3247,8 @@ static void tcp_ack_probe(struct sock *sk)
                 */
        } else {
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_PROBE0,
-                                         min(icsk->icsk_rto << icsk->icsk_backoff, TCP_RTO_MAX),
-                                         TCP_RTO_MAX);
+                                         min_t(unsigned int, icsk->icsk_rto << icsk->icsk_backoff, sysctl_tcp_rto_max),
+                                         sysctl_tcp_rto_max);
        }
 }
 
@@ -3288,12 +3324,19 @@ static void tcp_send_challenge_ack(struct sock *sk)
        static u32 challenge_timestamp;
        static unsigned int challenge_count;
        u32 now = jiffies / HZ;
+       u32 count;
 
        if (now != challenge_timestamp) {
+               u32 half = (sysctl_tcp_challenge_ack_limit + 1) >> 1;
+
                challenge_timestamp = now;
-               challenge_count = 0;
+               ACCESS_ONCE(challenge_count) = half +
+                                       reciprocal_divide(prandom_u32(),
+                                                       sysctl_tcp_challenge_ack_limit);
        }
-       if (++challenge_count <= sysctl_tcp_challenge_ack_limit) {
+       count = ACCESS_ONCE(challenge_count);
+       if (count > 0) {
+               ACCESS_ONCE(challenge_count) = count - 1;
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK);
                tcp_send_ack(sk);
        }
@@ -5530,7 +5573,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
                        icsk->icsk_ack.lrcvtime = tcp_time_stamp;
                        tcp_enter_quickack_mode(sk);
                        inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
-                                                 TCP_DELACK_MAX, TCP_RTO_MAX);
+                                                 TCP_DELACK_MAX, sysctl_tcp_rto_max);
 
 discard:
                        __kfree_skb(skb);