Summary: This changes the experimental behavior of BBR sending ACK_FREQUENCY frames. Now instead of using the static ack eliciting threshold, early in the connection BBR will set the threshold to 2 which has been empirically shown to be a good "initial" value.
Reviewed By: jbeshay
Differential Revision: D40438721
fbshipit-source-id: 184b8025581b6152eea97f9b557b6343d980322d
Summary:
This introduces the ability for BBR to control ACK_FREQUENCY. It also introduces a knob which will let us experiment with different policies.
This code makes BBR issue a new ACK_FREQUENCY every round trip. This may be excessive, so BBR will track the last frame sent, and only send a new one if the new value is sufficiently different in terms of milliseconds.
Note that the only dynamic part of the frame currently will be the max ack delay, which is in terms of fractional RTTs. It is not clear yet how we should vary the other parameters dynamically.
Reviewed By: kvtsoy
Differential Revision: D39910417
fbshipit-source-id: 73cfdac40ca52185c33322017a893e5a02ee58e8
Summary: Add a struct with `CongestionController::State` (if available) into `TransportInfo`, and expand the state structure to include the congestion controller's current bandwidth estimate (if available).
Reviewed By: bschlinker, mjoras
Differential Revision: D39413012
fbshipit-source-id: 3eb79cdf53cc37e2cf5e3729cf44557e8a0a3a45
Summary:
`largestAcked` is a field in the `AckFrame` defined in section 19.3 ("ACK Frames") of RFC9000. This diff adds it to the `AckFrame` as `largestAckedPacket` after renaming the existing field of the same name to `largestNewlyAckedPacket` in D34896383
Some changes to the ACK unit tests were made as part of this change to ensure we're tracking everything correctly.
Reviewed By: mjoras
Differential Revision: D34951525
fbshipit-source-id: c84262a24a93bc05c8c817c5e8d5da229d971e36
Summary:
This diff makes two changes to the RTT samples stored in `AckEvent`.
(1) `AckEvent` currently contains the RTT sample associated with the event. This diff adds two new related fields:
- a field that contains the ACK delay provided in the `AckFrame`
- a field that contains the RTT sample with the ACK delay subtracted from it
(2) The logic in `AckHandlers.cpp` currently updates `ack.mrttSample` if the RTT sample being considered is less than the current value of `ack.mrttSample`:
```
// update AckEvent RTTs, which are used by CCA and other procesisng
ack.mrttSample =
std::min(ack.mrttSample.value_or(rttSample), rttSample);
```
However, this is superfluous at best and confusing in general:
- There is a 1:1 relationship between an `AckEvent` and an `AckFrame`
- Each `AckFrame` can result in at most one RTT measurement
Thus, there can be only one RTT measurement per `AckEvent`, and we do not need to perform this comparison when updating `ack.mrttSample`
Reviewed By: mjoras
Differential Revision: D32588081
fbshipit-source-id: b63673a5bdd9c2830083e97572d422647932e65b
Summary:
- Enable starting BBR with an initial cwnd and minrtt guesses.
- Add minrtt to QuicConnectionStats
- Add unit test for new BBR constructor
Reviewed By: mjoras
Differential Revision: D34438518
fbshipit-source-id: 58607cd3b1424a3f1f006dee94f910a29103826b
Summary:
Adds the packet number space to `AckEvent`.
In tandem, adopts a builder pattern for `AckEvent` to ensure that expected fields are populated.
Reviewed By: mjoras
Differential Revision: D31365819
fbshipit-source-id: 94e9bb4b9b6386d9e3b572819a070e556aca5970
Summary:
Experiment with a less aggressive variant of BBR that could be used for background requests in order to improve responsiveness of foreground requests.
BBR's agressiveness can be controlled through a new transport knob CC_AGRESSIVENESS_KNOB(0xccab) which accepts values between 25-100. The value indicates the percentage of the available BW the congestion controller should try to use, leaving headroom for other flows.
Aggressiveness of BBR is reduced by adjusting BBR's startup gain during the STARTUP phase. During the ProbeBW phase, BBR uses a longer pacing gain progression with values that intentionally underutilize the available BW.
Reviewed By: bschlinker, mjoras
Differential Revision: D31219364
fbshipit-source-id: c67ffcf03d27fd4d41be2d58f00f4f960c7646c7
Summary:
As before we will now aggressively send probes on all spaces with probes available when the PTO timer fires.
This time with more unit tests and some bug fixes.
Reviewed By: yangchi
Differential Revision: D27338523
fbshipit-source-id: 8a9ccb90ed691e996fab4afa2f132c0f99044fbc
Summary:
Due to high number of RTT samples I refactored the OutstandingPacket to
split the packet data and packet metrics. We know have access to metrics
without the need of saving the packet data.
Pull Request resolved: https://github.com/facebookincubator/mvfst/pull/178
Reviewed By: mjoras
Differential Revision: D23711641
Pulled By: bschlinker
fbshipit-source-id: 53791f1f6f6e184f37afca991a873af05909fbd2
Summary: Implicit ACKs, while making code a little simpler/safer, are not real ACKs. One consequence of an implicit ACK is that it potentially ACKs bytes much earlier than they would be in reality, leading to inaccurate RTT measurements and inaccurate bandwidth estimations for BBR.
Reviewed By: yangchi
Differential Revision: D23675102
fbshipit-source-id: 64f779aceffa262515fe48deb18ff571b9a8c882
Summary: This was probably a premature optimization and introduces complexity for dubious gain. Additionally a sequence of losses could potentially cause multiple updates to be delayed.
Reviewed By: yangchi
Differential Revision: D23628058
fbshipit-source-id: d6cf70baec8c34f0209ea791dadc724795fe0c21
Summary:
First step towards d6d. Semantically we need to separate the old `udpSendPacketLen` into `peerMaxPacketSize` as well as `currPMTU`. The former is directly tied to the peer's max_packet_size transport parameter whereas the second is controlled by d6d. To get the actual udp mss, call `conn_->getUdpSendPacketLen()`, which will use the minimum of the two if d6d is enabled, otherwise it will fallback to use `peerMaxPacketSize` only.
During processClientInitialParams and processServerInitialParams, we no longer need to check whether `canIgnorePathMTU` is set because that logic is moved to `setUdpSendPacketLen`. If d6d is enabled, we set both `peerMaxPacketSize` and `currPMTU` to `packetSize` because receiving an initial packet of size x indicates both that the peer accepts x-sized packet and that the PMTU is at least x.
Many call sites and tests are changed.
Faebook:
For now, d6d is considered enabled if `canIgnorePathMTU==false` and `turnoffPMTUD==true`. Down the road, from semantic & practical POV at least one of them should be renamed to something like `enableD6D`, since enabling d6d implies turning off PMTUD and that we should not ignore PMTU. We can keep one for the sake of testing.
Reviewed By: mjoras
Differential Revision: D22049806
fbshipit-source-id: 7a9b30b7e2519c132101509be56a9e63b803dc93
Summary: This removes the notion of being app limited from the pacer, rather letting it run its normal logic in this situation.
Reviewed By: yangchi
Differential Revision: D22466201
fbshipit-source-id: a90f87e552e8207420eea576d1e273671abe0671
Summary: 0 is now a valid packet number, so we should make these optional. In cases where they are needed to construct packet builder, it should be safe to use 0 as default since it's only used for computing `twiceDistance` in PacketNumber.cpp.
Reviewed By: yangchi
Differential Revision: D21948454
fbshipit-source-id: af9fdc3e28ff85f1594296c4d436f24685a0acd6
Summary:
Previously we track them since we thought we can get some additional
RTT samples. But these are bad RTT samples since peer can delays the acking of
pure acks. Now we no longer trust such RTT samples, there is no reason to keep
tracking pure ack packets.
Reviewed By: mjoras
Differential Revision: D18946081
fbshipit-source-id: 0a92d88e709edf8475d67791ba064c3e8b7f627a
Summary:
Currently we need the newRoundTrip boolean to be true twice to exit
ProbeRtt: once to set the probeRttRound_, and another time to check the
200ms ProbeRtt duration. This makes ProbeRtt really long: it takes more then
one RTT to make this boolean turn True twice; And when it's not true, we don't
check the 200ms ProbeRtt duration, which makes the duration longer than 200ms.
And all of these happen *after* inflight is drained to be a very low value.
This diff changes so that we only wait for one newRoundTrip = True during
ProbeRtt. Once we get to that point, any ack will check the 200ms ProbeRtt
duration.
Reviewed By: bschlinker
Differential Revision: D18899570
fbshipit-source-id: 9a3ff37ea4d237c15859b3dc4db00a761dc29f70
Summary:
Inside the bandwidth sampler, once AppLimited is set, it lasts until a
packet is sent later than the AppLimited setting time. Currently we only set
AppLimited once when we enter ProbeRtt. This leads to bandwidth sampler exiting
AppLimited state when BBR is still in ProbeRtt. This diff changes to so that
any Ack during ProbeRtt will refresh AppLimited in BandwidthSampler.
Note that the an Ack may exit ProbeRtt. Then BandwidthSampler will be in
AppLimited while BBR will exit ProbeRtt. I think this is the correct behavior of
AppLimited in Bbr BandwidthSampler: Any time it goes to AppLimited, it needs
to mark all packets sent during the next RTT as expericing app-limited
condition. (The so called "bubble" in
https://tools.ietf.org/html/draft-cheng-iccrg-delivery-rate-estimation-00)
Reviewed By: mjoras
Differential Revision: D18886880
fbshipit-source-id: c46279ddc60054dc4cba168c6b054bf2053c69df
Summary:
Currently when a rtt sample expires, a new sample will replace the
value and refresh the timestamp. And then we always use the refreshed timestamp
to check if rtt sample has expired. But because it just got refreshed, the
answer is always false, then we never probe rtt.
This diff saves the rtt expiration result into a variable when we replace the
rtt sample, then answers the minRttExpireed API by returning this value.
Reviewed By: mjoras
Differential Revision: D18727892
fbshipit-source-id: 3907f705841f37f55c46950ed4e6c24cef50de8f
Summary:
Cubic has a hack that sets a "connection emulation". With this, on
packet loss, it reduces cwnd by 10% instead of 20%. Then a even more aggresive
hack was added into BBR to make the cwnd on par with Cubic when there is packet
loss. This was used to facilitate BBR and Cubic tests when they were tested
side-by-side in the same network. After that, neither of them were sound ideas.
Reviewed By: mjoras
Differential Revision: D17053330
fbshipit-source-id: 17f74f58d7a036f85aaced10ff6d9646abae9e85
Summary:
Use the ack packet receive time as the reference time for BBR rtt
sampler calls.
Reviewed By: siyengar
Differential Revision: D17884047
fbshipit-source-id: 8052b464be6b1874408eadfb46e86d4624d8c226
Summary:
Add a token value into the pacer. This is so that when there is not
enough application data to consume all the burst size in current event loop, we
can accumulate the unused sending credit and use the later when new data comes
in. Each time a packet is sent, we consume 1 token. On pakcet loss, we clear
all tokens. Each time there is an ack and we refresh pacing rate, token
increases by calculated burst size. It is also increased when timer drifts
during writes. When there is available tokens, there is no delay of writing out
packets, and the burst size is current token amount.
Reviewed By: siyengar
Differential Revision: D17670053
fbshipit-source-id: 6abc3acce39e0ece90248c52c3d73935a9878e02
Summary:
When the transport is app-limited, there is no reason to pace the
transmission.
Reviewed By: mjoras
Differential Revision: D17118630
fbshipit-source-id: 8980f9ab6ebfba429aa7177a03e8341740716755
Summary:
Use the new Pacer interface in the transport where we currently
directly use CongestinoController interrace for paciner related APIs.
Reviewed By: mjoras
Differential Revision: D16918672
fbshipit-source-id: 410f72d567e71bdd3279e344f6e9abf5e132518e
Summary:
Second try of this diff. This time after the fix of uninitizlied
default constructed std::chrono::duration values in BBR and Copa.
Currently each conegstion controller maintains this value while
TransportSettings also has this value. But currently there is no way they are
in sync. The timer uses the value in TransportSettings. So the value maintained
by each congestion controller isn't used except for tracing, but that also make
tracing wrong.
Reviewed By: oesh
Differential Revision: D16985568
fbshipit-source-id: 5fbd9fee4deec5177b92c733a159e0ba9bfd2289
Summary:
Currently each conegstion controller maintains this value while
TransportSettings also has this value. But currently there is no way they are
in sync. The timer uses the value in TransportSettings. So the value maintained
by each congestion controller isn't used except for tracing, but that also make
tracing wrong.
Reviewed By: mjoras
Differential Revision: D16772744
fbshipit-source-id: 71800e5dc1f9fce8df4b1f72ce5aa5cfd15fbc89
Summary: Update qlog format to be more complete. Adding the summary section (with extra fields like title, description, etc). This diff is just to make the format more on par with Robin's schema.
Reviewed By: mjoras
Differential Revision: D16499808
fbshipit-source-id: 56cfbb95404f7e3c6638bffda18b53f7d83048a1
Summary: Add AppIdleUpdate to Quic, so it can be logged in qlog. Haven't added it to Copa or NewReno as it's currently not supported.
Reviewed By: yangchi
Differential Revision: D16232121
fbshipit-source-id: 6ffcbe87b6353fd1590a2a95db5d6e54b5a56e41
Summary: Added PacingMetricUpdate to Quic, so it can be logged as part of qlog.
Reviewed By: yangchi
Differential Revision: D16220227
fbshipit-source-id: 688c1dd04120677dcdb39d42ac9c4e41d6049898
Summary: Add metricUpdate event to Quic, so it can be logged as part of qlog.
Reviewed By: yangchi
Differential Revision: D16190166
fbshipit-source-id: 193b343f568fece4ca6bb43fa44e374a1df76c84