diff options
-rw-r--r-- | net/ipv4/tcp_output.c | 12 |
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 |