aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/tcp_input.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d6edb98fd526..b54d9d37b636 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1842,9 +1842,16 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
1842 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; 1842 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
1843 } 1843 }
1844 1844
1845 /* Don't lost mark skbs that were fwd transmitted after RTO */ 1845 /* Marking forward transmissions that were made after RTO lost
1846 if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) && 1846 * can cause unnecessary retransmissions in some scenarios,
1847 !after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark)) { 1847 * SACK blocks will mitigate that in some but not in all cases.
1848 * We used to not mark them but it was causing break-ups with
1849 * receivers that do only in-order receival.
1850 *
1851 * TODO: we could detect presence of such receiver and select
1852 * different behavior per flow.
1853 */
1854 if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) {
1848 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; 1855 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
1849 tp->lost_out += tcp_skb_pcount(skb); 1856 tp->lost_out += tcp_skb_pcount(skb);
1850 } 1857 }
@@ -1860,7 +1867,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
1860 tp->reordering = min_t(unsigned int, tp->reordering, 1867 tp->reordering = min_t(unsigned int, tp->reordering,
1861 sysctl_tcp_reordering); 1868 sysctl_tcp_reordering);
1862 tcp_set_ca_state(sk, TCP_CA_Loss); 1869 tcp_set_ca_state(sk, TCP_CA_Loss);
1863 tp->high_seq = tp->frto_highmark; 1870 tp->high_seq = tp->snd_nxt;
1864 TCP_ECN_queue_cwr(tp); 1871 TCP_ECN_queue_cwr(tp);
1865 1872
1866 tcp_clear_retrans_hints_partial(tp); 1873 tcp_clear_retrans_hints_partial(tp);