OSDN Git Service

Merge 4.4.146 into android-4.4-p
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / net / ipv4 / tcp_input.c
index 51e8f1c..cbfc858 100644 (file)
@@ -177,21 +177,23 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)
        }
 }
 
-static void tcp_incr_quickack(struct sock *sk)
+static void tcp_incr_quickack(struct sock *sk, unsigned int max_quickacks)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        unsigned int quickacks = tcp_sk(sk)->rcv_wnd / (2 * icsk->icsk_ack.rcv_mss);
 
        if (quickacks == 0)
                quickacks = 2;
+       quickacks = min(quickacks, max_quickacks);
        if (quickacks > icsk->icsk_ack.quick)
-               icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
+               icsk->icsk_ack.quick = quickacks;
 }
 
-void tcp_enter_quickack_mode(struct sock *sk)
+void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
-       tcp_incr_quickack(sk);
+
+       tcp_incr_quickack(sk, max_quickacks);
        icsk->icsk_ack.pingpong = 0;
        icsk->icsk_ack.ato = TCP_ATO_MIN;
 }
@@ -227,8 +229,10 @@ static void tcp_ecn_withdraw_cwr(struct tcp_sock *tp)
        tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
 }
 
-static void __tcp_ecn_check_ce(struct tcp_sock *tp, const struct sk_buff *skb)
+static void __tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb)
 {
+       struct tcp_sock *tp = tcp_sk(sk);
+
        switch (TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK) {
        case INET_ECN_NOT_ECT:
                /* Funny extension: if ECT is not set on a segment,
@@ -236,31 +240,31 @@ static void __tcp_ecn_check_ce(struct tcp_sock *tp, const struct sk_buff *skb)
                 * it is probably a retransmit.
                 */
                if (tp->ecn_flags & TCP_ECN_SEEN)
-                       tcp_enter_quickack_mode((struct sock *)tp);
+                       tcp_enter_quickack_mode(sk, 2);
                break;
        case INET_ECN_CE:
-               if (tcp_ca_needs_ecn((struct sock *)tp))
-                       tcp_ca_event((struct sock *)tp, CA_EVENT_ECN_IS_CE);
+               if (tcp_ca_needs_ecn(sk))
+                       tcp_ca_event(sk, CA_EVENT_ECN_IS_CE);
 
                if (!(tp->ecn_flags & TCP_ECN_DEMAND_CWR)) {
                        /* Better not delay acks, sender can have a very low cwnd */
-                       tcp_enter_quickack_mode((struct sock *)tp);
+                       tcp_enter_quickack_mode(sk, 2);
                        tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
                }
                tp->ecn_flags |= TCP_ECN_SEEN;
                break;
        default:
-               if (tcp_ca_needs_ecn((struct sock *)tp))
-                       tcp_ca_event((struct sock *)tp, CA_EVENT_ECN_NO_CE);
+               if (tcp_ca_needs_ecn(sk))
+                       tcp_ca_event(sk, CA_EVENT_ECN_NO_CE);
                tp->ecn_flags |= TCP_ECN_SEEN;
                break;
        }
 }
 
-static void tcp_ecn_check_ce(struct tcp_sock *tp, const struct sk_buff *skb)
+static void tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb)
 {
-       if (tp->ecn_flags & TCP_ECN_OK)
-               __tcp_ecn_check_ce(tp, skb);
+       if (tcp_sk(sk)->ecn_flags & TCP_ECN_OK)
+               __tcp_ecn_check_ce(sk, skb);
 }
 
 static void tcp_ecn_rcv_synack(struct tcp_sock *tp, const struct tcphdr *th)
@@ -652,7 +656,7 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb)
                /* The _first_ data packet received, initialize
                 * delayed ACK engine.
                 */
-               tcp_incr_quickack(sk);
+               tcp_incr_quickack(sk, TCP_MAX_QUICKACKS);
                icsk->icsk_ack.ato = TCP_ATO_MIN;
        } else {
                int m = now - icsk->icsk_ack.lrcvtime;
@@ -668,13 +672,13 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb)
                        /* Too long gap. Apparently sender failed to
                         * restart window, so that we send ACKs quickly.
                         */
-                       tcp_incr_quickack(sk);
+                       tcp_incr_quickack(sk, TCP_MAX_QUICKACKS);
                        sk_mem_reclaim(sk);
                }
        }
        icsk->icsk_ack.lrcvtime = now;
 
-       tcp_ecn_check_ce(tp, skb);
+       tcp_ecn_check_ce(sk, skb);
 
        if (skb->len >= 128)
                tcp_grow_window(sk, skb);
@@ -4137,7 +4141,7 @@ static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb)
        if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq &&
            before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOST);
-               tcp_enter_quickack_mode(sk);
+               tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS);
 
                if (tcp_is_sack(tp) && sysctl_tcp_dsack) {
                        u32 end_seq = TCP_SKB_CB(skb)->end_seq;
@@ -4365,7 +4369,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
        struct sk_buff *skb1;
        u32 seq, end_seq;
 
-       tcp_ecn_check_ce(tp, skb);
+       tcp_ecn_check_ce(sk, skb);
 
        if (unlikely(tcp_try_rmem_schedule(sk, skb, skb->truesize))) {
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFODROP);
@@ -4639,7 +4643,7 @@ queue_and_out:
                tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
 
 out_of_window:
-               tcp_enter_quickack_mode(sk);
+               tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS);
                inet_csk_schedule_ack(sk);
 drop:
                __kfree_skb(skb);
@@ -4650,8 +4654,6 @@ drop:
        if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt + tcp_receive_window(tp)))
                goto out_of_window;
 
-       tcp_enter_quickack_mode(sk);
-
        if (before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
                /* Partial packet, seq < rcv_next < end_seq */
                SOCK_DEBUG(sk, "partial packet: rcv_next %X seq %X - %X\n",
@@ -5677,7 +5679,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
                         * to stand against the temptation 8)     --ANK
                         */
                        inet_csk_schedule_ack(sk);
-                       tcp_enter_quickack_mode(sk);
+                       tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS);
                        inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
                                                  TCP_DELACK_MAX, TCP_RTO_MAX);