diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 051f0f815f17..6b669898b197 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1265,20 +1265,15 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
1265 | return flag; | 1265 | return flag; |
1266 | } | 1266 | } |
1267 | 1267 | ||
1268 | /* F-RTO can only be used if these conditions are satisfied: | 1268 | /* F-RTO can only be used if TCP has never retransmitted anything other than |
1269 | * - there must be some unsent new data | 1269 | * head (SACK enhanced variant from Appendix B of RFC4138 is more robust here) |
1270 | * - the advertised window should allow sending it | ||
1271 | * - TCP has never retransmitted anything other than head (SACK enhanced | ||
1272 | * variant from Appendix B of RFC4138 is more robust here) | ||
1273 | */ | 1270 | */ |
1274 | int tcp_use_frto(struct sock *sk) | 1271 | int tcp_use_frto(struct sock *sk) |
1275 | { | 1272 | { |
1276 | const struct tcp_sock *tp = tcp_sk(sk); | 1273 | const struct tcp_sock *tp = tcp_sk(sk); |
1277 | struct sk_buff *skb; | 1274 | struct sk_buff *skb; |
1278 | 1275 | ||
1279 | if (!sysctl_tcp_frto || !tcp_send_head(sk) || | 1276 | if (!sysctl_tcp_frto) |
1280 | after(TCP_SKB_CB(tcp_send_head(sk))->end_seq, | ||
1281 | tp->snd_una + tp->snd_wnd)) | ||
1282 | return 0; | 1277 | return 0; |
1283 | 1278 | ||
1284 | if (IsSackFrto()) | 1279 | if (IsSackFrto()) |
@@ -2710,6 +2705,14 @@ static int tcp_process_frto(struct sock *sk, u32 prior_snd_una, int flag) | |||
2710 | } | 2705 | } |
2711 | 2706 | ||
2712 | if (tp->frto_counter == 1) { | 2707 | if (tp->frto_counter == 1) { |
2708 | /* Sending of the next skb must be allowed or no FRTO */ | ||
2709 | if (!tcp_send_head(sk) || | ||
2710 | after(TCP_SKB_CB(tcp_send_head(sk))->end_seq, | ||
2711 | tp->snd_una + tp->snd_wnd)) { | ||
2712 | tcp_enter_frto_loss(sk, tp->frto_counter + 1, flag); | ||
2713 | return 1; | ||
2714 | } | ||
2715 | |||
2713 | tp->snd_cwnd = tcp_packets_in_flight(tp) + 2; | 2716 | tp->snd_cwnd = tcp_packets_in_flight(tp) + 2; |
2714 | tp->frto_counter = 2; | 2717 | tp->frto_counter = 2; |
2715 | return 1; | 2718 | return 1; |