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