diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 24 |
1 files changed, 8 insertions, 16 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 06b9c4765f42..451ef3012636 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1968,11 +1968,6 @@ void tcp_enter_loss(struct sock *sk) | |||
1968 | /* F-RTO RFC5682 sec 3.1 step 1: retransmit SND.UNA if no previous | 1968 | /* F-RTO RFC5682 sec 3.1 step 1: retransmit SND.UNA if no previous |
1969 | * loss recovery is underway except recurring timeout(s) on | 1969 | * loss recovery is underway except recurring timeout(s) on |
1970 | * the same SND.UNA (sec 3.2). Disable F-RTO on path MTU probing | 1970 | * the same SND.UNA (sec 3.2). Disable F-RTO on path MTU probing |
1971 | * | ||
1972 | * In theory F-RTO can be used repeatedly during loss recovery. | ||
1973 | * In practice this interacts badly with broken middle-boxes that | ||
1974 | * falsely raise the receive window, which results in repeated | ||
1975 | * timeouts and stop-and-go behavior. | ||
1976 | */ | 1971 | */ |
1977 | tp->frto = net->ipv4.sysctl_tcp_frto && | 1972 | tp->frto = net->ipv4.sysctl_tcp_frto && |
1978 | (new_recovery || icsk->icsk_retransmits) && | 1973 | (new_recovery || icsk->icsk_retransmits) && |
@@ -2628,18 +2623,14 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack, | |||
2628 | tcp_try_undo_loss(sk, false)) | 2623 | tcp_try_undo_loss(sk, false)) |
2629 | return; | 2624 | return; |
2630 | 2625 | ||
2631 | /* The ACK (s)acks some never-retransmitted data meaning not all | ||
2632 | * the data packets before the timeout were lost. Therefore we | ||
2633 | * undo the congestion window and state. This is essentially | ||
2634 | * the operation in F-RTO (RFC5682 section 3.1 step 3.b). Since | ||
2635 | * a retransmitted skb is permantly marked, we can apply such an | ||
2636 | * operation even if F-RTO was not used. | ||
2637 | */ | ||
2638 | if ((flag & FLAG_ORIG_SACK_ACKED) && | ||
2639 | tcp_try_undo_loss(sk, tp->undo_marker)) | ||
2640 | return; | ||
2641 | |||
2642 | if (tp->frto) { /* F-RTO RFC5682 sec 3.1 (sack enhanced version). */ | 2626 | if (tp->frto) { /* F-RTO RFC5682 sec 3.1 (sack enhanced version). */ |
2627 | /* Step 3.b. A timeout is spurious if not all data are | ||
2628 | * lost, i.e., never-retransmitted data are (s)acked. | ||
2629 | */ | ||
2630 | if ((flag & FLAG_ORIG_SACK_ACKED) && | ||
2631 | tcp_try_undo_loss(sk, true)) | ||
2632 | return; | ||
2633 | |||
2643 | if (after(tp->snd_nxt, tp->high_seq)) { | 2634 | if (after(tp->snd_nxt, tp->high_seq)) { |
2644 | if (flag & FLAG_DATA_SACKED || is_dupack) | 2635 | if (flag & FLAG_DATA_SACKED || is_dupack) |
2645 | tp->frto = 0; /* Step 3.a. loss was real */ | 2636 | tp->frto = 0; /* Step 3.a. loss was real */ |
@@ -3998,6 +3989,7 @@ void tcp_reset(struct sock *sk) | |||
3998 | /* This barrier is coupled with smp_rmb() in tcp_poll() */ | 3989 | /* This barrier is coupled with smp_rmb() in tcp_poll() */ |
3999 | smp_wmb(); | 3990 | smp_wmb(); |
4000 | 3991 | ||
3992 | tcp_write_queue_purge(sk); | ||
4001 | tcp_done(sk); | 3993 | tcp_done(sk); |
4002 | 3994 | ||
4003 | if (!sock_flag(sk, SOCK_DEAD)) | 3995 | if (!sock_flag(sk, SOCK_DEAD)) |