Commit 0eb96bf7 authored by Yuchung Cheng's avatar Yuchung Cheng Committed by David S. Miller

tcp: fix tcp_fastretrans_alert warning

This patch fixes the cause of an WARNING indicatng TCP has pending
retransmission in Open state in tcp_fastretrans_alert().

The root cause is a bad interaction between path mtu probing,
if enabled, and the RACK loss detection. Upong receiving a SACK
above the sequence of the MTU probing packet, RACK could mark the
probe packet lost in tcp_fastretrans_alert(), prior to calling
tcp_simple_retransmit().

tcp_simple_retransmit() only enters Loss state if it newly marks
the probe packet lost. If the probe packet is already identified as
lost by RACK, the sender remains in Open state with some packets
marked lost and retransmitted. Then the next SACK would trigger
the warning. The likely scenario is that the probe packet was
lost due to its size or network congestion. The actual impact of
this warning is small by potentially entering fast recovery an
ACK later.

The simple fix is always entering recovery (Loss) state if some
packet is marked lost during path MTU probing.

Fixes: a0370b3f ("tcp: enable RACK loss detection to trigger recovery")
Reported-by: default avatarOleksandr Natalenko <oleksandr@natalenko.name>
Reported-by: default avatarAlexei Starovoitov <alexei.starovoitov@gmail.com>
Reported-by: default avatarRoman Gushchin <guro@fb.com>
Signed-off-by: default avatarYuchung Cheng <ycheng@google.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarNeal Cardwell <ncardwell@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7ec318fe
...@@ -2615,7 +2615,6 @@ void tcp_simple_retransmit(struct sock *sk) ...@@ -2615,7 +2615,6 @@ void tcp_simple_retransmit(struct sock *sk)
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb; struct sk_buff *skb;
unsigned int mss = tcp_current_mss(sk); unsigned int mss = tcp_current_mss(sk);
u32 prior_lost = tp->lost_out;
tcp_for_write_queue(skb, sk) { tcp_for_write_queue(skb, sk) {
if (skb == tcp_send_head(sk)) if (skb == tcp_send_head(sk))
...@@ -2632,7 +2631,7 @@ void tcp_simple_retransmit(struct sock *sk) ...@@ -2632,7 +2631,7 @@ void tcp_simple_retransmit(struct sock *sk)
tcp_clear_retrans_hints_partial(tp); tcp_clear_retrans_hints_partial(tp);
if (prior_lost == tp->lost_out) if (!tp->lost_out)
return; return;
if (tcp_is_reno(tp)) if (tcp_is_reno(tp))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment