Re: TCP being hoodwinked into spurious retransmissions by lack of timestamps?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 03/04/2014 02:23 PM, Yuchung Cheng wrote:
On Tue, Mar 4, 2014 at 12:35 PM, Neal Cardwell <ncardwell@xxxxxxxxxx> wrote:
What's the receiver OS in this trace? It's reneging on SACKs. :-) Take
a look at this ACK:

18:20:46.800063 IP 75.236.145.7.443 > 91.216.86.7.56064: .
4262:4262(0) ack 3171368 win 32716 <nop,nop,sack 1 {3171368:3177208}>

Note that it's ACKing 3171368 and SACKing the adjacent sequence range:
{3171368:3177208}. That's not cool.

I think that's causing the Linux sender to enter the
tcp_check_sack_reneging() code path, which calls tcp_enter_loss().

It seems that the Linux sender did not enable FRTO for that
tcp_enter_loss() invocation. Maybe there is some way we can revise the
logic to enable FRTO in cases like this, so we can detect that the
retransmission was not needed, and abort the stream of spurious
retransmissions...
Sure we can try:

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 6e48093..735ece6 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1972,7 +1972,7 @@ void tcp_enter_loss(struct sock *sk, int how)
          * the same SND.UNA (sec 3.2). Disable F-RTO on path MTU probing
          */
         tp->frto = sysctl_tcp_frto &&
-                  (new_recovery || icsk->icsk_retransmits) &&
+                  (new_recovery || icsk->icsk_retransmits || how) &&
                    !inet_csk(sk)->icsk_mtup.probe_size;
  }


However that only works if we got new data to send. For a better
solution, with the lack of TS option or DSACK support, we can
1) use Neal's neat idea to send a different size packet on the first
retransmission after timeout, and use that to distinguish if the ACK
is for the original or retry.

What would one do if the ACK arriving after the short retransmission was farther to the right than the end of the original packet? Won't that be ambiguous?

2) Do not blindly marked any packet unsacked lost in tcp_enter_loss;
My idea would be to do that only if the packet was sent min_rtt ago;

I can try to implement these ideas if people are interested.

If these near-heroics are unnecessary if timestamps are present, I'm not sure I'd push too hard. Unless you think that timestamps not being present is sufficiently common.

rick
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Discussion]     [TCP Instrumentation]     [Ethernet Bridging]     [Linux Wireless Networking]     [Linux WPAN Networking]     [Linux Host AP]     [Linux WPAN Networking]     [Linux Bluetooth Networking]     [Linux ATH6KL Networking]     [Linux Networking Users]     [Linux Coverity]     [VLAN]     [Git]     [IETF Annouce]     [Linux Assembly]     [Security]     [Bugtraq]     [Yosemite Information]     [MIPS Linux]     [ARM Linux Kernel]     [ARM Linux]     [Linux Virtualization]     [Linux IDE]     [Linux RAID]     [Linux SCSI]