gfe-relnote: (n/a) Add 2 connection options for BBRv2 to disable 1) adding ack height in queueing threshold, and 2) avoiding unnecessary PROBE_RTTs. Not protected, just more switches for already existing behaviors.
PiperOrigin-RevId: 301176881
Change-Id: Idb6108aec370ea3aa7c8db5fafe2f3e57b507e8d
diff --git a/quic/core/congestion_control/bbr2_misc.h b/quic/core/congestion_control/bbr2_misc.h
index d98bb1a..b8ba702 100644
--- a/quic/core/congestion_control/bbr2_misc.h
+++ b/quic/core/congestion_control/bbr2_misc.h
@@ -161,6 +161,22 @@
float beta = 0.3;
Limits<QuicByteCount> cwnd_limits;
+
+ /*
+ * Experimental flags from QuicConfig.
+ */
+
+ // Indicates app-limited calls should be ignored as long as there's
+ // enough data inflight to see more bandwidth when necessary.
+ bool flexible_app_limited = false;
+
+ // Can be disabled by connection option 'B2NA'.
+ bool add_ack_height_to_queueing_threshold =
+ GetQuicReloadableFlag(quic_bbr2_add_ack_height_to_queueing_threshold);
+
+ // Can be disabled by connection option 'B2RP'.
+ bool avoid_unnecessary_probe_rtt =
+ GetQuicReloadableFlag(quic_bbr2_avoid_unnecessary_probe_rtt);
};
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 1002983..1a7a719 100644
--- a/quic/core/congestion_control/bbr2_probe_bw.cc
+++ b/quic/core/congestion_control/bbr2_probe_bw.cc
@@ -393,7 +393,7 @@
} else if (cycle_.rounds_in_phase > 0) {
const QuicByteCount bdp = model_->BDP(model_->MaxBandwidth());
QuicByteCount queuing_threshold_extra_bytes = 2 * kDefaultTCPMSS;
- if (add_ack_height_to_queueing_threshold_) {
+ if (Params().add_ack_height_to_queueing_threshold) {
QUIC_RELOADABLE_FLAG_COUNT(
quic_bbr2_add_ack_height_to_queueing_threshold);
queuing_threshold_extra_bytes += model_->MaxAckHeight();
diff --git a/quic/core/congestion_control/bbr2_probe_bw.h b/quic/core/congestion_control/bbr2_probe_bw.h
index e42ab30..5c0224f 100644
--- a/quic/core/congestion_control/bbr2_probe_bw.h
+++ b/quic/core/congestion_control/bbr2_probe_bw.h
@@ -126,9 +126,6 @@
bool last_cycle_probed_too_high_;
bool last_cycle_stopped_risky_probe_;
-
- const bool add_ack_height_to_queueing_threshold_ =
- GetQuicReloadableFlag(quic_bbr2_add_ack_height_to_queueing_threshold);
};
QUIC_EXPORT_PRIVATE std::ostream& operator<<(
diff --git a/quic/core/congestion_control/bbr2_sender.cc b/quic/core/congestion_control/bbr2_sender.cc
index 5b6f6e8..c975aec 100644
--- a/quic/core/congestion_control/bbr2_sender.cc
+++ b/quic/core/congestion_control/bbr2_sender.cc
@@ -81,7 +81,6 @@
drain_(this, &model_),
probe_bw_(this, &model_),
probe_rtt_(this, &model_),
- flexible_app_limited_(false),
last_sample_is_app_limited_(false) {
QUIC_DVLOG(2) << this << " Initializing Bbr2Sender. mode:" << mode_
<< ", PacingRate:" << pacing_rate_ << ", Cwnd:" << cwnd_
@@ -92,7 +91,7 @@
void Bbr2Sender::SetFromConfig(const QuicConfig& config,
Perspective perspective) {
if (config.HasClientRequestedIndependentOption(kBBR9, perspective)) {
- flexible_app_limited_ = true;
+ params_.flexible_app_limited = true;
}
if (GetQuicReloadableFlag(
quic_avoid_overestimate_bandwidth_with_aggregation) &&
@@ -101,6 +100,12 @@
quic_avoid_overestimate_bandwidth_with_aggregation, 4, 4);
model_.EnableOverestimateAvoidance();
}
+ if (config.HasClientRequestedIndependentOption(kB2NA, perspective)) {
+ params_.add_ack_height_to_queueing_threshold = false;
+ }
+ if (config.HasClientRequestedIndependentOption(kB2RP, perspective)) {
+ params_.avoid_unnecessary_probe_rtt = false;
+ }
}
Limits<QuicByteCount> Bbr2Sender::GetCwndLimitsByMode() const {
@@ -120,7 +125,7 @@
}
const Limits<QuicByteCount>& Bbr2Sender::cwnd_limits() const {
- return params_.cwnd_limits;
+ return params().cwnd_limits;
}
void Bbr2Sender::AdjustNetworkParameters(const NetworkParams& params) {
@@ -197,7 +202,8 @@
model_.OnCongestionEventFinish(unacked_packets_->GetLeastUnacked(),
congestion_event);
last_sample_is_app_limited_ = congestion_event.last_sample_is_app_limited;
- if (avoid_unnecessary_probe_rtt_ && congestion_event.bytes_in_flight == 0) {
+ if (congestion_event.bytes_in_flight == 0 &&
+ params().avoid_unnecessary_probe_rtt) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_avoid_unnecessary_probe_rtt, 2, 2);
OnEnterQuiescence(event_time);
}
@@ -292,7 +298,7 @@
<< ", total_acked:" << model_.total_bytes_acked()
<< ", total_lost:" << model_.total_bytes_lost() << " @ "
<< sent_time;
- if (avoid_unnecessary_probe_rtt_ && bytes_in_flight == 0) {
+ if (bytes_in_flight == 0 && params().avoid_unnecessary_probe_rtt) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_avoid_unnecessary_probe_rtt, 1, 2);
OnExitQuiescence(sent_time);
}
@@ -322,7 +328,7 @@
if (bytes_in_flight >= GetCongestionWindow()) {
return;
}
- if (flexible_app_limited_ && IsPipeSufficientlyFull()) {
+ if (params().flexible_app_limited && IsPipeSufficientlyFull()) {
return;
}
@@ -367,12 +373,12 @@
// TODO(b/77975811): If the pipe is highly under-utilized, consider not
// sending a probing transmission, because the extra bandwidth is not needed.
// If flexible_app_limited is enabled, check if the pipe is sufficiently full.
- if (flexible_app_limited_) {
+ if (params().flexible_app_limited) {
const bool is_pipe_sufficiently_full = IsPipeSufficientlyFull();
QUIC_DVLOG(3) << this << " CWND: " << GetCongestionWindow()
<< ", inflight: " << unacked_packets_->bytes_in_flight()
<< ", pacing_rate: " << PacingRate(0)
- << ", flexible_app_limited_: true, ShouldSendProbingPacket: "
+ << ", flexible_app_limited: true, ShouldSendProbingPacket: "
<< !is_pipe_sufficiently_full;
return !is_pipe_sufficiently_full;
} else {
diff --git a/quic/core/congestion_control/bbr2_sender.h b/quic/core/congestion_control/bbr2_sender.h
index e63b2bd..f865e27 100644
--- a/quic/core/congestion_control/bbr2_sender.h
+++ b/quic/core/congestion_control/bbr2_sender.h
@@ -162,6 +162,8 @@
// Cwnd limits imposed by caller.
const Limits<QuicByteCount>& cwnd_limits() const;
+ const Bbr2Params& params() const { return params_; }
+
Bbr2Mode mode_;
const RttStats* const rtt_stats_;
@@ -169,7 +171,9 @@
QuicRandom* random_;
QuicConnectionStats* connection_stats_;
- const Bbr2Params params_;
+ // Don't use it directly outside of SetFromConfig. Instead, use params() to
+ // get read-only access.
+ Bbr2Params params_;
Bbr2NetworkModel model_;
@@ -186,16 +190,9 @@
Bbr2ProbeBwMode probe_bw_;
Bbr2ProbeRttMode probe_rtt_;
- // Indicates app-limited calls should be ignored as long as there's
- // enough data inflight to see more bandwidth when necessary.
- bool flexible_app_limited_;
-
// Debug only.
bool last_sample_is_app_limited_;
- const bool avoid_unnecessary_probe_rtt_ =
- GetQuicReloadableFlag(quic_bbr2_avoid_unnecessary_probe_rtt);
-
friend class Bbr2StartupMode;
friend class Bbr2DrainMode;
friend class Bbr2ProbeBwMode;
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h
index 7f8d959..b9ddae9 100644
--- a/quic/core/crypto/crypto_protocol.h
+++ b/quic/core/crypto/crypto_protocol.h
@@ -121,6 +121,10 @@
const QuicTag kIW20 = TAG('I', 'W', '2', '0'); // Force ICWND to 20
const QuicTag kIW50 = TAG('I', 'W', '5', '0'); // Force ICWND to 50
const QuicTag kB2ON = TAG('B', '2', 'O', 'N'); // Enable BBRv2
+const QuicTag kB2NA = TAG('B', '2', 'N', 'A'); // For BBRv2, do not add ack
+ // height to queueing threshold
+const QuicTag kB2RP = TAG('B', '2', 'R', 'P'); // For BBRv2, run PROBE_RTT on
+ // the regular schedule
const QuicTag kBSAO = TAG('B', 'S', 'A', 'O'); // Avoid Overestimation in
// Bandwidth Sampler with ack
// aggregation