diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index cfe6ffe1c177..948ac275b9b5 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -1986,6 +1986,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
1986 | tso_segs = tcp_init_tso_segs(sk, skb, mss_now); | 1986 | tso_segs = tcp_init_tso_segs(sk, skb, mss_now); |
1987 | BUG_ON(!tso_segs); | 1987 | BUG_ON(!tso_segs); |
1988 | 1988 | ||
1989 | if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE) | ||
1990 | goto repair; /* Skip network transmission */ | ||
1991 | |||
1989 | cwnd_quota = tcp_cwnd_test(tp, skb); | 1992 | cwnd_quota = tcp_cwnd_test(tp, skb); |
1990 | if (!cwnd_quota) | 1993 | if (!cwnd_quota) |
1991 | break; | 1994 | break; |
@@ -2026,6 +2029,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
2026 | if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) | 2029 | if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) |
2027 | break; | 2030 | break; |
2028 | 2031 | ||
2032 | repair: | ||
2029 | /* Advance the send_head. This one is sent out. | 2033 | /* Advance the send_head. This one is sent out. |
2030 | * This call will increment packets_out. | 2034 | * This call will increment packets_out. |
2031 | */ | 2035 | */ |
@@ -2305,12 +2309,11 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to, | |||
2305 | * state updates are done by the caller. Returns non-zero if an | 2309 | * state updates are done by the caller. Returns non-zero if an |
2306 | * error occurred which prevented the send. | 2310 | * error occurred which prevented the send. |
2307 | */ | 2311 | */ |
2308 | int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | 2312 | int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) |
2309 | { | 2313 | { |
2310 | struct tcp_sock *tp = tcp_sk(sk); | 2314 | struct tcp_sock *tp = tcp_sk(sk); |
2311 | struct inet_connection_sock *icsk = inet_csk(sk); | 2315 | struct inet_connection_sock *icsk = inet_csk(sk); |
2312 | unsigned int cur_mss; | 2316 | unsigned int cur_mss; |
2313 | int err; | ||
2314 | 2317 | ||
2315 | /* Inconslusive MTU probe */ | 2318 | /* Inconslusive MTU probe */ |
2316 | if (icsk->icsk_mtup.probe_size) { | 2319 | if (icsk->icsk_mtup.probe_size) { |
@@ -2383,11 +2386,17 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2383 | if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { | 2386 | if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { |
2384 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, | 2387 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, |
2385 | GFP_ATOMIC); | 2388 | GFP_ATOMIC); |
2386 | err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : | 2389 | return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : |
2387 | -ENOBUFS; | 2390 | -ENOBUFS; |
2388 | } else { | 2391 | } else { |
2389 | err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); | 2392 | return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); |
2390 | } | 2393 | } |
2394 | } | ||
2395 | |||
2396 | int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | ||
2397 | { | ||
2398 | struct tcp_sock *tp = tcp_sk(sk); | ||
2399 | int err = __tcp_retransmit_skb(sk, skb); | ||
2391 | 2400 | ||
2392 | if (err == 0) { | 2401 | if (err == 0) { |
2393 | /* Update global TCP statistics. */ | 2402 | /* Update global TCP statistics. */ |