aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 4c2dd9f863f7..62508a2f9b21 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4199,6 +4199,17 @@ static void tcp_dsack_extend(struct sock *sk, u32 seq, u32 end_seq)
4199 tcp_sack_extend(tp->duplicate_sack, seq, end_seq); 4199 tcp_sack_extend(tp->duplicate_sack, seq, end_seq);
4200} 4200}
4201 4201
4202static void tcp_rcv_spurious_retrans(struct sock *sk, const struct sk_buff *skb)
4203{
4204 /* When the ACK path fails or drops most ACKs, the sender would
4205 * timeout and spuriously retransmit the same segment repeatedly.
4206 * The receiver remembers and reflects via DSACKs. Leverage the
4207 * DSACK state and change the txhash to re-route speculatively.
4208 */
4209 if (TCP_SKB_CB(skb)->seq == tcp_sk(sk)->duplicate_sack[0].start_seq)
4210 sk_rethink_txhash(sk);
4211}
4212
4202static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb) 4213static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb)
4203{ 4214{
4204 struct tcp_sock *tp = tcp_sk(sk); 4215 struct tcp_sock *tp = tcp_sk(sk);
@@ -4211,6 +4222,7 @@ static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb)
4211 if (tcp_is_sack(tp) && sock_net(sk)->ipv4.sysctl_tcp_dsack) { 4222 if (tcp_is_sack(tp) && sock_net(sk)->ipv4.sysctl_tcp_dsack) {
4212 u32 end_seq = TCP_SKB_CB(skb)->end_seq; 4223 u32 end_seq = TCP_SKB_CB(skb)->end_seq;
4213 4224
4225 tcp_rcv_spurious_retrans(sk, skb);
4214 if (after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) 4226 if (after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt))
4215 end_seq = tp->rcv_nxt; 4227 end_seq = tp->rcv_nxt;
4216 tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, end_seq); 4228 tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, end_seq);
@@ -4755,6 +4767,7 @@ queue_and_out:
4755 } 4767 }
4756 4768
4757 if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { 4769 if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) {
4770 tcp_rcv_spurious_retrans(sk, skb);
4758 /* A retransmit, 2nd most common case. Force an immediate ack. */ 4771 /* A retransmit, 2nd most common case. Force an immediate ack. */
4759 NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOST); 4772 NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOST);
4760 tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); 4773 tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);