Merge branch 'srp' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
[powerpc.git] / net / ipv4 / tcp_input.c
index 1afb080..3e98b57 100644 (file)
@@ -355,8 +355,6 @@ static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp)
                        app_win -= icsk->icsk_ack.rcv_mss;
                app_win = max(app_win, 2U*tp->advmss);
 
-               if (!ofo_win)
-                       tp->window_clamp = min(tp->window_clamp, app_win);
                tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss);
        }
 }
@@ -923,14 +921,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
        int flag = 0;
        int i;
 
-       /* So, SACKs for already sent large segments will be lost.
-        * Not good, but alternative is to resegment the queue. */
-       if (sk->sk_route_caps & NETIF_F_TSO) {
-               sk->sk_route_caps &= ~NETIF_F_TSO;
-               sock_set_flag(sk, SOCK_NO_LARGESEND);
-               tp->mss_cache = tp->mss_cache;
-       }
-
        if (!tp->sacked_out)
                tp->fackets_out = 0;
        prior_fackets = tp->fackets_out;
@@ -978,20 +968,42 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
                        flag |= FLAG_DATA_LOST;
 
                sk_stream_for_retrans_queue(skb, sk) {
-                       u8 sacked = TCP_SKB_CB(skb)->sacked;
-                       int in_sack;
+                       int in_sack, pcount;
+                       u8 sacked;
 
                        /* The retransmission queue is always in order, so
                         * we can short-circuit the walk early.
                         */
-                       if(!before(TCP_SKB_CB(skb)->seq, end_seq))
+                       if (!before(TCP_SKB_CB(skb)->seq, end_seq))
                                break;
 
-                       fack_count += tcp_skb_pcount(skb);
-
                        in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) &&
                                !before(end_seq, TCP_SKB_CB(skb)->end_seq);
 
+                       pcount = tcp_skb_pcount(skb);
+
+                       if (pcount > 1 && !in_sack &&
+                           after(TCP_SKB_CB(skb)->end_seq, start_seq)) {
+                               unsigned int pkt_len;
+
+                               in_sack = !after(start_seq,
+                                                TCP_SKB_CB(skb)->seq);
+
+                               if (!in_sack)
+                                       pkt_len = (start_seq -
+                                                  TCP_SKB_CB(skb)->seq);
+                               else
+                                       pkt_len = (end_seq -
+                                                  TCP_SKB_CB(skb)->seq);
+                               if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->tso_size))
+                                       break;
+                               pcount = tcp_skb_pcount(skb);
+                       }
+
+                       fack_count += pcount;
+
+                       sacked = TCP_SKB_CB(skb)->sacked;
+
                        /* Account D-SACK for retransmitted packet. */
                        if ((dup_sack && in_sack) &&
                            (sacked & TCPCB_RETRANS) &&
@@ -2227,6 +2239,7 @@ static int tcp_ack_update_window(struct sock *sk, struct tcp_sock *tp,
                        /* Note, it is the only place, where
                         * fast path is recovered for sending TCP.
                         */
+                       tp->pred_flags = 0;
                        tcp_fast_path_check(sk, tp);
 
                        if (nwin > tp->max_window) {