diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/tcp_input.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 0f757578f3bd..9fc9096ada8a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1417,11 +1417,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
1417 | if ((dup_sack && in_sack) && | 1417 | if ((dup_sack && in_sack) && |
1418 | (sacked&TCPCB_SACKED_ACKED)) | 1418 | (sacked&TCPCB_SACKED_ACKED)) |
1419 | reord = min(fack_count, reord); | 1419 | reord = min(fack_count, reord); |
1420 | } else { | ||
1421 | /* If it was in a hole, we detected reordering. */ | ||
1422 | if (fack_count < prior_fackets && | ||
1423 | !(sacked&TCPCB_SACKED_ACKED)) | ||
1424 | reord = min(fack_count, reord); | ||
1425 | } | 1420 | } |
1426 | 1421 | ||
1427 | /* Nothing to do; acked frame is about to be dropped. */ | 1422 | /* Nothing to do; acked frame is about to be dropped. */ |
@@ -2634,7 +2629,8 @@ static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) | |||
2634 | * is before the ack sequence we can discard it as it's confirmed to have | 2629 | * is before the ack sequence we can discard it as it's confirmed to have |
2635 | * arrived at the other end. | 2630 | * arrived at the other end. |
2636 | */ | 2631 | */ |
2637 | static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) | 2632 | static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, |
2633 | int prior_fackets) | ||
2638 | { | 2634 | { |
2639 | struct tcp_sock *tp = tcp_sk(sk); | 2635 | struct tcp_sock *tp = tcp_sk(sk); |
2640 | const struct inet_connection_sock *icsk = inet_csk(sk); | 2636 | const struct inet_connection_sock *icsk = inet_csk(sk); |
@@ -2643,6 +2639,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) | |||
2643 | int fully_acked = 1; | 2639 | int fully_acked = 1; |
2644 | int flag = 0; | 2640 | int flag = 0; |
2645 | int prior_packets = tp->packets_out; | 2641 | int prior_packets = tp->packets_out; |
2642 | u32 cnt = 0; | ||
2643 | u32 reord = tp->packets_out; | ||
2646 | s32 seq_rtt = -1; | 2644 | s32 seq_rtt = -1; |
2647 | ktime_t last_ackt = net_invalid_timestamp(); | 2645 | ktime_t last_ackt = net_invalid_timestamp(); |
2648 | 2646 | ||
@@ -2683,10 +2681,14 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) | |||
2683 | if ((flag & FLAG_DATA_ACKED) || | 2681 | if ((flag & FLAG_DATA_ACKED) || |
2684 | (packets_acked > 1)) | 2682 | (packets_acked > 1)) |
2685 | flag |= FLAG_NONHEAD_RETRANS_ACKED; | 2683 | flag |= FLAG_NONHEAD_RETRANS_ACKED; |
2686 | } else if (seq_rtt < 0) { | 2684 | } else { |
2687 | seq_rtt = now - scb->when; | 2685 | if (seq_rtt < 0) { |
2688 | if (fully_acked) | 2686 | seq_rtt = now - scb->when; |
2689 | last_ackt = skb->tstamp; | 2687 | if (fully_acked) |
2688 | last_ackt = skb->tstamp; | ||
2689 | } | ||
2690 | if (!(sacked & TCPCB_SACKED_ACKED)) | ||
2691 | reord = min(cnt, reord); | ||
2690 | } | 2692 | } |
2691 | 2693 | ||
2692 | if (sacked & TCPCB_SACKED_ACKED) | 2694 | if (sacked & TCPCB_SACKED_ACKED) |
@@ -2697,12 +2699,16 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) | |||
2697 | if ((sacked & TCPCB_URG) && tp->urg_mode && | 2699 | if ((sacked & TCPCB_URG) && tp->urg_mode && |
2698 | !before(end_seq, tp->snd_up)) | 2700 | !before(end_seq, tp->snd_up)) |
2699 | tp->urg_mode = 0; | 2701 | tp->urg_mode = 0; |
2700 | } else if (seq_rtt < 0) { | 2702 | } else { |
2701 | seq_rtt = now - scb->when; | 2703 | if (seq_rtt < 0) { |
2702 | if (fully_acked) | 2704 | seq_rtt = now - scb->when; |
2703 | last_ackt = skb->tstamp; | 2705 | if (fully_acked) |
2706 | last_ackt = skb->tstamp; | ||
2707 | } | ||
2708 | reord = min(cnt, reord); | ||
2704 | } | 2709 | } |
2705 | tp->packets_out -= packets_acked; | 2710 | tp->packets_out -= packets_acked; |
2711 | cnt += packets_acked; | ||
2706 | 2712 | ||
2707 | /* Initial outgoing SYN's get put onto the write_queue | 2713 | /* Initial outgoing SYN's get put onto the write_queue |
2708 | * just like anything else we transmit. It is not | 2714 | * just like anything else we transmit. It is not |
@@ -2734,13 +2740,18 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) | |||
2734 | tcp_ack_update_rtt(sk, flag, seq_rtt); | 2740 | tcp_ack_update_rtt(sk, flag, seq_rtt); |
2735 | tcp_rearm_rto(sk); | 2741 | tcp_rearm_rto(sk); |
2736 | 2742 | ||
2743 | if (tcp_is_reno(tp)) { | ||
2744 | tcp_remove_reno_sacks(sk, pkts_acked); | ||
2745 | } else { | ||
2746 | /* Non-retransmitted hole got filled? That's reordering */ | ||
2747 | if (reord < prior_fackets) | ||
2748 | tcp_update_reordering(sk, tp->fackets_out - reord, 0); | ||
2749 | } | ||
2750 | |||
2737 | tp->fackets_out -= min(pkts_acked, tp->fackets_out); | 2751 | tp->fackets_out -= min(pkts_acked, tp->fackets_out); |
2738 | /* hint's skb might be NULL but we don't need to care */ | 2752 | /* hint's skb might be NULL but we don't need to care */ |
2739 | tp->fastpath_cnt_hint -= min_t(u32, pkts_acked, | 2753 | tp->fastpath_cnt_hint -= min_t(u32, pkts_acked, |
2740 | tp->fastpath_cnt_hint); | 2754 | tp->fastpath_cnt_hint); |
2741 | if (tcp_is_reno(tp)) | ||
2742 | tcp_remove_reno_sacks(sk, pkts_acked); | ||
2743 | |||
2744 | if (ca_ops->pkts_acked) { | 2755 | if (ca_ops->pkts_acked) { |
2745 | s32 rtt_us = -1; | 2756 | s32 rtt_us = -1; |
2746 | 2757 | ||
@@ -3023,6 +3034,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) | |||
3023 | u32 ack_seq = TCP_SKB_CB(skb)->seq; | 3034 | u32 ack_seq = TCP_SKB_CB(skb)->seq; |
3024 | u32 ack = TCP_SKB_CB(skb)->ack_seq; | 3035 | u32 ack = TCP_SKB_CB(skb)->ack_seq; |
3025 | u32 prior_in_flight; | 3036 | u32 prior_in_flight; |
3037 | u32 prior_fackets; | ||
3026 | s32 seq_rtt; | 3038 | s32 seq_rtt; |
3027 | int prior_packets; | 3039 | int prior_packets; |
3028 | int frto_cwnd = 0; | 3040 | int frto_cwnd = 0; |
@@ -3047,6 +3059,8 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) | |||
3047 | tp->bytes_acked += min(ack - prior_snd_una, tp->mss_cache); | 3059 | tp->bytes_acked += min(ack - prior_snd_una, tp->mss_cache); |
3048 | } | 3060 | } |
3049 | 3061 | ||
3062 | prior_fackets = tp->fackets_out; | ||
3063 | |||
3050 | if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) { | 3064 | if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) { |
3051 | /* Window is constant, pure forward advance. | 3065 | /* Window is constant, pure forward advance. |
3052 | * No more checks are required. | 3066 | * No more checks are required. |
@@ -3088,7 +3102,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) | |||
3088 | prior_in_flight = tcp_packets_in_flight(tp); | 3102 | prior_in_flight = tcp_packets_in_flight(tp); |
3089 | 3103 | ||
3090 | /* See if we can take anything off of the retransmit queue. */ | 3104 | /* See if we can take anything off of the retransmit queue. */ |
3091 | flag |= tcp_clean_rtx_queue(sk, &seq_rtt); | 3105 | flag |= tcp_clean_rtx_queue(sk, &seq_rtt, prior_fackets); |
3092 | 3106 | ||
3093 | /* Guarantee sacktag reordering detection against wrap-arounds */ | 3107 | /* Guarantee sacktag reordering detection against wrap-arounds */ |
3094 | if (before(tp->frto_highmark, tp->snd_una)) | 3108 | if (before(tp->frto_highmark, tp->snd_una)) |