gfe-relnote: Allow GFE to perform initial cwnd up and down experiment. Protected by --gfe2_reloadable_flag_quic_gfe_selected_initial_cwnd_experiments. The minimum cwnd is 10, and the default enabled up and down experiment is 25%. PiperOrigin-RevId: 248124804 Change-Id: Ie21685f8e35946eaa499dab935b154b928af7318
diff --git a/quic/core/congestion_control/bbr_sender.cc b/quic/core/congestion_control/bbr_sender.cc index 7d7258f..3369876 100644 --- a/quic/core/congestion_control/bbr_sender.cc +++ b/quic/core/congestion_control/bbr_sender.cc
@@ -340,7 +340,8 @@ } void BbrSender::AdjustNetworkParameters(QuicBandwidth bandwidth, - QuicTime::Delta rtt) { + QuicTime::Delta rtt, + bool allow_cwnd_to_decrease) { if (!bandwidth.IsZero()) { max_bandwidth_.Update(bandwidth, round_trip_count_); } @@ -350,8 +351,13 @@ if (GetQuicReloadableFlag(quic_fix_bbr_cwnd_in_bandwidth_resumption) && mode_ == STARTUP) { const QuicByteCount new_cwnd = - std::min(kMaxInitialCongestionWindow * kDefaultTCPMSS, - bandwidth * rtt_stats_->SmoothedOrInitialRtt()); + std::max(kMinInitialCongestionWindow * kDefaultTCPMSS, + std::min(kMaxInitialCongestionWindow * kDefaultTCPMSS, + bandwidth * rtt_stats_->SmoothedOrInitialRtt())); + // Decreases cwnd gain and pacing gain. Please note, if pacing_rate_ has + // been calculated, it cannot decrease in STARTUP phase. + set_high_gain(kDerivedHighCWNDGain); + set_high_cwnd_gain(kDerivedHighCWNDGain); if (new_cwnd > congestion_window_) { QUIC_RELOADABLE_FLAG_COUNT_N(quic_fix_bbr_cwnd_in_bandwidth_resumption, 1, 2); @@ -359,11 +365,13 @@ QUIC_RELOADABLE_FLAG_COUNT_N(quic_fix_bbr_cwnd_in_bandwidth_resumption, 2, 2); } - // Decreases cwnd gain and pacing gain. Please note, if pacing_rate_ has - // been calculated, it cannot decrease in STARTUP phase. - set_high_gain(kDerivedHighCWNDGain); - set_high_cwnd_gain(kDerivedHighCWNDGain); - congestion_window_ = std::max(new_cwnd, congestion_window_); + if (bandwidth.IsZero() || + (new_cwnd < congestion_window_ && !allow_cwnd_to_decrease)) { + // Ignore bad bandwidth samples. Only decrease cwnd if + // allow_cwnd_to_decrease is true. + return; + } + congestion_window_ = new_cwnd; } }
diff --git a/quic/core/congestion_control/bbr_sender.h b/quic/core/congestion_control/bbr_sender.h index 843764b..a49a5ef 100644 --- a/quic/core/congestion_control/bbr_sender.h +++ b/quic/core/congestion_control/bbr_sender.h
@@ -108,7 +108,8 @@ Perspective perspective) override; void AdjustNetworkParameters(QuicBandwidth bandwidth, - QuicTime::Delta rtt) override; + QuicTime::Delta rtt, + bool allow_cwnd_to_decrease) override; void SetNumEmulatedConnections(int num_connections) override {} void SetInitialCongestionWindowInPackets( QuicPacketCount congestion_window) override;
diff --git a/quic/core/congestion_control/bbr_sender_test.cc b/quic/core/congestion_control/bbr_sender_test.cc index 1f4c082..be4f291 100644 --- a/quic/core/congestion_control/bbr_sender_test.cc +++ b/quic/core/congestion_control/bbr_sender_test.cc
@@ -1292,7 +1292,7 @@ CreateDefaultSetup(); bbr_sender_.connection()->AdjustNetworkParameters(kTestLinkBandwidth, - kTestRtt); + kTestRtt, false); EXPECT_EQ(kTestLinkBandwidth, sender_->ExportDebugState().max_bandwidth); EXPECT_EQ(kTestLinkBandwidth, sender_->BandwidthEstimate()); EXPECT_APPROX_EQ(kTestRtt, sender_->ExportDebugState().min_rtt, 0.01f);
diff --git a/quic/core/congestion_control/send_algorithm_interface.h b/quic/core/congestion_control/send_algorithm_interface.h index 620b23f..9db67b5 100644 --- a/quic/core/congestion_control/send_algorithm_interface.h +++ b/quic/core/congestion_control/send_algorithm_interface.h
@@ -120,7 +120,8 @@ // measurement or prediction. Either |bandwidth| or |rtt| may be zero if no // sample is available. virtual void AdjustNetworkParameters(QuicBandwidth bandwidth, - QuicTime::Delta rtt) = 0; + QuicTime::Delta rtt, + bool allow_cwnd_to_decrease) = 0; // Retrieves debugging information about the current state of the // send algorithm.
diff --git a/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/quic/core/congestion_control/tcp_cubic_sender_bytes.cc index fde8d75..7cbf332 100644 --- a/quic/core/congestion_control/tcp_cubic_sender_bytes.cc +++ b/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
@@ -105,8 +105,10 @@ } } -void TcpCubicSenderBytes::AdjustNetworkParameters(QuicBandwidth bandwidth, - QuicTime::Delta rtt) { +void TcpCubicSenderBytes::AdjustNetworkParameters( + QuicBandwidth bandwidth, + QuicTime::Delta rtt, + bool /*allow_cwnd_to_decrease*/) { if (bandwidth.IsZero() || rtt.IsZero()) { return; }
diff --git a/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/quic/core/congestion_control/tcp_cubic_sender_bytes.h index a437426..dd8be12 100644 --- a/quic/core/congestion_control/tcp_cubic_sender_bytes.h +++ b/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -47,7 +47,8 @@ void SetFromConfig(const QuicConfig& config, Perspective perspective) override; void AdjustNetworkParameters(QuicBandwidth bandwidth, - QuicTime::Delta rtt) override; + QuicTime::Delta rtt, + bool allow_cwnd_to_decrease) override; void SetNumEmulatedConnections(int num_connections) override; void SetInitialCongestionWindowInPackets( QuicPacketCount congestion_window) override;
diff --git a/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc b/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc index 5eb6226..32451a5 100644 --- a/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc +++ b/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
@@ -677,11 +677,11 @@ const QuicBandwidth kBandwidthEstimate = QuicBandwidth::FromBytesPerSecond(kNumberOfPackets * kDefaultTCPMSS); const QuicTime::Delta kRttEstimate = QuicTime::Delta::FromSeconds(1); - sender_->AdjustNetworkParameters(kBandwidthEstimate, kRttEstimate); + sender_->AdjustNetworkParameters(kBandwidthEstimate, kRttEstimate, false); EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow()); // Resume with an illegal value of 0 and verify the server ignores it. - sender_->AdjustNetworkParameters(QuicBandwidth::Zero(), kRttEstimate); + sender_->AdjustNetworkParameters(QuicBandwidth::Zero(), kRttEstimate, false); EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow()); // Resumed CWND is limited to be in a sensible range. @@ -689,7 +689,7 @@ QuicBandwidth::FromBytesPerSecond((kMaxCongestionWindowPackets + 1) * kDefaultTCPMSS); sender_->AdjustNetworkParameters(kUnreasonableBandwidth, - QuicTime::Delta::FromSeconds(1)); + QuicTime::Delta::FromSeconds(1), false); EXPECT_EQ(kMaxCongestionWindowPackets * kDefaultTCPMSS, sender_->GetCongestionWindow()); }
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h index 6873e0f..a3abb33 100644 --- a/quic/core/crypto/crypto_protocol.h +++ b/quic/core/crypto/crypto_protocol.h
@@ -192,6 +192,7 @@ const QuicTag kBWS2 = TAG('B', 'W', 'S', '2'); // Server bw resumption v2. const QuicTag kBWS3 = TAG('B', 'W', 'S', '3'); // QUIC Initial CWND - Control. const QuicTag kBWS4 = TAG('B', 'W', 'S', '4'); // QUIC Initial CWND - Enabled. +const QuicTag kBWS5 = TAG('B', 'W', 'S', '5'); // QUIC Initial CWND up and down // Enable path MTU discovery experiment. const QuicTag kMTUH = TAG('M', 'T', 'U', 'H'); // High-target MTU discovery.
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc index eea8618..6798f63 100644 --- a/quic/core/quic_connection.cc +++ b/quic/core/quic_connection.cc
@@ -548,8 +548,10 @@ } void QuicConnection::AdjustNetworkParameters(QuicBandwidth bandwidth, - QuicTime::Delta rtt) { - sent_packet_manager_.AdjustNetworkParameters(bandwidth, rtt); + QuicTime::Delta rtt, + bool allow_cwnd_to_decrease) { + sent_packet_manager_.AdjustNetworkParameters(bandwidth, rtt, + allow_cwnd_to_decrease); } QuicBandwidth QuicConnection::MaxPacingRate() const {
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h index ea12d71..47816de 100644 --- a/quic/core/quic_connection.h +++ b/quic/core/quic_connection.h
@@ -374,7 +374,9 @@ // Allows the client to adjust network parameters based on external // information. - void AdjustNetworkParameters(QuicBandwidth bandwidth, QuicTime::Delta rtt); + void AdjustNetworkParameters(QuicBandwidth bandwidth, + QuicTime::Delta rtt, + bool allow_cwnd_to_decrease); // Returns the max pacing rate for the connection. virtual QuicBandwidth MaxPacingRate() const;
diff --git a/quic/core/quic_constants.h b/quic/core/quic_constants.h index 939f746..caac2c7 100644 --- a/quic/core/quic_constants.h +++ b/quic/core/quic_constants.h
@@ -61,6 +61,9 @@ // Do not allow initial congestion window to be greater than 200 packets. const QuicPacketCount kMaxInitialCongestionWindow = 200; +// Do not allow initial congestion window to be smaller than 10 packets. +const QuicPacketCount kMinInitialCongestionWindow = 10; + // Minimum size of initial flow control window, for both stream and session. // This is only enforced when version.AllowsLowFlowControlLimits() is false. const uint32_t kMinimumFlowControlSendWindow = 16 * 1024; // 16 KB
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc index 061ebac..202a8d8 100644 --- a/quic/core/quic_sent_packet_manager.cc +++ b/quic/core/quic_sent_packet_manager.cc
@@ -264,11 +264,13 @@ : cached_network_params.bandwidth_estimate_bytes_per_second()); QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms()); - AdjustNetworkParameters(bandwidth, rtt); + AdjustNetworkParameters(bandwidth, rtt, /*allow_cwnd_to_decrease=*/false); } -void QuicSentPacketManager::AdjustNetworkParameters(QuicBandwidth bandwidth, - QuicTime::Delta rtt) { +void QuicSentPacketManager::AdjustNetworkParameters( + QuicBandwidth bandwidth, + QuicTime::Delta rtt, + bool allow_cwnd_to_decrease) { if (!rtt.IsZero()) { SetInitialRtt(rtt); } @@ -277,7 +279,8 @@ QUIC_RELOADABLE_FLAG_COUNT(quic_conservative_bursts); pacing_sender_.SetBurstTokens(kConservativeUnpacedBurst); } - send_algorithm_->AdjustNetworkParameters(bandwidth, rtt); + send_algorithm_->AdjustNetworkParameters(bandwidth, rtt, + allow_cwnd_to_decrease); if (debug_delegate_ != nullptr) { debug_delegate_->OnAdjustNetworkParameters( bandwidth, rtt.IsZero() ? rtt_stats_.SmoothedOrInitialRtt() : rtt,
diff --git a/quic/core/quic_sent_packet_manager.h b/quic/core/quic_sent_packet_manager.h index 04fab58..3df874d 100644 --- a/quic/core/quic_sent_packet_manager.h +++ b/quic/core/quic_sent_packet_manager.h
@@ -130,7 +130,9 @@ // Notify the sent packet manager of an external network measurement or // prediction for either |bandwidth| or |rtt|; either can be empty. - void AdjustNetworkParameters(QuicBandwidth bandwidth, QuicTime::Delta rtt); + void AdjustNetworkParameters(QuicBandwidth bandwidth, + QuicTime::Delta rtt, + bool allow_cwnd_to_decrease); // Retransmits the oldest pending packet there is still a tail loss probe // pending. Invoked after OnRetransmissionTimeout.
diff --git a/quic/core/quic_sent_packet_manager_test.cc b/quic/core/quic_sent_packet_manager_test.cc index 6a641fe..c508cca 100644 --- a/quic/core/quic_sent_packet_manager_test.cc +++ b/quic/core/quic_sent_packet_manager_test.cc
@@ -2371,7 +2371,7 @@ cached_network_params.set_min_rtt_ms(kRtt.ToMilliseconds()); EXPECT_CALL(*send_algorithm_, - AdjustNetworkParameters(QuicBandwidth::Zero(), kRtt)); + AdjustNetworkParameters(QuicBandwidth::Zero(), kRtt, false)); EXPECT_CALL(*send_algorithm_, GetCongestionWindow()) .Times(testing::AnyNumber()); manager_.ResumeConnectionState(cached_network_params, false);
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h index 643291e..f64ddbd 100644 --- a/quic/test_tools/quic_test_utils.h +++ b/quic/test_tools/quic_test_utils.h
@@ -917,7 +917,8 @@ MOCK_CONST_METHOD0(ShouldSendProbingPacket, bool()); MOCK_CONST_METHOD0(GetSlowStartThreshold, QuicByteCount()); MOCK_CONST_METHOD0(GetCongestionControlType, CongestionControlType()); - MOCK_METHOD2(AdjustNetworkParameters, void(QuicBandwidth, QuicTime::Delta)); + MOCK_METHOD3(AdjustNetworkParameters, + void(QuicBandwidth, QuicTime::Delta, bool)); MOCK_METHOD1(OnApplicationLimited, void(QuicByteCount)); };