gfe-relnote: In QUIC BBRv2's PROBE_BW mode, make sure the cwnd upper bound is at least BDP + AckHeight. Protected by --gfe2_reloadable_flag_quic_bbr2_avoid_too_low_probe_bw_cwnd.
Connection option 'B2CL' is introduced to hold back to the original behavior.
PiperOrigin-RevId: 306901798
Change-Id: Idc47368fd380419fce1f92f36a5a2ad3e1c879f3
diff --git a/quic/core/congestion_control/bbr2_misc.h b/quic/core/congestion_control/bbr2_misc.h
index 0c72131..2315e63 100644
--- a/quic/core/congestion_control/bbr2_misc.h
+++ b/quic/core/congestion_control/bbr2_misc.h
@@ -177,6 +177,10 @@
// Can be disabled by connection option 'B2RP'.
bool avoid_unnecessary_probe_rtt = true;
+
+ // Can be disabled by connection option 'B2CL'.
+ bool avoid_too_low_probe_bw_cwnd =
+ GetQuicReloadableFlag(quic_bbr2_avoid_too_low_probe_bw_cwnd);
};
class QUIC_EXPORT_PRIVATE RoundTripCounter {
diff --git a/quic/core/congestion_control/bbr2_probe_bw.cc b/quic/core/congestion_control/bbr2_probe_bw.cc
index 1a7a719..6fb7eee 100644
--- a/quic/core/congestion_control/bbr2_probe_bw.cc
+++ b/quic/core/congestion_control/bbr2_probe_bw.cc
@@ -79,12 +79,36 @@
}
Limits<QuicByteCount> Bbr2ProbeBwMode::GetCwndLimits() const {
- if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
+ if (!GetQuicReloadableFlag(quic_bbr2_avoid_too_low_probe_bw_cwnd)) {
+ if (cycle_.phase == CyclePhase::PROBE_CRUISE) {
+ return NoGreaterThan(
+ std::min(model_->inflight_lo(), model_->inflight_hi_with_headroom()));
+ }
+
return NoGreaterThan(
- std::min(model_->inflight_lo(), model_->inflight_hi_with_headroom()));
+ std::min(model_->inflight_lo(), model_->inflight_hi()));
}
- return NoGreaterThan(std::min(model_->inflight_lo(), model_->inflight_hi()));
+ QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_avoid_too_low_probe_bw_cwnd);
+
+ QuicByteCount upper_limit =
+ std::min(model_->inflight_lo(), cycle_.phase == CyclePhase::PROBE_CRUISE
+ ? model_->inflight_hi_with_headroom()
+ : model_->inflight_hi());
+
+ if (Params().avoid_too_low_probe_bw_cwnd) {
+ // Ensure upper_limit is at least BDP + AckHeight.
+ QuicByteCount bdp_with_ack_height =
+ model_->BDP(model_->MaxBandwidth()) + model_->MaxAckHeight();
+ if (upper_limit < bdp_with_ack_height) {
+ QUIC_DVLOG(3) << sender_ << " Rasing upper_limit from " << upper_limit
+ << " to " << bdp_with_ack_height;
+ QUIC_CODE_COUNT(quic_bbr2_avoid_too_low_probe_bw_cwnd_in_effect);
+ upper_limit = bdp_with_ack_height;
+ }
+ }
+
+ return NoGreaterThan(upper_limit);
}
bool Bbr2ProbeBwMode::IsProbingForBandwidth() const {
diff --git a/quic/core/congestion_control/bbr2_sender.cc b/quic/core/congestion_control/bbr2_sender.cc
index ff5f74f..a367a56 100644
--- a/quic/core/congestion_control/bbr2_sender.cc
+++ b/quic/core/congestion_control/bbr2_sender.cc
@@ -115,6 +115,10 @@
params_.startup_cwnd_gain = 2;
params_.drain_cwnd_gain = 2;
}
+ if (GetQuicReloadableFlag(quic_bbr2_avoid_too_low_probe_bw_cwnd) &&
+ config.HasClientRequestedIndependentOption(kB2CL, perspective)) {
+ params_.avoid_too_low_probe_bw_cwnd = false;
+ }
}
Limits<QuicByteCount> Bbr2Sender::GetCwndLimitsByMode() const {
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h
index aaa2d6f..9a5eaf2 100644
--- a/quic/core/crypto/crypto_protocol.h
+++ b/quic/core/crypto/crypto_protocol.h
@@ -121,6 +121,9 @@
// height to queueing threshold
const QuicTag kB2RP = TAG('B', '2', 'R', 'P'); // For BBRv2, run PROBE_RTT on
// the regular schedule
+const QuicTag kB2CL = TAG('B', '2', 'C', 'L'); // For BBRv2, allow PROBE_BW
+ // cwnd to be below BDP + ack
+ // height.
const QuicTag kBSAO = TAG('B', 'S', 'A', 'O'); // Avoid Overestimation in
// Bandwidth Sampler with ack
// aggregation