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