No public description PiperOrigin-RevId: 675563943
diff --git a/quiche/quic/core/congestion_control/bbr2_misc.cc b/quiche/quic/core/congestion_control/bbr2_misc.cc index 1584d02..00879b9 100644 --- a/quiche/quic/core/congestion_control/bbr2_misc.cc +++ b/quiche/quic/core/congestion_control/bbr2_misc.cc
@@ -226,6 +226,16 @@ std::max(bandwidth_latest_, bandwidth_lo_ * (1.0 - Params().beta)); QUIC_DVLOG(3) << "bandwidth_lo_ updated to " << bandwidth_lo_ << ", bandwidth_latest_ is " << bandwidth_latest_; + if (enable_app_driven_pacing_) { + // In this mode, we forcibly cap bandwidth_lo_ at the application driven + // pacing rate when congestion_event.bytes_lost > 0. The idea is to + // avoid going over what the application needs at the earliest signs of + // network congestion. + bandwidth_lo_ = std::min(application_bandwidth_target_, bandwidth_lo_); + QUIC_DVLOG(3) << "bandwidth_lo_ updated to " << bandwidth_lo_ + << "after applying application_driven_pacing at " + << application_bandwidth_target_; + } if (Params().ignore_inflight_lo) { return;
diff --git a/quiche/quic/core/congestion_control/bbr2_misc.h b/quiche/quic/core/congestion_control/bbr2_misc.h index 6dbe904..09654ad 100644 --- a/quiche/quic/core/congestion_control/bbr2_misc.h +++ b/quiche/quic/core/congestion_control/bbr2_misc.h
@@ -438,6 +438,14 @@ bool MaybeExpireMinRtt(const Bbr2CongestionEvent& congestion_event); + void SetEnableAppDrivenPacing(bool value) { + enable_app_driven_pacing_ = value; + } + + void SetApplicationBandwidthTarget(QuicBandwidth bandwidth) { + application_bandwidth_target_ = bandwidth; + } + QuicBandwidth BandwidthEstimate() const { return std::min(MaxBandwidth(), bandwidth_lo_); } @@ -576,6 +584,9 @@ QuicBandwidth bandwidth_latest_ = QuicBandwidth::Zero(); // Max bandwidth of recent rounds. Updated once per round. QuicBandwidth bandwidth_lo_ = bandwidth_lo_default(); + // Target bandwidth from applications for app-driven pacing. Only used when + // enable_app_driven_pacing_ is true. + QuicBandwidth application_bandwidth_target_ = QuicBandwidth::Infinite(); // bandwidth_lo_ at the beginning of a round with loss. Only used when the // bw_lo_mode is non-default. QuicBandwidth prior_bandwidth_lo_ = QuicBandwidth::Zero(); @@ -593,6 +604,9 @@ // epoch. bool cwnd_limited_before_aggregation_epoch_ = false; + // Enable application-driven pacing. + bool enable_app_driven_pacing_ = false; + // STARTUP-centric fields which experimentally used by PROBE_UP. bool full_bandwidth_reached_ = false; QuicBandwidth full_bandwidth_baseline_ = QuicBandwidth::Zero();
diff --git a/quiche/quic/core/congestion_control/bbr2_sender.cc b/quiche/quic/core/congestion_control/bbr2_sender.cc index 3e4ecb3..6118546 100644 --- a/quiche/quic/core/congestion_control/bbr2_sender.cc +++ b/quiche/quic/core/congestion_control/bbr2_sender.cc
@@ -194,6 +194,9 @@ if (ContainsQuicTag(connection_options, kBBRB)) { model_.SetLimitMaxAckHeightTrackerBySendRate(true); } + if (ContainsQuicTag(connection_options, kADP0)) { + model_.SetEnableAppDrivenPacing(true); + } if (ContainsQuicTag(connection_options, kB206)) { params_.startup_full_loss_count = params_.probe_bw_full_loss_count; } @@ -273,6 +276,11 @@ } } +void Bbr2Sender::SetApplicationDrivenPacingRate( + QuicBandwidth application_bandwidth_target) { + model_.SetApplicationBandwidthTarget(application_bandwidth_target); +} + void Bbr2Sender::OnCongestionEvent(bool /*rtt_updated*/, QuicByteCount prior_in_flight, QuicTime event_time,
diff --git a/quiche/quic/core/congestion_control/bbr2_sender.h b/quiche/quic/core/congestion_control/bbr2_sender.h index 636d340..9338414 100644 --- a/quiche/quic/core/congestion_control/bbr2_sender.h +++ b/quiche/quic/core/congestion_control/bbr2_sender.h
@@ -52,6 +52,9 @@ void SetInitialCongestionWindowInPackets( QuicPacketCount congestion_window) override; + void SetApplicationDrivenPacingRate( + QuicBandwidth application_bandwidth_target) override; + void OnCongestionEvent(bool rtt_updated, QuicByteCount prior_in_flight, QuicTime event_time, const AckedPacketVector& acked_packets,
diff --git a/quiche/quic/core/congestion_control/bbr_sender.h b/quiche/quic/core/congestion_control/bbr_sender.h index 625394a..132908f 100644 --- a/quiche/quic/core/congestion_control/bbr_sender.h +++ b/quiche/quic/core/congestion_control/bbr_sender.h
@@ -108,6 +108,8 @@ void AdjustNetworkParameters(const NetworkParams& params) override; void SetInitialCongestionWindowInPackets( QuicPacketCount congestion_window) override; + void SetApplicationDrivenPacingRate( + QuicBandwidth /*application_bandwidth_target*/) override {} void OnCongestionEvent(bool rtt_updated, QuicByteCount prior_in_flight, QuicTime event_time, const AckedPacketVector& acked_packets,
diff --git a/quiche/quic/core/congestion_control/send_algorithm_interface.h b/quiche/quic/core/congestion_control/send_algorithm_interface.h index 95cd8f0..e5f5588 100644 --- a/quiche/quic/core/congestion_control/send_algorithm_interface.h +++ b/quiche/quic/core/congestion_control/send_algorithm_interface.h
@@ -74,6 +74,11 @@ // if called after the initial congestion window is no longer relevant. virtual void SetInitialCongestionWindowInPackets(QuicPacketCount packets) = 0; + // [Experimental] Sets the application driven pacing rate. This is only used + // by an experimental feature for bbr2_sender. + virtual void SetApplicationDrivenPacingRate( + QuicBandwidth application_bandwidth_target) = 0; + // Indicates an update to the congestion state, caused either by an incoming // ack or loss event timeout. |rtt_updated| indicates whether a new // latest_rtt sample has been taken, |prior_in_flight| the bytes in flight
diff --git a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h index de003f7..b62a808 100644 --- a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h +++ b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -50,6 +50,8 @@ void SetNumEmulatedConnections(int num_connections); void SetInitialCongestionWindowInPackets( QuicPacketCount congestion_window) override; + void SetApplicationDrivenPacingRate( + QuicBandwidth /*application_bandwidth_target*/) override {} void OnConnectionMigration() override; void OnCongestionEvent(bool rtt_updated, QuicByteCount prior_in_flight, QuicTime event_time,
diff --git a/quiche/quic/core/crypto/crypto_protocol.h b/quiche/quic/core/crypto/crypto_protocol.h index e05f869..118de64 100644 --- a/quiche/quic/core/crypto/crypto_protocol.h +++ b/quiche/quic/core/crypto/crypto_protocol.h
@@ -364,6 +364,9 @@ const QuicTag kNSLC = TAG('N', 'S', 'L', 'C'); // Always send connection close // for idle timeout. +// Enable application-driven pacing experiment. +const QuicTag kADP0 = TAG('A', 'D', 'P', '0'); // Enable App-Driven Pacing. + // Proof types (i.e. certificate types) // NOTE: although it would be silly to do so, specifying both kX509 and kX59R // is allowed and is equivalent to specifying only kX509.
diff --git a/quiche/quic/test_tools/quic_test_utils.h b/quiche/quic/test_tools/quic_test_utils.h index ada2cbc..df9fd66 100644 --- a/quiche/quic/test_tools/quic_test_utils.h +++ b/quiche/quic/test_tools/quic_test_utils.h
@@ -1216,6 +1216,8 @@ (const QuicTagVector& connection_options), (override)); MOCK_METHOD(void, SetInitialCongestionWindowInPackets, (QuicPacketCount packets), (override)); + MOCK_METHOD(void, SetApplicationDrivenPacingRate, + (QuicBandwidth application_bandwidth_target), (override)); MOCK_METHOD(void, OnCongestionEvent, (bool rtt_updated, QuicByteCount bytes_in_flight, QuicTime event_time, const AckedPacketVector& acked_packets,