quicwg / base-drafts Public
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
congestion window increase on every ACKed packet could result in bursty sends #3094
Comments
|
PR #2675 added more specific text on avoiding bursts into the network, FYI. |
|
Please note that PR #2675 addresses the issue of app-limited or pacing-limited cases to not increase cwnd when it is under utilized. My concern is cwnd being inflated due to an ACK frame containing ACKs for large number of packets. |
|
@ianswett : The problem here is that we don't talk about burstiness that can occur when pacing is not in place, and a stretch-ack is received. PRR handles this, but we don't do PRR in the draft. |
|
No we need to spend lots of time on Reno as everybody appears to be doing Cubic or BBR? |
|
Cubic has this problem. BBR cannot be assumed. |
|
Except Cubic opens the window based on time spent, not just ack received |
|
I don't get the scenario. It seems that @goelvidhi is worried about receiving an ACK for a large number of packets. This is not a congestion window problem, because it happens even if the congestion windows size remains constant. The root cause is that the ACK of N packets now reduces the number of packet in flow by N. So this is strictly about pacing, not about congestion control. |
|
@huitema: yes, and it can and still does burst because of stretch acks |
|
Not just stretch Acks -- deliberate Ack compression by the network happens too. Very few alternative to pacing. |
|
https://tools.ietf.org/html/rfc3465 describes
|
|
Discussed in Cupertino. @goelvidhi to prepare a PR that hopefully can incorporate some ideas from RFC3465 to add safety features for non-pacing stacks. |
|
But 3465 does not solve the burst problem. It limits the growth of the window, but does not do pacing of any kind. |
|
I think we can change to something like this
|
|
@junhochoi, I think we need to do 2MSS clamping per ACK received and not per packet acked. I am thinking that we can remove OnPacketAckedCC and instead do OnAckReceivedCC. Pseudocode change something like this: |
|
I think we can keep |
|
Yup, that's an important missing fix, though it needs to be applied only when not pacing. Additionally, #3106 helps with burstiness in general. @goelvidhi : I would make a |
|
The proposed change has the effect of reducing the effective Window if ACKs are compressed. Say you have a window of 12 packets, acks are delayed, and a single ACK acknowledges 12 packets. Now you have a window of 2 packets, your transmission rate is 6 times slower than before, and it will take you 10 RTT to recover. Is that really what you want? |
|
@huitema: This is what ABC (RFC 3465) does for TCP. ACK compression has side-effects, and the way to deal with it is, as you say, to pace packets out. This reduction in performance is only when the endpoint does not pace, and it is the only way to limit bursts in that case. |
|
Also, ACK compression does not necessarily imply ACK pruning. I have traces in which 1 RTT worth of ACKs is compressed and delivered back to back. In that case, the proposed algorithm will do nothing: you will get 2 MSS added for each ACK, back to back within less than 1 ms. |
|
FYI. FreeBSD implements rfc3465 (and enabled by default) https://github.com/freebsd/freebsd/blob/master/sys/netinet/cc/cc_newreno.c#L174 |
When not pacing packets, limit the CWND increase to 2 packets per ACK frame received and cite RFC3465. Fixes #3094
|
@ianswett: I am working on the PR for pseudocode changes. |
|
Bringing conversation in from the list: With regards to #3232, one of the things we found in testing was that it could (a) still allow an implementation to be vulnerable to too much bursting (the original problem), but more importantly (b) locked receivers into an ack pattern of acking every other packet. My main concern is that this causes problems if receivers want to experiment with and change acking strategies going forward in way that otherwise would be fine. One way to look at the problem described by this issue is that the existing text has a minor underspecification, in which it has the notion of a burst limit but says nothing about the frequency of such bursts. Two "bursts" of 10MSS that are sent within a couple nanoseconds are really one burst that's too big. Another way of fixing this is to remove even the specification of the 10MSS limit if we really don't want too much text about the non-pacing cases. Essentially, what this comes down to is: pace, or even if you don't pace, you need to not send bursts above some frequency; and if you don't set some pacing timers, you'll likely underutilize the link. |
|
I'm going to put this out there: the answer is MUST pace. You might formalize this by saying the number of packets sent in any interval |
|
@martinthomson Yes, it does largely reduce to "implementations MUST pace" (even if the pacing algorithm isn't very nuanced, in which case you'll perform poorly). The formalization of the rate, one option for which was specified in #3351, I think is the heart of what should be done here. |
|
There are two routes that we can take:
OR |
|
I'm sympathetic to saying MUST pace, and I like the formatlization that @martinthomson suggests. I've heard some pushback on saying MUST pace in the past, but it might be worth giving it a shot again. @erickinnear @tfpauly @goelvidhi : What do you think? |
|
That said... I will note that @martinthomson 's formalization allows for a burst at the end of an RTT. Consider for example when a single ACK is received that acknowledges an entire window. That would be legal by this definition. I think that's ok. |
|
Discussed in ZRH. Proposed resolution is to define and REQUIRE pacing. |
|
@janaiyengar I think requiring pacing makes good sense, with some formalization of what that means. |
|
To clarify the status here, my understanding is that the proposal is to close this design issue with no action. The discussions have identified editorial improvements that will be addressed independently. |
|
Let's continue the editorial discussion on #3122. |
|
Closing this issue and continuing discussion on #3122 |
|
This needs to run through the consensus call procedure, so we'll keep it open for another week. |
When an ACK arrives that acknowledges N packets (where N could be very large), QUIC will increase the congestion window by more than 1MSS per congestion window during Congestion Avoidance causing bursty send. This could also affect the slow start.
if (congestion_window < ssthresh):
// Slow start.
congestion_window += acked_packet.size
else:
// Congestion avoidance.
congestion_window += kMaxDatagramSize * acked_packet.size / congestion_window
One could argue that QUIC ACKs every other packet, but there ACK packet could get lost or ACK for ACK packet could get lost.
The draft is probably assuming packet pacing but not all implementations support that.
I discussed this with Jana and he thinks that we should add something in pseudo code or some specific text in the draft.
The text was updated successfully, but these errors were encountered: