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);