aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/tcp_output.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 239cea7b6c0e..8f9793a37b61 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2035,16 +2035,22 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
2035 struct tcp_sock *tp = tcp_sk(sk); 2035 struct tcp_sock *tp = tcp_sk(sk);
2036 struct sk_buff *skb; 2036 struct sk_buff *skb;
2037 struct sk_buff *hole = NULL; 2037 struct sk_buff *hole = NULL;
2038 u32 last_lost;
2038 int mib_idx; 2039 int mib_idx;
2039 int fwd_rexmitting = 0; 2040 int fwd_rexmitting = 0;
2040 2041
2041 if (!tp->lost_out) 2042 if (!tp->lost_out)
2042 tp->retransmit_high = tp->snd_una; 2043 tp->retransmit_high = tp->snd_una;
2043 2044
2044 if (tp->retransmit_skb_hint) 2045 if (tp->retransmit_skb_hint) {
2045 skb = tp->retransmit_skb_hint; 2046 skb = tp->retransmit_skb_hint;
2046 else 2047 last_lost = TCP_SKB_CB(skb)->end_seq;
2048 if (after(last_lost, tp->retransmit_high))
2049 last_lost = tp->retransmit_high;
2050 } else {
2047 skb = tcp_write_queue_head(sk); 2051 skb = tcp_write_queue_head(sk);
2052 last_lost = tp->snd_una;
2053 }
2048 2054
2049 /* First pass: retransmit lost packets. */ 2055 /* First pass: retransmit lost packets. */
2050 tcp_for_write_queue_from(skb, sk) { 2056 tcp_for_write_queue_from(skb, sk) {
@@ -2073,6 +2079,7 @@ begin_fwd:
2073 mib_idx = LINUX_MIB_TCPFORWARDRETRANS; 2079 mib_idx = LINUX_MIB_TCPFORWARDRETRANS;
2074 2080
2075 } else if (!before(TCP_SKB_CB(skb)->seq, tp->retransmit_high)) { 2081 } else if (!before(TCP_SKB_CB(skb)->seq, tp->retransmit_high)) {
2082 tp->retransmit_high = last_lost;
2076 if (!tcp_can_forward_retransmit(sk)) 2083 if (!tcp_can_forward_retransmit(sk))
2077 break; 2084 break;
2078 /* Backtrack if necessary to non-L'ed skb */ 2085 /* Backtrack if necessary to non-L'ed skb */
@@ -2089,6 +2096,7 @@ begin_fwd:
2089 continue; 2096 continue;
2090 2097
2091 } else { 2098 } else {
2099 last_lost = TCP_SKB_CB(skb)->end_seq;
2092 if (icsk->icsk_ca_state != TCP_CA_Loss) 2100 if (icsk->icsk_ca_state != TCP_CA_Loss)
2093 mib_idx = LINUX_MIB_TCPFASTRETRANS; 2101 mib_idx = LINUX_MIB_TCPFASTRETRANS;
2094 else 2102 else