diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index dc810df53e90..2d690b3f0a7b 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1214,6 +1214,7 @@ static u8 tcp_sacktag_one(struct sock *sk, | |||
1214 | sacked |= TCPCB_SACKED_ACKED; | 1214 | sacked |= TCPCB_SACKED_ACKED; |
1215 | state->flag |= FLAG_DATA_SACKED; | 1215 | state->flag |= FLAG_DATA_SACKED; |
1216 | tp->sacked_out += pcount; | 1216 | tp->sacked_out += pcount; |
1217 | tp->delivered += pcount; /* Out-of-order packets delivered */ | ||
1217 | 1218 | ||
1218 | fack_count += pcount; | 1219 | fack_count += pcount; |
1219 | 1220 | ||
@@ -1825,8 +1826,12 @@ static void tcp_check_reno_reordering(struct sock *sk, const int addend) | |||
1825 | static void tcp_add_reno_sack(struct sock *sk) | 1826 | static void tcp_add_reno_sack(struct sock *sk) |
1826 | { | 1827 | { |
1827 | struct tcp_sock *tp = tcp_sk(sk); | 1828 | struct tcp_sock *tp = tcp_sk(sk); |
1829 | u32 prior_sacked = tp->sacked_out; | ||
1830 | |||
1828 | tp->sacked_out++; | 1831 | tp->sacked_out++; |
1829 | tcp_check_reno_reordering(sk, 0); | 1832 | tcp_check_reno_reordering(sk, 0); |
1833 | if (tp->sacked_out > prior_sacked) | ||
1834 | tp->delivered++; /* Some out-of-order packet is delivered */ | ||
1830 | tcp_verify_left_out(tp); | 1835 | tcp_verify_left_out(tp); |
1831 | } | 1836 | } |
1832 | 1837 | ||
@@ -1838,6 +1843,7 @@ static void tcp_remove_reno_sacks(struct sock *sk, int acked) | |||
1838 | 1843 | ||
1839 | if (acked > 0) { | 1844 | if (acked > 0) { |
1840 | /* One ACK acked hole. The rest eat duplicate ACKs. */ | 1845 | /* One ACK acked hole. The rest eat duplicate ACKs. */ |
1846 | tp->delivered += max_t(int, acked - tp->sacked_out, 1); | ||
1841 | if (acked - 1 >= tp->sacked_out) | 1847 | if (acked - 1 >= tp->sacked_out) |
1842 | tp->sacked_out = 0; | 1848 | tp->sacked_out = 0; |
1843 | else | 1849 | else |
@@ -3156,10 +3162,13 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, | |||
3156 | flag |= FLAG_ORIG_SACK_ACKED; | 3162 | flag |= FLAG_ORIG_SACK_ACKED; |
3157 | } | 3163 | } |
3158 | 3164 | ||
3159 | if (sacked & TCPCB_SACKED_ACKED) | 3165 | if (sacked & TCPCB_SACKED_ACKED) { |
3160 | tp->sacked_out -= acked_pcount; | 3166 | tp->sacked_out -= acked_pcount; |
3161 | else if (tcp_is_sack(tp) && !tcp_skb_spurious_retrans(tp, skb)) | 3167 | } else if (tcp_is_sack(tp)) { |
3162 | tcp_rack_advance(tp, &skb->skb_mstamp, sacked); | 3168 | tp->delivered += acked_pcount; |
3169 | if (!tcp_skb_spurious_retrans(tp, skb)) | ||
3170 | tcp_rack_advance(tp, &skb->skb_mstamp, sacked); | ||
3171 | } | ||
3163 | if (sacked & TCPCB_LOST) | 3172 | if (sacked & TCPCB_LOST) |
3164 | tp->lost_out -= acked_pcount; | 3173 | tp->lost_out -= acked_pcount; |
3165 | 3174 | ||
@@ -3541,9 +3550,9 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3541 | bool is_dupack = false; | 3550 | bool is_dupack = false; |
3542 | u32 prior_fackets; | 3551 | u32 prior_fackets; |
3543 | int prior_packets = tp->packets_out; | 3552 | int prior_packets = tp->packets_out; |
3544 | const int prior_unsacked = tp->packets_out - tp->sacked_out; | 3553 | u32 prior_delivered = tp->delivered; |
3545 | int acked = 0; /* Number of packets newly acked */ | 3554 | int acked = 0; /* Number of packets newly acked */ |
3546 | int acked_sacked; /* Number of packets newly acked or sacked */ | 3555 | u32 acked_sacked; /* Number of packets newly acked or sacked */ |
3547 | int rexmit = REXMIT_NONE; /* Flag to (re)transmit to recover losses */ | 3556 | int rexmit = REXMIT_NONE; /* Flag to (re)transmit to recover losses */ |
3548 | 3557 | ||
3549 | sack_state.first_sackt.v64 = 0; | 3558 | sack_state.first_sackt.v64 = 0; |
@@ -3645,7 +3654,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3645 | if (tp->tlp_high_seq) | 3654 | if (tp->tlp_high_seq) |
3646 | tcp_process_tlp_ack(sk, ack, flag); | 3655 | tcp_process_tlp_ack(sk, ack, flag); |
3647 | 3656 | ||
3648 | acked_sacked = prior_unsacked - (tp->packets_out - tp->sacked_out); | 3657 | acked_sacked = tp->delivered - prior_delivered; |
3649 | /* Advance cwnd if state allows */ | 3658 | /* Advance cwnd if state allows */ |
3650 | if (tcp_in_cwnd_reduction(sk)) { | 3659 | if (tcp_in_cwnd_reduction(sk)) { |
3651 | /* Reduce cwnd if state mandates */ | 3660 | /* Reduce cwnd if state mandates */ |