1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_ 6 #define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_ 7 8 #include <cstdint> 9 10 #include "net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h" 11 #include "net/third_party/quiche/src/quic/core/quic_time.h" 12 #include "net/third_party/quiche/src/quic/core/quic_types.h" 13 #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" 14 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" 15 16 namespace quic { 17 18 class Bbr2Sender; 19 class QUIC_EXPORT_PRIVATE Bbr2ProbeBwMode final : public Bbr2ModeBase { 20 public: 21 using Bbr2ModeBase::Bbr2ModeBase; 22 23 void Enter(QuicTime now, 24 const Bbr2CongestionEvent* congestion_event) override; Leave(QuicTime,const Bbr2CongestionEvent *)25 void Leave(QuicTime /*now*/, 26 const Bbr2CongestionEvent* /*congestion_event*/) override {} 27 28 Bbr2Mode OnCongestionEvent( 29 QuicByteCount prior_in_flight, 30 QuicTime event_time, 31 const AckedPacketVector& acked_packets, 32 const LostPacketVector& lost_packets, 33 const Bbr2CongestionEvent& congestion_event) override; 34 35 Limits<QuicByteCount> GetCwndLimits() const override; 36 37 bool IsProbingForBandwidth() const override; 38 39 Bbr2Mode OnExitQuiescence(QuicTime now, 40 QuicTime quiescence_start_time) override; 41 42 enum class CyclePhase : uint8_t { 43 PROBE_NOT_STARTED, 44 PROBE_UP, 45 PROBE_DOWN, 46 PROBE_CRUISE, 47 PROBE_REFILL, 48 }; 49 50 static const char* CyclePhaseToString(CyclePhase phase); 51 52 struct QUIC_EXPORT_PRIVATE DebugState { 53 CyclePhase phase; 54 QuicTime cycle_start_time = QuicTime::Zero(); 55 QuicTime phase_start_time = QuicTime::Zero(); 56 }; 57 58 DebugState ExportDebugState() const; 59 60 private: 61 const Bbr2Params& Params() const; 62 float PacingGainForPhase(CyclePhase phase) const; 63 64 void UpdateProbeUp(QuicByteCount prior_in_flight, 65 const Bbr2CongestionEvent& congestion_event); 66 void UpdateProbeDown(QuicByteCount prior_in_flight, 67 const Bbr2CongestionEvent& congestion_event); 68 void UpdateProbeCruise(const Bbr2CongestionEvent& congestion_event); 69 void UpdateProbeRefill(const Bbr2CongestionEvent& congestion_event); 70 71 enum AdaptUpperBoundsResult : uint8_t { 72 ADAPTED_OK, 73 ADAPTED_PROBED_TOO_HIGH, 74 NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET, 75 NOT_ADAPTED_INVALID_SAMPLE, 76 }; 77 78 // Return whether adapted inflight_hi. If inflight is too high, this function 79 // will not adapt inflight_hi and will return false. 80 AdaptUpperBoundsResult MaybeAdaptUpperBounds( 81 const Bbr2CongestionEvent& congestion_event); 82 83 void EnterProbeDown(bool probed_too_high, 84 bool stopped_risky_probe, 85 QuicTime now); 86 void EnterProbeCruise(QuicTime now); 87 void EnterProbeRefill(uint64_t probe_up_rounds, QuicTime now); 88 void EnterProbeUp(QuicTime now); 89 90 // Call right before the exit of PROBE_DOWN. 91 void ExitProbeDown(); 92 93 float PercentTimeElapsedToProbeBandwidth( 94 const Bbr2CongestionEvent& congestion_event) const; 95 96 bool IsTimeToProbeBandwidth( 97 const Bbr2CongestionEvent& congestion_event) const; 98 bool HasStayedLongEnoughInProbeDown( 99 const Bbr2CongestionEvent& congestion_event) const; 100 bool HasCycleLasted(QuicTime::Delta duration, 101 const Bbr2CongestionEvent& congestion_event) const; 102 bool HasPhaseLasted(QuicTime::Delta duration, 103 const Bbr2CongestionEvent& congestion_event) const; 104 bool IsTimeToProbeForRenoCoexistence( 105 double probe_wait_fraction, 106 const Bbr2CongestionEvent& congestion_event) const; 107 108 void RaiseInflightHighSlope(); 109 void ProbeInflightHighUpward(const Bbr2CongestionEvent& congestion_event); 110 111 struct QUIC_EXPORT_PRIVATE Cycle { 112 QuicTime cycle_start_time = QuicTime::Zero(); 113 CyclePhase phase = CyclePhase::PROBE_NOT_STARTED; 114 uint64_t rounds_in_phase = 0; 115 QuicTime phase_start_time = QuicTime::Zero(); 116 QuicRoundTripCount rounds_since_probe = 0; 117 QuicTime::Delta probe_wait_time = QuicTime::Delta::Zero(); 118 uint64_t probe_up_rounds = 0; 119 QuicByteCount probe_up_bytes = std::numeric_limits<QuicByteCount>::max(); 120 QuicByteCount probe_up_acked = 0; 121 // Whether max bandwidth filter window has advanced in this cycle. It is 122 // advanced once per cycle. 123 bool has_advanced_max_bw = false; 124 bool is_sample_from_probing = false; 125 } cycle_; 126 127 bool last_cycle_probed_too_high_; 128 bool last_cycle_stopped_risky_probe_; 129 }; 130 131 QUIC_EXPORT_PRIVATE std::ostream& operator<<( 132 std::ostream& os, 133 const Bbr2ProbeBwMode::DebugState& state); 134 135 QUIC_EXPORT_PRIVATE std::ostream& operator<<( 136 std::ostream& os, 137 const Bbr2ProbeBwMode::CyclePhase phase); 138 139 } // namespace quic 140 141 #endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_ 142