|
@@ -2514,7 +2514,7 @@ void tcp_skb_collapse_tstamp(struct sk_buff *skb,
|
|
}
|
|
}
|
|
|
|
|
|
/* Collapses two adjacent SKB's during retransmission. */
|
|
/* Collapses two adjacent SKB's during retransmission. */
|
|
-static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)
|
|
|
|
|
|
+static bool tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)
|
|
{
|
|
{
|
|
struct tcp_sock *tp = tcp_sk(sk);
|
|
struct tcp_sock *tp = tcp_sk(sk);
|
|
struct sk_buff *next_skb = tcp_write_queue_next(sk, skb);
|
|
struct sk_buff *next_skb = tcp_write_queue_next(sk, skb);
|
|
@@ -2525,14 +2525,17 @@ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)
|
|
|
|
|
|
BUG_ON(tcp_skb_pcount(skb) != 1 || tcp_skb_pcount(next_skb) != 1);
|
|
BUG_ON(tcp_skb_pcount(skb) != 1 || tcp_skb_pcount(next_skb) != 1);
|
|
|
|
|
|
|
|
+ if (next_skb_size) {
|
|
|
|
+ if (next_skb_size <= skb_availroom(skb))
|
|
|
|
+ skb_copy_bits(next_skb, 0, skb_put(skb, next_skb_size),
|
|
|
|
+ next_skb_size);
|
|
|
|
+ else if (!skb_shift(skb, next_skb, next_skb_size))
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
tcp_highest_sack_combine(sk, next_skb, skb);
|
|
tcp_highest_sack_combine(sk, next_skb, skb);
|
|
|
|
|
|
tcp_unlink_write_queue(next_skb, sk);
|
|
tcp_unlink_write_queue(next_skb, sk);
|
|
|
|
|
|
- if (next_skb_size)
|
|
|
|
- skb_copy_bits(next_skb, 0, skb_put(skb, next_skb_size),
|
|
|
|
- next_skb_size);
|
|
|
|
-
|
|
|
|
if (next_skb->ip_summed == CHECKSUM_PARTIAL)
|
|
if (next_skb->ip_summed == CHECKSUM_PARTIAL)
|
|
skb->ip_summed = CHECKSUM_PARTIAL;
|
|
skb->ip_summed = CHECKSUM_PARTIAL;
|
|
|
|
|
|
@@ -2561,6 +2564,7 @@ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)
|
|
tcp_skb_collapse_tstamp(skb, next_skb);
|
|
tcp_skb_collapse_tstamp(skb, next_skb);
|
|
|
|
|
|
sk_wmem_free_skb(sk, next_skb);
|
|
sk_wmem_free_skb(sk, next_skb);
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
/* Check if coalescing SKBs is legal. */
|
|
/* Check if coalescing SKBs is legal. */
|
|
@@ -2610,16 +2614,12 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,
|
|
|
|
|
|
if (space < 0)
|
|
if (space < 0)
|
|
break;
|
|
break;
|
|
- /* Punt if not enough space exists in the first SKB for
|
|
|
|
- * the data in the second
|
|
|
|
- */
|
|
|
|
- if (skb->len > skb_availroom(to))
|
|
|
|
- break;
|
|
|
|
|
|
|
|
if (after(TCP_SKB_CB(skb)->end_seq, tcp_wnd_end(tp)))
|
|
if (after(TCP_SKB_CB(skb)->end_seq, tcp_wnd_end(tp)))
|
|
break;
|
|
break;
|
|
|
|
|
|
- tcp_collapse_retrans(sk, to);
|
|
|
|
|
|
+ if (!tcp_collapse_retrans(sk, to))
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|