In bbr2sender::adjustnetworkparameters, 1) do not inject a bandwidth sample to max bandwidth filter, and 2) update pacing rate after cwnd is updated. protected by --gfe2_reloadable_flag_quic_bbr2_improve_adjust_network_parameters. PiperOrigin-RevId: 321198508 Change-Id: I4366a2b159c48302eaf935784dfb7d093d322257
diff --git a/quic/core/congestion_control/bbr2_misc.cc b/quic/core/congestion_control/bbr2_misc.cc index cdd0cb5..153f63e 100644 --- a/quic/core/congestion_control/bbr2_misc.cc +++ b/quic/core/congestion_control/bbr2_misc.cc
@@ -213,7 +213,8 @@ void Bbr2NetworkModel::UpdateNetworkParameters(QuicBandwidth bandwidth, QuicTime::Delta rtt) { - if (!bandwidth.IsInfinite() && bandwidth > MaxBandwidth()) { + if (!improve_adjust_network_parameters_ && !bandwidth.IsInfinite() && + bandwidth > MaxBandwidth()) { max_bandwidth_filter_.Update(bandwidth); }
diff --git a/quic/core/congestion_control/bbr2_misc.h b/quic/core/congestion_control/bbr2_misc.h index cd89e6c..bf22bc5 100644 --- a/quic/core/congestion_control/bbr2_misc.h +++ b/quic/core/congestion_control/bbr2_misc.h
@@ -446,6 +446,10 @@ float pacing_gain() const { return pacing_gain_; } void set_pacing_gain(float pacing_gain) { pacing_gain_ = pacing_gain; } + bool improve_adjust_network_parameters() const { + return improve_adjust_network_parameters_; + } + private: const Bbr2Params& Params() const { return *params_; } const Bbr2Params* const params_; @@ -477,6 +481,9 @@ float cwnd_gain_; float pacing_gain_; + + const bool improve_adjust_network_parameters_ = + GetQuicReloadableFlag(quic_bbr2_improve_adjust_network_parameters); }; enum class Bbr2Mode : uint8_t {
diff --git a/quic/core/congestion_control/bbr2_sender.cc b/quic/core/congestion_control/bbr2_sender.cc index d1b3159..3f80f42 100644 --- a/quic/core/congestion_control/bbr2_sender.cc +++ b/quic/core/congestion_control/bbr2_sender.cc
@@ -167,14 +167,28 @@ if (mode_ == Bbr2Mode::STARTUP) { const QuicByteCount prior_cwnd = cwnd_; - // Normally UpdateCongestionWindow updates |cwnd_| towards the target by a - // small step per congestion event, by changing |cwnd_| to the bdp at here - // we are reducing the number of updates needed to arrive at the target. - cwnd_ = model_.BDP(model_.BandwidthEstimate()); - UpdateCongestionWindow(0); + if (model_.improve_adjust_network_parameters()) { + QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_improve_adjust_network_parameters); + QuicBandwidth effective_bandwidth = + std::max(params.bandwidth, model_.BandwidthEstimate()); + cwnd_ = cwnd_limits().ApplyLimits(model_.BDP(effective_bandwidth)); + } else { + // Normally UpdateCongestionWindow updates |cwnd_| towards the target by a + // small step per congestion event, by changing |cwnd_| to the bdp at here + // we are reducing the number of updates needed to arrive at the target. + cwnd_ = model_.BDP(model_.BandwidthEstimate()); + UpdateCongestionWindow(0); + } + if (!params.allow_cwnd_to_decrease) { cwnd_ = std::max(cwnd_, prior_cwnd); } + + if (model_.improve_adjust_network_parameters()) { + pacing_rate_ = std::max( + pacing_rate_, + QuicBandwidth::FromBytesAndTimeDelta(cwnd_, model_.MinRtt())); + } } }
diff --git a/quic/core/congestion_control/bbr2_simulator_test.cc b/quic/core/congestion_control/bbr2_simulator_test.cc index 205d356..8ea5217 100644 --- a/quic/core/congestion_control/bbr2_simulator_test.cc +++ b/quic/core/congestion_control/bbr2_simulator_test.cc
@@ -331,6 +331,10 @@ QuicConnection* sender_connection() { return sender_endpoint_.connection(); } + Bbr2Sender::DebugState sender_debug_state() const { + return sender_->ExportDebugState(); + } + const QuicConnectionStats& sender_connection_stats() { return sender_connection()->GetStats(); } @@ -990,14 +994,46 @@ EXPECT_FALSE(sender_->BandwidthEstimate().IsZero()); } +TEST_F(Bbr2DefaultTopologyTest, AdjustNetworkParameters) { + DefaultTopologyParams params; + CreateNetwork(params); + + QUIC_LOG(INFO) << "Initial cwnd: " << sender_debug_state().congestion_window + << "\nInitial pacing rate: " << sender_->PacingRate(0) + << "\nInitial bandwidth estimate: " + << sender_->BandwidthEstimate() + << "\nInitial rtt: " << sender_debug_state().min_rtt; + + sender_connection()->AdjustNetworkParameters( + SendAlgorithmInterface::NetworkParams(params.BottleneckBandwidth(), + params.RTT(), + /*allow_cwnd_to_decrease=*/false)); + + EXPECT_EQ(params.BDP(), sender_->ExportDebugState().congestion_window); + + if (GetQuicReloadableFlag(quic_bbr2_improve_adjust_network_parameters)) { + EXPECT_EQ(params.BottleneckBandwidth(), + sender_->PacingRate(/*bytes_in_flight=*/0)); + EXPECT_NE(params.BottleneckBandwidth(), sender_->BandwidthEstimate()); + } else { + EXPECT_EQ(params.BottleneckBandwidth(), sender_->BandwidthEstimate()); + } + + EXPECT_APPROX_EQ(params.RTT(), sender_->ExportDebugState().min_rtt, 0.01f); + + DriveOutOfStartup(params); +} + // All Bbr2MultiSenderTests uses the following network topology: // // Sender 0 (A Bbr2Sender) // | // | <-- local_links[0] // | -// | Sender N (1 <= N < kNumLocalLinks) (May or may not be a -// Bbr2Sender) | | | | <-- local_links[N] | | +// | Sender N (1 <= N < kNumLocalLinks) (May or may not be a Bbr2Sender) +// | | +// | | <-- local_links[N] +// | | // Network switch // * <-- the bottleneck queue in the direction // | of the receiver