* TCP NewReno and single retransmit
@ 2014-10-27 18:49 Marcelo Ricardo Leitner
2014-10-30 2:03 ` Neal Cardwell
0 siblings, 1 reply; 12+ messages in thread
From: Marcelo Ricardo Leitner @ 2014-10-27 18:49 UTC (permalink / raw)
To: netdev
Hi,
We have a report from a customer saying that on a very calm connection, like
having only a single data packet within some minutes, if this packet gets to
be re-transmitted, retrans_stamp is only cleared when the next acked packet is
received. But this may make we abort the connection too soon if this next
packet also gets lost, because the reference for the initial loss is still for
a big while ago..
local-machine remote-machine
| |
send#1---->(*1)|--------> data#1 --------->|
| | |
RTO : :
| | |
---(*2)|----> data#1(retrans) ---->|
| (*3)|<---------- ACK <----------|
| | |
| : :
| : :
| : :
16 minutes (or more) :
| : :
| : :
| : :
| | |
send#2---->(*4)|--------> data#2 --------->|
| | |
RTO : :
| | |
---(*5)|----> data#2(retrans) ---->|
| | |
| | |
RTO*2 : :
| | |
| | |
ETIMEDOUT<----(*6)| |
(diagram is not mine)
ETIMEDOUT happens way too early, because that's based on (*2) stamp.
Question is, can't we really clear retrans_stamp on step (*3)? Like with:
@@ -2382,31 +2382,32 @@ static inline bool tcp_may_undo(const struct tcp_sock *tp)
static bool tcp_try_undo_recovery(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
if (tcp_may_undo(tp)) {
int mib_idx;
/* Happy end! We did not retransmit anything
* or our original transmission succeeded.
*/
DBGUNDO(sk, inet_csk(sk)->icsk_ca_state == TCP_CA_Loss ?
"loss" : "retrans");
tcp_undo_cwnd_reduction(sk, false);
if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss)
mib_idx = LINUX_MIB_TCPLOSSUNDO;
else
mib_idx = LINUX_MIB_TCPFULLUNDO;
NET_INC_STATS_BH(sock_net(sk), mib_idx);
}
if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) {
/* Hold old state until something *above* high_seq
* is ACKed. For Reno it is MUST to prevent false
* fast retransmits (RFC2582). SACK TCP is safe. */
tcp_moderate_cwnd(tp);
+ tp->retrans_stamp = 0;
return true;
}
tcp_set_ca_state(sk, TCP_CA_Open);
return false;
}
We would still hold state, at least part of it.. WDYT?
Thanks,
Marcelo
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: TCP NewReno and single retransmit 2014-10-27 18:49 TCP NewReno and single retransmit Marcelo Ricardo Leitner @ 2014-10-30 2:03 ` Neal Cardwell 2014-10-30 11:24 ` Marcelo Ricardo Leitner 0 siblings, 1 reply; 12+ messages in thread From: Neal Cardwell @ 2014-10-30 2:03 UTC (permalink / raw) To: Marcelo Ricardo Leitner; +Cc: netdev, Yuchung Cheng, Eric Dumazet On Mon, Oct 27, 2014 at 2:49 PM, Marcelo Ricardo Leitner <mleitner@redhat.com> wrote: > Hi, > > We have a report from a customer saying that on a very calm connection, like > having only a single data packet within some minutes, if this packet gets to > be re-transmitted, retrans_stamp is only cleared when the next acked packet > is received. But this may make we abort the connection too soon if this next > packet also gets lost, because the reference for the initial loss is still > for a big while ago.. ... > @@ -2382,31 +2382,32 @@ static inline bool tcp_may_undo(const struct > tcp_sock *tp) > static bool tcp_try_undo_recovery(struct sock *sk) ... > if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) { > /* Hold old state until something *above* high_seq > * is ACKed. For Reno it is MUST to prevent false > * fast retransmits (RFC2582). SACK TCP is safe. */ > tcp_moderate_cwnd(tp); > + tp->retrans_stamp = 0; > return true; > } > tcp_set_ca_state(sk, TCP_CA_Open); > return false; > } > > We would still hold state, at least part of it.. WDYT? This approach sounds OK to me as long as we include a check of tcp_any_retrans_done(), as we do in the similar code paths (for motivation, see the comment above tcp_any_retrans_done()). So it sounds fine to me if you change that one new line to the following 2: + if (!tcp_any_retrans_done(sk)) + tp->retrans_stamp = 0; Nice catch! neal ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TCP NewReno and single retransmit 2014-10-30 2:03 ` Neal Cardwell @ 2014-10-30 11:24 ` Marcelo Ricardo Leitner 2014-10-31 3:51 ` Yuchung Cheng 0 siblings, 1 reply; 12+ messages in thread From: Marcelo Ricardo Leitner @ 2014-10-30 11:24 UTC (permalink / raw) To: Neal Cardwell; +Cc: netdev, Yuchung Cheng, Eric Dumazet On 30-10-2014 00:03, Neal Cardwell wrote: > On Mon, Oct 27, 2014 at 2:49 PM, Marcelo Ricardo Leitner > <mleitner@redhat.com> wrote: >> Hi, >> >> We have a report from a customer saying that on a very calm connection, like >> having only a single data packet within some minutes, if this packet gets to >> be re-transmitted, retrans_stamp is only cleared when the next acked packet >> is received. But this may make we abort the connection too soon if this next >> packet also gets lost, because the reference for the initial loss is still >> for a big while ago.. > ... >> @@ -2382,31 +2382,32 @@ static inline bool tcp_may_undo(const struct >> tcp_sock *tp) >> static bool tcp_try_undo_recovery(struct sock *sk) > ... >> if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) { >> /* Hold old state until something *above* high_seq >> * is ACKed. For Reno it is MUST to prevent false >> * fast retransmits (RFC2582). SACK TCP is safe. */ >> tcp_moderate_cwnd(tp); >> + tp->retrans_stamp = 0; >> return true; >> } >> tcp_set_ca_state(sk, TCP_CA_Open); >> return false; >> } >> >> We would still hold state, at least part of it.. WDYT? > > This approach sounds OK to me as long as we include a check of > tcp_any_retrans_done(), as we do in the similar code paths (for > motivation, see the comment above tcp_any_retrans_done()). Yes, okay. I thought that this would be taken care of already by then but reading the code again now after your comment, I can see what you're saying. Thanks. > So it sounds fine to me if you change that one new line to the following 2: > > + if (!tcp_any_retrans_done(sk)) > + tp->retrans_stamp = 0; Will do. > Nice catch! A good part of it (including the diagram) was done by customer. :) I'll post the patch as soon as we sync with them (credits). Marcelo ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TCP NewReno and single retransmit 2014-10-30 11:24 ` Marcelo Ricardo Leitner @ 2014-10-31 3:51 ` Yuchung Cheng 2014-11-03 16:38 ` Marcelo Ricardo Leitner 0 siblings, 1 reply; 12+ messages in thread From: Yuchung Cheng @ 2014-10-31 3:51 UTC (permalink / raw) To: Marcelo Ricardo Leitner; +Cc: Neal Cardwell, netdev, Eric Dumazet On Thu, Oct 30, 2014 at 7:24 PM, Marcelo Ricardo Leitner <mleitner@redhat.com> wrote: > On 30-10-2014 00:03, Neal Cardwell wrote: >> >> On Mon, Oct 27, 2014 at 2:49 PM, Marcelo Ricardo Leitner >> <mleitner@redhat.com> wrote: >>> >>> Hi, >>> >>> We have a report from a customer saying that on a very calm connection, >>> like >>> having only a single data packet within some minutes, if this packet gets >>> to >>> be re-transmitted, retrans_stamp is only cleared when the next acked >>> packet >>> is received. But this may make we abort the connection too soon if this >>> next >>> packet also gets lost, because the reference for the initial loss is >>> still >>> for a big while ago.. >> >> ... >>> >>> @@ -2382,31 +2382,32 @@ static inline bool tcp_may_undo(const struct >>> tcp_sock *tp) >>> static bool tcp_try_undo_recovery(struct sock *sk) >> >> ... >>> >>> if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) { >>> /* Hold old state until something *above* high_seq >>> * is ACKed. For Reno it is MUST to prevent false >>> * fast retransmits (RFC2582). SACK TCP is safe. */ Or we can just remove this strange state-holding logic? I couldn't find such a "MUST" statement in RFC2582. RFC2582 section 3 step 5 suggests exiting the recovery procedure when an ACK acknowledges the "recover" variable (== tp->high_seq - 1). Since we've called tcp_reset_reno_sack() before tcp_try_undo_recovery(), I couldn't see how false fast retransmits can be triggered without this state-holding. Any insights? >>> tcp_moderate_cwnd(tp); >>> + tp->retrans_stamp = 0; >>> return true; >>> } >>> tcp_set_ca_state(sk, TCP_CA_Open); >>> return false; >>> } >>> >>> We would still hold state, at least part of it.. WDYT? >> >> >> This approach sounds OK to me as long as we include a check of >> tcp_any_retrans_done(), as we do in the similar code paths (for >> motivation, see the comment above tcp_any_retrans_done()). > > > Yes, okay. I thought that this would be taken care of already by then but > reading the code again now after your comment, I can see what you're saying. > Thanks. > >> So it sounds fine to me if you change that one new line to the following >> 2: >> >> + if (!tcp_any_retrans_done(sk)) >> + tp->retrans_stamp = 0; > > > Will do. > >> Nice catch! > > > A good part of it (including the diagram) was done by customer. :) > I'll post the patch as soon as we sync with them (credits). > > Marcelo > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TCP NewReno and single retransmit 2014-10-31 3:51 ` Yuchung Cheng @ 2014-11-03 16:38 ` Marcelo Ricardo Leitner 2014-11-03 20:08 ` Neal Cardwell 0 siblings, 1 reply; 12+ messages in thread From: Marcelo Ricardo Leitner @ 2014-11-03 16:38 UTC (permalink / raw) To: Yuchung Cheng; +Cc: Neal Cardwell, netdev, Eric Dumazet On 31-10-2014 01:51, Yuchung Cheng wrote: > On Thu, Oct 30, 2014 at 7:24 PM, Marcelo Ricardo Leitner > <mleitner@redhat.com> wrote: >> On 30-10-2014 00:03, Neal Cardwell wrote: >>> >>> On Mon, Oct 27, 2014 at 2:49 PM, Marcelo Ricardo Leitner >>> <mleitner@redhat.com> wrote: >>>> >>>> Hi, >>>> >>>> We have a report from a customer saying that on a very calm connection, >>>> like >>>> having only a single data packet within some minutes, if this packet gets >>>> to >>>> be re-transmitted, retrans_stamp is only cleared when the next acked >>>> packet >>>> is received. But this may make we abort the connection too soon if this >>>> next >>>> packet also gets lost, because the reference for the initial loss is >>>> still >>>> for a big while ago.. >>> >>> ... >>>> >>>> @@ -2382,31 +2382,32 @@ static inline bool tcp_may_undo(const struct >>>> tcp_sock *tp) >>>> static bool tcp_try_undo_recovery(struct sock *sk) >>> >>> ... >>>> >>>> if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) { >>>> /* Hold old state until something *above* high_seq >>>> * is ACKed. For Reno it is MUST to prevent false >>>> * fast retransmits (RFC2582). SACK TCP is safe. */ > Or we can just remove this strange state-holding logic? > > I couldn't find such a "MUST" statement in RFC2582. RFC2582 section 3 > step 5 suggests exiting the recovery procedure when an ACK acknowledges > the "recover" variable (== tp->high_seq - 1). > > Since we've called tcp_reset_reno_sack() before tcp_try_undo_recovery(), > I couldn't see how false fast retransmits can be triggered without > this state-holding. > > Any insights? Nice one, me neither. Neal? From RFC2582, Section 5, Avoiding Multiple Fast Retransmits: Nevertheless, unnecessary Fast Retransmits can occur with Reno or NewReno TCP, particularly if a Retransmit Timeout occurs during Fast Recovery. (This is illustrated for Reno on page 6 of [F98], and for NewReno on page 8 of [F98].) With NewReno, the data sender remains in Fast Recovery until either a Retransmit Timeout, or *until all of the data outstanding when Fast Retransmit was entered has been acknowledged*. Thus with NewReno, the problem of multiple Fast Retransmits from a single window of data can only occur after a Retransmit Timeout. Bolding mark is mine. If I didn't miss anything, as that condition was met, we should be good to keep that cwnd reduction (required by section 3 step 5) and but get back to Open state right away. Marcelo >>>> tcp_moderate_cwnd(tp); >>>> + tp->retrans_stamp = 0; >>>> return true; >>>> } >>>> tcp_set_ca_state(sk, TCP_CA_Open); >>>> return false; >>>> } >>>> >>>> We would still hold state, at least part of it.. WDYT? >>> >>> >>> This approach sounds OK to me as long as we include a check of >>> tcp_any_retrans_done(), as we do in the similar code paths (for >>> motivation, see the comment above tcp_any_retrans_done()). >> >> >> Yes, okay. I thought that this would be taken care of already by then but >> reading the code again now after your comment, I can see what you're saying. >> Thanks. >> >>> So it sounds fine to me if you change that one new line to the following >>> 2: >>> >>> + if (!tcp_any_retrans_done(sk)) >>> + tp->retrans_stamp = 0; >> >> >> Will do. >> >>> Nice catch! >> >> >> A good part of it (including the diagram) was done by customer. :) >> I'll post the patch as soon as we sync with them (credits). >> >> Marcelo >> > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TCP NewReno and single retransmit 2014-11-03 16:38 ` Marcelo Ricardo Leitner @ 2014-11-03 20:08 ` Neal Cardwell 2014-11-03 21:35 ` Marcelo Ricardo Leitner 2014-11-04 9:56 ` David Laight 0 siblings, 2 replies; 12+ messages in thread From: Neal Cardwell @ 2014-11-03 20:08 UTC (permalink / raw) To: Marcelo Ricardo Leitner; +Cc: Yuchung Cheng, netdev, Eric Dumazet On Mon, Nov 3, 2014 at 11:38 AM, Marcelo Ricardo Leitner <mleitner@redhat.com> wrote: > On 31-10-2014 01:51, Yuchung Cheng wrote: >>>>> if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) { >>>>> /* Hold old state until something *above* high_seq >>>>> * is ACKed. For Reno it is MUST to prevent false >>>>> * fast retransmits (RFC2582). SACK TCP is safe. */ >> >> Or we can just remove this strange state-holding logic? >> >> I couldn't find such a "MUST" statement in RFC2582. RFC2582 section 3 >> step 5 suggests exiting the recovery procedure when an ACK acknowledges >> the "recover" variable (== tp->high_seq - 1). >> >> Since we've called tcp_reset_reno_sack() before tcp_try_undo_recovery(), >> I couldn't see how false fast retransmits can be triggered without >> this state-holding. >> >> Any insights? > > > Nice one, me neither. Neal? Since there are no literal IETF-style "MUST" statements in RFC2582, I think the "MUST" in the code here is expressing the design philosophy behind the author. :-) AFAICT the "Hold old state" code in tcp_try_undo_recovery() is a pretty reasonable implementation of a mechanism specified in NewReno RFCs to deal with the fundamental ambiguity between (1) dupacks for packets the receiver received above a hole above snd_una, and (2) dupacks for spurious retransmits below snd_una. I think the motivation behind the "Hold old state" code is to stay in Recovery so that we do not treat (2) dupacks as (1) dupacks. I find RFC 2582 not very clear on this point, and the newest NewReno RFC, RFC 6582, is also not so clear IMHO. But the RFC 3782 version of NewReno - https://tools.ietf.org/html/rfc3782 - has a reasonable discussion of this issue. There is a discussion in https://tools.ietf.org/html/rfc3782#section-11 of this ambiguity: There are two separate scenarios in which the TCP sender could receive three duplicate acknowledgements acknowledging "recover" but no more than "recover". One scenario would be that the data sender transmitted four packets with sequence numbers higher than "recover", that the first packet was dropped in the network, and the following three packets triggered three duplicate acknowledgements acknowledging "recover". The second scenario would be that the sender unnecessarily retransmitted three packets below "recover", and that these three packets triggered three duplicate acknowledgements acknowledging "recover". In the absence of SACK, the TCP sender is unable to distinguish between these two scenarios. AFAICT RFC 3782 uses the term "recover" for the sequence number Linux calls tp->high_seq. The specification in RFC 3782 Sec 3 - https://tools.ietf.org/html/rfc3782#section-3 - of the criteria for entering Fast Recovery say that we shouldn't go into a new recovery if the cumulative ACK field doesn't cover more than high_seq/"recover": 1) Three duplicate ACKs: When the third duplicate ACK is received and the sender is not already in the Fast Recovery procedure, check to see if the Cumulative Acknowledgement field covers more than "recover". If so, go to Step 1A. Otherwise, go to Step 1B. 1A) Invoking Fast Retransmit: ... In addition, record the highest sequence number transmitted in the variable "recover", and go to Step 2. 1B) Not invoking Fast Retransmit: ... The last few slides of this presentation by Sally Floyd also talk about this point: http://www.icir.org/floyd/talks/newreno-Mar03.pdf neal ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TCP NewReno and single retransmit 2014-11-03 20:08 ` Neal Cardwell @ 2014-11-03 21:35 ` Marcelo Ricardo Leitner 2014-11-03 23:17 ` Neal Cardwell 2014-11-04 9:56 ` David Laight 1 sibling, 1 reply; 12+ messages in thread From: Marcelo Ricardo Leitner @ 2014-11-03 21:35 UTC (permalink / raw) To: Neal Cardwell; +Cc: Yuchung Cheng, netdev, Eric Dumazet On 03-11-2014 18:08, Neal Cardwell wrote: > On Mon, Nov 3, 2014 at 11:38 AM, Marcelo Ricardo Leitner > <mleitner@redhat.com> wrote: >> On 31-10-2014 01:51, Yuchung Cheng wrote: >>>>>> if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) { >>>>>> /* Hold old state until something *above* high_seq >>>>>> * is ACKed. For Reno it is MUST to prevent false >>>>>> * fast retransmits (RFC2582). SACK TCP is safe. */ >>> >>> Or we can just remove this strange state-holding logic? >>> >>> I couldn't find such a "MUST" statement in RFC2582. RFC2582 section 3 >>> step 5 suggests exiting the recovery procedure when an ACK acknowledges >>> the "recover" variable (== tp->high_seq - 1). >>> >>> Since we've called tcp_reset_reno_sack() before tcp_try_undo_recovery(), >>> I couldn't see how false fast retransmits can be triggered without >>> this state-holding. >>> >>> Any insights? >> >> >> Nice one, me neither. Neal? > > Since there are no literal IETF-style "MUST" statements in RFC2582, I > think the "MUST" in the code here is expressing the design philosophy > behind the author. :-) > > AFAICT the "Hold old state" code in tcp_try_undo_recovery() is a > pretty reasonable implementation of a mechanism specified in NewReno > RFCs to deal with the fundamental ambiguity between (1) dupacks for > packets the receiver received above a hole above snd_una, and (2) > dupacks for spurious retransmits below snd_una. I think the motivation > behind the "Hold old state" code is to stay in Recovery so that we do > not treat (2) dupacks as (1) dupacks. > > I find RFC 2582 not very clear on this point, and the newest NewReno > RFC, RFC 6582, is also not so clear IMHO. But the RFC 3782 version of > NewReno - https://tools.ietf.org/html/rfc3782 - has a reasonable > discussion of this issue. There is a discussion in > https://tools.ietf.org/html/rfc3782#section-11 > of this ambiguity: > > There are two separate scenarios in which the TCP sender could > receive three duplicate acknowledgements acknowledging "recover" but > no more than "recover". One scenario would be that the data sender > transmitted four packets with sequence numbers higher than "recover", > that the first packet was dropped in the network, and the following > three packets triggered three duplicate acknowledgements > acknowledging "recover". The second scenario would be that the > sender unnecessarily retransmitted three packets below "recover", and > that these three packets triggered three duplicate acknowledgements > acknowledging "recover". In the absence of SACK, the TCP sender is > unable to distinguish between these two scenarios. > > AFAICT RFC 3782 uses the term "recover" for the sequence number Linux > calls tp->high_seq. The specification in RFC 3782 Sec 3 - > https://tools.ietf.org/html/rfc3782#section-3 - of the criteria for > entering Fast Recovery say that we shouldn't go into a new recovery if > the cumulative ACK field doesn't cover more than high_seq/"recover": > > 1) Three duplicate ACKs: > When the third duplicate ACK is received and the sender is not > already in the Fast Recovery procedure, check to see if the > Cumulative Acknowledgement field covers more than "recover". If > so, go to Step 1A. Otherwise, go to Step 1B. > > 1A) Invoking Fast Retransmit: > ... > In addition, record the highest sequence number transmitted in > the variable "recover", and go to Step 2. > > 1B) Not invoking Fast Retransmit: > ... > > The last few slides of this presentation by Sally Floyd also talk > about this point: > > http://www.icir.org/floyd/talks/newreno-Mar03.pdf So by sticking with the recovery for a bit longer will help disambiguate the 3 dupacks on high_seq, if they ever happen, and with that avoid re-entering Fast Retransmit if initial (2) happen. It's at the cost of leaving the fast retransmit an ack later but if (2) happens the impact would be much worse, AFAICS. Cool, thanks Neal. If Yuchung is okay with it, I'll proceed with just zeroing that tstamp as initially proposed. Marcelo ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TCP NewReno and single retransmit 2014-11-03 21:35 ` Marcelo Ricardo Leitner @ 2014-11-03 23:17 ` Neal Cardwell 2014-11-04 7:59 ` Yuchung Cheng 0 siblings, 1 reply; 12+ messages in thread From: Neal Cardwell @ 2014-11-03 23:17 UTC (permalink / raw) To: Marcelo Ricardo Leitner; +Cc: Yuchung Cheng, netdev, Eric Dumazet On Mon, Nov 3, 2014 at 4:35 PM, Marcelo Ricardo Leitner <mleitner@redhat.com> wrote: > So by sticking with the recovery for a bit longer will help disambiguate the > 3 dupacks on high_seq, if they ever happen, and with that avoid re-entering > Fast Retransmit if initial (2) happen. It's at the cost of leaving the fast > retransmit an ack later but if (2) happens the impact would be much worse, > AFAICS. Yes, that's my sense. > Cool, thanks Neal. If Yuchung is okay with it, I'll proceed with just > zeroing that tstamp as initially proposed. Yes, that sounds good to me for a short-term fix for the "net" branch, as long as it's: + if (!tcp_any_retrans_done(sk)) + tp->retrans_stamp = 0; Longer-term ("net-next"?) perhaps it makes sense to remove the hold state and protect against this spurious FR situation at the time we decide to enter Fast Recovery, which seems to be the model the RFC is suggesting. neal ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TCP NewReno and single retransmit 2014-11-03 23:17 ` Neal Cardwell @ 2014-11-04 7:59 ` Yuchung Cheng 2014-11-04 13:12 ` Marcelo Ricardo Leitner 2014-11-04 14:38 ` Neal Cardwell 0 siblings, 2 replies; 12+ messages in thread From: Yuchung Cheng @ 2014-11-04 7:59 UTC (permalink / raw) To: Neal Cardwell; +Cc: Marcelo Ricardo Leitner, netdev, Eric Dumazet On Tue, Nov 4, 2014 at 7:17 AM, Neal Cardwell <ncardwell@google.com> wrote: > On Mon, Nov 3, 2014 at 4:35 PM, Marcelo Ricardo Leitner > <mleitner@redhat.com> wrote: >> So by sticking with the recovery for a bit longer will help disambiguate the >> 3 dupacks on high_seq, if they ever happen, and with that avoid re-entering >> Fast Retransmit if initial (2) happen. It's at the cost of leaving the fast >> retransmit an ack later but if (2) happens the impact would be much worse, >> AFAICS. > > Yes, that's my sense. > >> Cool, thanks Neal. If Yuchung is okay with it, I'll proceed with just >> zeroing that tstamp as initially proposed. > > Yes, that sounds good to me for a short-term fix for the "net" branch, > as long as it's: > > + if (!tcp_any_retrans_done(sk)) > + tp->retrans_stamp = 0; > > Longer-term ("net-next"?) perhaps it makes sense to remove the hold > state and protect against this spurious FR situation at the time we > decide to enter Fast Recovery, which seems to be the model the RFC is > suggesting. Thanks for checking. So my suggested fix of removing the hold state is the "less careful variant" that RFC does not recommend. I would rather have the proposed 2-liner fix than implementing the section 6 heuristics to detect spurious retransmit. It's not worth the effort. Everyone should use SACK. > > neal ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TCP NewReno and single retransmit 2014-11-04 7:59 ` Yuchung Cheng @ 2014-11-04 13:12 ` Marcelo Ricardo Leitner 2014-11-04 14:38 ` Neal Cardwell 1 sibling, 0 replies; 12+ messages in thread From: Marcelo Ricardo Leitner @ 2014-11-04 13:12 UTC (permalink / raw) To: Yuchung Cheng, Neal Cardwell; +Cc: netdev, Eric Dumazet On 04-11-2014 05:59, Yuchung Cheng wrote: > On Tue, Nov 4, 2014 at 7:17 AM, Neal Cardwell <ncardwell@google.com> wrote: >> On Mon, Nov 3, 2014 at 4:35 PM, Marcelo Ricardo Leitner >> <mleitner@redhat.com> wrote: >>> So by sticking with the recovery for a bit longer will help disambiguate the >>> 3 dupacks on high_seq, if they ever happen, and with that avoid re-entering >>> Fast Retransmit if initial (2) happen. It's at the cost of leaving the fast >>> retransmit an ack later but if (2) happens the impact would be much worse, >>> AFAICS. >> >> Yes, that's my sense. >> >>> Cool, thanks Neal. If Yuchung is okay with it, I'll proceed with just >>> zeroing that tstamp as initially proposed. >> >> Yes, that sounds good to me for a short-term fix for the "net" branch, >> as long as it's: >> >> + if (!tcp_any_retrans_done(sk)) >> + tp->retrans_stamp = 0; >> >> Longer-term ("net-next"?) perhaps it makes sense to remove the hold >> state and protect against this spurious FR situation at the time we >> decide to enter Fast Recovery, which seems to be the model the RFC is >> suggesting. > Thanks for checking. So my suggested fix of removing the hold state is > the "less careful variant" that RFC does not recommend. I would rather > have the proposed 2-liner fix than implementing the section 6 > heuristics to detect spurious retransmit. It's not worth the effort. > Everyone should use SACK. Yup, agreed. Thanks, Marcelo ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: TCP NewReno and single retransmit 2014-11-04 7:59 ` Yuchung Cheng 2014-11-04 13:12 ` Marcelo Ricardo Leitner @ 2014-11-04 14:38 ` Neal Cardwell 1 sibling, 0 replies; 12+ messages in thread From: Neal Cardwell @ 2014-11-04 14:38 UTC (permalink / raw) To: Yuchung Cheng; +Cc: Marcelo Ricardo Leitner, netdev, Eric Dumazet On Tue, Nov 4, 2014 at 2:59 AM, Yuchung Cheng <ycheng@google.com> wrote: > Thanks for checking. So my suggested fix of removing the hold state is > the "less careful variant" that RFC does not recommend. I would rather > have the proposed 2-liner fix than implementing the section 6 > heuristics to detect spurious retransmit. It's not worth the effort. > Everyone should use SACK. Agreed. The simple 2-liner seems like the simplest and lowest-risk fix. And given that >95% of public Internet flows and an even higher proportion of datacenter flows use SACK, it's not worth spending time optimizing NewReno. neal ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: TCP NewReno and single retransmit 2014-11-03 20:08 ` Neal Cardwell 2014-11-03 21:35 ` Marcelo Ricardo Leitner @ 2014-11-04 9:56 ` David Laight 1 sibling, 0 replies; 12+ messages in thread From: David Laight @ 2014-11-04 9:56 UTC (permalink / raw) To: 'Neal Cardwell', Marcelo Ricardo Leitner Cc: Yuchung Cheng, netdev, Eric Dumazet > Since there are no literal IETF-style "MUST" statements in RFC2582, I > think the "MUST" in the code here is expressing the design philosophy > behind the author. :-) I wouldn't guarantee that the authors of any RFC (or other standards document) managed to cover all possible cases. David ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2014-11-04 14:38 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-10-27 18:49 TCP NewReno and single retransmit Marcelo Ricardo Leitner 2014-10-30 2:03 ` Neal Cardwell 2014-10-30 11:24 ` Marcelo Ricardo Leitner 2014-10-31 3:51 ` Yuchung Cheng 2014-11-03 16:38 ` Marcelo Ricardo Leitner 2014-11-03 20:08 ` Neal Cardwell 2014-11-03 21:35 ` Marcelo Ricardo Leitner 2014-11-03 23:17 ` Neal Cardwell 2014-11-04 7:59 ` Yuchung Cheng 2014-11-04 13:12 ` Marcelo Ricardo Leitner 2014-11-04 14:38 ` Neal Cardwell 2014-11-04 9:56 ` David Laight
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).