[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <alpine.DEB.2.20.1807021245150.30209@whs-18.cs.helsinki.fi>
Date: Mon, 2 Jul 2018 13:26:06 +0300 (EEST)
From: Ilpo Järvinen <ilpo.jarvinen@...sinki.fi>
To: Neal Cardwell <ncardwell@...gle.com>
cc: Netdev <netdev@...r.kernel.org>, Yuchung Cheng <ycheng@...gle.com>,
Eric Dumazet <edumazet@...gle.com>,
Michal Kubecek <mkubecek@...e.cz>
Subject: Re: [PATCH net] tcp: prevent bogus FRTO undos with non-SACK flows
On Sat, 30 Jun 2018, Neal Cardwell wrote:
> As I mentioned, I ran your patch through all our team's TCP
> packetdrill tests, and it passes all of the tests. One of our tests
> needed updating, because if there is a non-SACK connection with a
> spurious RTO due to a delayed flight of ACKs then the FRTO undo now
> happens one ACK later (when we get an ACK that doesn't cover a
> retransmit). But that seems fine to me.
Yes, this is what is wanted. The non-SACK FRTO cannot make decision on
the first cumulative ACK because that could be (often is) triggered by the
retransmit but only from the next ACK after that.
Even with SACK FRTO, there is a hazard on doing it that early as tail ACK
losses can lead to discovery of newly SACKed skbs from ACK of the
retransmitted segment. For that to occur, however, the cumulative ACK
cannot cover those skbs implying more holes that need to be recovered.
Therefore, the window reduction will eventually occur anyway but it would
still first do a bogus undo also in that case.
> I also cooked the new packetdrill test below to explicitly cover this
> case you are addressing (please let me know if you have an alternate
> suggestion).
>
> Tested-by: Neal Cardwell <ncardwell@...gle.com>
> Acked-by: Neal Cardwell <ncardwell@...gle.com>
>
> Thanks!
> neal
>
> ---
>
> 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
> +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
> +0 bind(3, ..., ...) = 0
> +0 listen(3, 1) = 0
>
> +0 < S 0:0(0) win 32792 <mss 1000,nop,wscale 7>
> +0 > S. 0:0(0) ack 1 <mss 1460,nop,wscale 8>
> +.02 < . 1:1(0) ack 1 win 257
> +0 accept(3, ..., ...) = 4
>
> // Send 3 packets. First is really lost. And the dupacks
> // for the data packets that arrived at the reciver are slow in arriving.
> +0 write(4, ..., 3000) = 3000
> +0 > P. 1:3001(3000) ack 1
>
> // RTO and retransmit head. This fills a real loss.
> +.22 > . 1:1001(1000) ack 1
>
> // Dupacks for packets 2 and 3 arrive.
> +.02 < . 1:1(0) ack 1 win 257
> +0 < . 1:1(0) ack 1 win 257
>
> // The cumulative ACK for all the data arrives. We do not undo, because
> // this is a non-SACK connection, and retransmitted data was ACKed.
> // It's good that there's no FRTO undo, since a packet was really lost.
> // Because this is non-SACK, tcp_try_undo_recovery() holds CA_Loss
> // until something beyond high_seq is ACKed.
> +.005 < . 1:1(0) ack 3001 win 257
> +0 %{ assert tcpi_ca_state == TCP_CA_Loss, tcpi_ca_state }%
> +0 %{ assert tcpi_snd_cwnd == 4, tcpi_snd_cwnd }%
> +0 %{ assert tcpi_snd_ssthresh == 7, tcpi_snd_ssthresh }%
I think that the snd_cwnd is still fishy there but that would
require also the other patch from my series (cwnd was 1 so it should be 2
after the cumulative ACK).
--
i.
Powered by blists - more mailing lists