diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
| -rw-r--r-- | net/ipv4/tcp_input.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2549b29b062d..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) |
| @@ -4399,7 +4402,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | |||
| 4399 | if (!skb_copy_datagram_iovec(skb, 0, tp->ucopy.iov, chunk)) { | 4402 | if (!skb_copy_datagram_iovec(skb, 0, tp->ucopy.iov, chunk)) { |
| 4400 | tp->ucopy.len -= chunk; | 4403 | tp->ucopy.len -= chunk; |
| 4401 | tp->copied_seq += chunk; | 4404 | tp->copied_seq += chunk; |
| 4402 | eaten = (chunk == skb->len && !th->fin); | 4405 | eaten = (chunk == skb->len); |
| 4403 | tcp_rcv_space_adjust(sk); | 4406 | tcp_rcv_space_adjust(sk); |
| 4404 | } | 4407 | } |
| 4405 | local_bh_disable(); | 4408 | local_bh_disable(); |
