Add a new 'b2hi' connection option which limits the reduction of inflight_hi based on cwnd instead of target inflight.  protected by gfe2_reloadable_flag_quic_bbr2_limit_inflight_hi.

PiperOrigin-RevId: 313091939
Change-Id: Ic722bca8e08e42d7b3e3235e8d3c37c9a17ac836
diff --git a/quic/core/congestion_control/bbr2_misc.h b/quic/core/congestion_control/bbr2_misc.h
index e110a4c..ddef772 100644
--- a/quic/core/congestion_control/bbr2_misc.h
+++ b/quic/core/congestion_control/bbr2_misc.h
@@ -184,6 +184,9 @@
 
   // Can be enabled by connection option 'B2LO'.
   bool ignore_inflight_lo = false;
+
+  // Can be enabled by connection optoin 'B2HI'.
+  bool limit_inflight_hi_by_cwnd = false;
 };
 
 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 6fb7eee..f6a0938 100644
--- a/quic/core/congestion_control/bbr2_probe_bw.cc
+++ b/quic/core/congestion_control/bbr2_probe_bw.cc
@@ -198,9 +198,9 @@
       cycle_.is_sample_from_probing = false;
 
       if (!send_state.is_app_limited) {
-        QuicByteCount inflight_at_send = BytesInFlight(send_state);
+        const QuicByteCount inflight_at_send = BytesInFlight(send_state);
 
-        QuicByteCount inflight_target =
+        const QuicByteCount inflight_target =
             sender_->GetTargetBytesInflight() * (1.0 - Params().beta);
         if (inflight_at_send >= inflight_target) {
           // The new code does not change behavior.
@@ -209,7 +209,20 @@
           // The new code actually cuts inflight_hi slower than before.
           QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_gradually_in_effect);
         }
-        model_->set_inflight_hi(std::max(inflight_at_send, inflight_target));
+        if (Params().limit_inflight_hi_by_cwnd) {
+          const QuicByteCount cwnd_target =
+              sender_->GetCongestionWindow() * (1.0 - Params().beta);
+          if (inflight_at_send >= cwnd_target) {
+            // The new code does not change behavior.
+            QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_cwnd_noop);
+          } else {
+            // The new code actually cuts inflight_hi slower than before.
+            QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_cwnd_in_effect);
+          }
+          model_->set_inflight_hi(std::max(inflight_at_send, cwnd_target));
+        } else {
+          model_->set_inflight_hi(std::max(inflight_at_send, inflight_target));
+        }
       }
 
       QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
diff --git a/quic/core/congestion_control/bbr2_sender.cc b/quic/core/congestion_control/bbr2_sender.cc
index 8c3f7e5..7b891a6 100644
--- a/quic/core/congestion_control/bbr2_sender.cc
+++ b/quic/core/congestion_control/bbr2_sender.cc
@@ -127,6 +127,11 @@
     QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_ignore_inflight_lo);
     params_.ignore_inflight_lo = true;
   }
+  if (GetQuicReloadableFlag(quic_bbr2_limit_inflight_hi) &&
+      config.HasClientRequestedIndependentOption(kB2HI, perspective)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_limit_inflight_hi);
+    params_.limit_inflight_hi_by_cwnd = true;
+  }
 
   ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective));
 }
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h
index 172fd82..36ea6ca 100644
--- a/quic/core/crypto/crypto_protocol.h
+++ b/quic/core/crypto/crypto_protocol.h
@@ -125,6 +125,8 @@
                                                  // cwnd to be below BDP + ack
                                                  // height.
 const QuicTag kB2LO = TAG('B', '2', 'L', 'O');   // Ignore inflight_lo in BBR2
+const QuicTag kB2HI = TAG('B', '2', 'H', 'I');   // Limit inflight_hi reduction
+                                                 // based on CWND.
 const QuicTag kBSAO = TAG('B', 'S', 'A', 'O');   // Avoid Overestimation in
                                                  // Bandwidth Sampler with ack
                                                  // aggregation