diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index eb7f82ebf4a3..bef9f04c22ba 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -817,7 +817,7 @@ __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) | |||
817 | __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); | 817 | __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); |
818 | 818 | ||
819 | if (!cwnd) | 819 | if (!cwnd) |
820 | cwnd = rfc3390_bytes_to_packets(tp->mss_cache); | 820 | cwnd = TCP_INIT_CWND; |
821 | return min_t(__u32, cwnd, tp->snd_cwnd_clamp); | 821 | return min_t(__u32, cwnd, tp->snd_cwnd_clamp); |
822 | } | 822 | } |
823 | 823 | ||
@@ -1222,7 +1222,7 @@ static int tcp_check_dsack(struct sock *sk, struct sk_buff *ack_skb, | |||
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | /* D-SACK for already forgotten data... Do dumb counting. */ | 1224 | /* D-SACK for already forgotten data... Do dumb counting. */ |
1225 | if (dup_sack && | 1225 | if (dup_sack && tp->undo_marker && tp->undo_retrans && |
1226 | !after(end_seq_0, prior_snd_una) && | 1226 | !after(end_seq_0, prior_snd_una) && |
1227 | after(end_seq_0, tp->undo_marker)) | 1227 | after(end_seq_0, tp->undo_marker)) |
1228 | tp->undo_retrans--; | 1228 | tp->undo_retrans--; |
@@ -1299,7 +1299,8 @@ static u8 tcp_sacktag_one(struct sk_buff *skb, struct sock *sk, | |||
1299 | 1299 | ||
1300 | /* Account D-SACK for retransmitted packet. */ | 1300 | /* Account D-SACK for retransmitted packet. */ |
1301 | if (dup_sack && (sacked & TCPCB_RETRANS)) { | 1301 | if (dup_sack && (sacked & TCPCB_RETRANS)) { |
1302 | if (after(TCP_SKB_CB(skb)->end_seq, tp->undo_marker)) | 1302 | if (tp->undo_marker && tp->undo_retrans && |
1303 | after(TCP_SKB_CB(skb)->end_seq, tp->undo_marker)) | ||
1303 | tp->undo_retrans--; | 1304 | tp->undo_retrans--; |
1304 | if (sacked & TCPCB_SACKED_ACKED) | 1305 | if (sacked & TCPCB_SACKED_ACKED) |
1305 | state->reord = min(fack_count, state->reord); | 1306 | state->reord = min(fack_count, state->reord); |
@@ -2658,7 +2659,7 @@ static void DBGUNDO(struct sock *sk, const char *msg) | |||
2658 | #define DBGUNDO(x...) do { } while (0) | 2659 | #define DBGUNDO(x...) do { } while (0) |
2659 | #endif | 2660 | #endif |
2660 | 2661 | ||
2661 | static void tcp_undo_cwr(struct sock *sk, const int undo) | 2662 | static void tcp_undo_cwr(struct sock *sk, const bool undo_ssthresh) |
2662 | { | 2663 | { |
2663 | struct tcp_sock *tp = tcp_sk(sk); | 2664 | struct tcp_sock *tp = tcp_sk(sk); |
2664 | 2665 | ||
@@ -2670,14 +2671,13 @@ static void tcp_undo_cwr(struct sock *sk, const int undo) | |||
2670 | else | 2671 | else |
2671 | tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh << 1); | 2672 | tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh << 1); |
2672 | 2673 | ||
2673 | if (undo && tp->prior_ssthresh > tp->snd_ssthresh) { | 2674 | if (undo_ssthresh && tp->prior_ssthresh > tp->snd_ssthresh) { |
2674 | tp->snd_ssthresh = tp->prior_ssthresh; | 2675 | tp->snd_ssthresh = tp->prior_ssthresh; |
2675 | TCP_ECN_withdraw_cwr(tp); | 2676 | TCP_ECN_withdraw_cwr(tp); |
2676 | } | 2677 | } |
2677 | } else { | 2678 | } else { |
2678 | tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh); | 2679 | tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh); |
2679 | } | 2680 | } |
2680 | tcp_moderate_cwnd(tp); | ||
2681 | tp->snd_cwnd_stamp = tcp_time_stamp; | 2681 | tp->snd_cwnd_stamp = tcp_time_stamp; |
2682 | } | 2682 | } |
2683 | 2683 | ||
@@ -2698,7 +2698,7 @@ static int tcp_try_undo_recovery(struct sock *sk) | |||
2698 | * or our original transmission succeeded. | 2698 | * or our original transmission succeeded. |
2699 | */ | 2699 | */ |
2700 | DBGUNDO(sk, inet_csk(sk)->icsk_ca_state == TCP_CA_Loss ? "loss" : "retrans"); | 2700 | DBGUNDO(sk, inet_csk(sk)->icsk_ca_state == TCP_CA_Loss ? "loss" : "retrans"); |
2701 | tcp_undo_cwr(sk, 1); | 2701 | tcp_undo_cwr(sk, true); |
2702 | if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) | 2702 | if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) |
2703 | mib_idx = LINUX_MIB_TCPLOSSUNDO; | 2703 | mib_idx = LINUX_MIB_TCPLOSSUNDO; |
2704 | else | 2704 | else |
@@ -2725,7 +2725,7 @@ static void tcp_try_undo_dsack(struct sock *sk) | |||
2725 | 2725 | ||
2726 | if (tp->undo_marker && !tp->undo_retrans) { | 2726 | if (tp->undo_marker && !tp->undo_retrans) { |
2727 | DBGUNDO(sk, "D-SACK"); | 2727 | DBGUNDO(sk, "D-SACK"); |
2728 | tcp_undo_cwr(sk, 1); | 2728 | tcp_undo_cwr(sk, true); |
2729 | tp->undo_marker = 0; | 2729 | tp->undo_marker = 0; |
2730 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDSACKUNDO); | 2730 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDSACKUNDO); |
2731 | } | 2731 | } |
@@ -2778,7 +2778,7 @@ static int tcp_try_undo_partial(struct sock *sk, int acked) | |||
2778 | tcp_update_reordering(sk, tcp_fackets_out(tp) + acked, 1); | 2778 | tcp_update_reordering(sk, tcp_fackets_out(tp) + acked, 1); |
2779 | 2779 | ||
2780 | DBGUNDO(sk, "Hoe"); | 2780 | DBGUNDO(sk, "Hoe"); |
2781 | tcp_undo_cwr(sk, 0); | 2781 | tcp_undo_cwr(sk, false); |
2782 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPPARTIALUNDO); | 2782 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPPARTIALUNDO); |
2783 | 2783 | ||
2784 | /* So... Do not make Hoe's retransmit yet. | 2784 | /* So... Do not make Hoe's retransmit yet. |
@@ -2807,7 +2807,7 @@ static int tcp_try_undo_loss(struct sock *sk) | |||
2807 | 2807 | ||
2808 | DBGUNDO(sk, "partial loss"); | 2808 | DBGUNDO(sk, "partial loss"); |
2809 | tp->lost_out = 0; | 2809 | tp->lost_out = 0; |
2810 | tcp_undo_cwr(sk, 1); | 2810 | tcp_undo_cwr(sk, true); |
2811 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSSUNDO); | 2811 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSSUNDO); |
2812 | inet_csk(sk)->icsk_retransmits = 0; | 2812 | inet_csk(sk)->icsk_retransmits = 0; |
2813 | tp->undo_marker = 0; | 2813 | tp->undo_marker = 0; |
@@ -2821,8 +2821,11 @@ static int tcp_try_undo_loss(struct sock *sk) | |||
2821 | static inline void tcp_complete_cwr(struct sock *sk) | 2821 | static inline void tcp_complete_cwr(struct sock *sk) |
2822 | { | 2822 | { |
2823 | struct tcp_sock *tp = tcp_sk(sk); | 2823 | struct tcp_sock *tp = tcp_sk(sk); |
2824 | tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh); | 2824 | /* Do not moderate cwnd if it's already undone in cwr or recovery */ |
2825 | tp->snd_cwnd_stamp = tcp_time_stamp; | 2825 | if (tp->undo_marker && tp->snd_cwnd > tp->snd_ssthresh) { |
2826 | tp->snd_cwnd = tp->snd_ssthresh; | ||
2827 | tp->snd_cwnd_stamp = tcp_time_stamp; | ||
2828 | } | ||
2826 | tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR); | 2829 | tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR); |
2827 | } | 2830 | } |
2828 | 2831 | ||
@@ -3349,7 +3352,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, | |||
3349 | net_invalid_timestamp())) | 3352 | net_invalid_timestamp())) |
3350 | rtt_us = ktime_us_delta(ktime_get_real(), | 3353 | rtt_us = ktime_us_delta(ktime_get_real(), |
3351 | last_ackt); | 3354 | last_ackt); |
3352 | else if (ca_seq_rtt > 0) | 3355 | else if (ca_seq_rtt >= 0) |
3353 | rtt_us = jiffies_to_usecs(ca_seq_rtt); | 3356 | rtt_us = jiffies_to_usecs(ca_seq_rtt); |
3354 | } | 3357 | } |
3355 | 3358 | ||
@@ -3493,7 +3496,7 @@ static void tcp_undo_spur_to_response(struct sock *sk, int flag) | |||
3493 | if (flag & FLAG_ECE) | 3496 | if (flag & FLAG_ECE) |
3494 | tcp_ratehalving_spur_to_response(sk); | 3497 | tcp_ratehalving_spur_to_response(sk); |
3495 | else | 3498 | else |
3496 | tcp_undo_cwr(sk, 1); | 3499 | tcp_undo_cwr(sk, true); |
3497 | } | 3500 | } |
3498 | 3501 | ||
3499 | /* F-RTO spurious RTO detection algorithm (RFC4138) | 3502 | /* F-RTO spurious RTO detection algorithm (RFC4138) |