| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/core/congestion_control/bbr_sender.h" | 5 #include "net/quic/core/congestion_control/bbr_sender.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "net/quic/core/congestion_control/rtt_stats.h" | 10 #include "net/quic/core/congestion_control/rtt_stats.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 // The time after which the current min_rtt value expires. | 39 // The time after which the current min_rtt value expires. |
| 40 const QuicTime::Delta kMinRttExpiry = QuicTime::Delta::FromSeconds(10); | 40 const QuicTime::Delta kMinRttExpiry = QuicTime::Delta::FromSeconds(10); |
| 41 // The minimum time the connection can spend in PROBE_RTT mode. | 41 // The minimum time the connection can spend in PROBE_RTT mode. |
| 42 const QuicTime::Delta kProbeRttTime = QuicTime::Delta::FromMilliseconds(200); | 42 const QuicTime::Delta kProbeRttTime = QuicTime::Delta::FromMilliseconds(200); |
| 43 | 43 |
| 44 // If the bandwidth does not increase by the factor of |kStartupGrowthTarget| | 44 // If the bandwidth does not increase by the factor of |kStartupGrowthTarget| |
| 45 // within |kRoundTripsWithoutGrowthBeforeExitingStartup| rounds, the connection | 45 // within |kRoundTripsWithoutGrowthBeforeExitingStartup| rounds, the connection |
| 46 // will exit the STARTUP mode. | 46 // will exit the STARTUP mode. |
| 47 const float kStartupGrowthTarget = 1.25; | 47 const float kStartupGrowthTarget = 1.25; |
| 48 const QuicRoundTripCount kRoundTripsWithoutGrowthBeforeExitingStartup = 3; | 48 const QuicRoundTripCount kRoundTripsWithoutGrowthBeforeExitingStartup = 3; |
| 49 |
| 50 // Maintain ack history for this fraction of the smoothed RTT. |
| 51 const float kRecentlyAckedRttFraction = 0.5f; |
| 52 // Minimum period over which ack history will be maintained. |
| 53 const QuicTime::Delta kMinAckHistory = QuicTime::Delta::FromMilliseconds(5); |
| 54 |
| 49 } // namespace | 55 } // namespace |
| 50 | 56 |
| 51 BbrSender::DebugState::DebugState(const BbrSender& sender) | 57 BbrSender::DebugState::DebugState(const BbrSender& sender) |
| 52 : mode(sender.mode_), | 58 : mode(sender.mode_), |
| 53 max_bandwidth(sender.max_bandwidth_.GetBest()), | 59 max_bandwidth(sender.max_bandwidth_.GetBest()), |
| 54 round_trip_count(sender.round_trip_count_), | 60 round_trip_count(sender.round_trip_count_), |
| 55 gain_cycle_index(sender.cycle_current_offset_), | 61 gain_cycle_index(sender.cycle_current_offset_), |
| 56 congestion_window(sender.congestion_window_), | 62 congestion_window(sender.congestion_window_), |
| 57 is_at_full_bandwidth(sender.is_at_full_bandwidth_), | 63 is_at_full_bandwidth(sender.is_at_full_bandwidth_), |
| 58 bandwidth_at_last_round(sender.bandwidth_at_last_round_), | 64 bandwidth_at_last_round(sender.bandwidth_at_last_round_), |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 kDefaultTCPMSS), | 96 kDefaultTCPMSS), |
| 91 max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS), | 97 max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS), |
| 92 pacing_rate_(QuicBandwidth::Zero()), | 98 pacing_rate_(QuicBandwidth::Zero()), |
| 93 pacing_gain_(1), | 99 pacing_gain_(1), |
| 94 congestion_window_gain_(1), | 100 congestion_window_gain_(1), |
| 95 congestion_window_gain_constant_( | 101 congestion_window_gain_constant_( |
| 96 static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_cwnd_gain))), | 102 static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_cwnd_gain))), |
| 97 rtt_variance_weight_( | 103 rtt_variance_weight_( |
| 98 static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_rtt_variation_weight))), | 104 static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_rtt_variation_weight))), |
| 99 num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup), | 105 num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup), |
| 106 congestion_window_gain_for_slow_delivery_(static_cast<float>( |
| 107 GetQuicFlag(FLAGS_quic_bbr_slow_delivery_cwnd_gain))), |
| 108 threshold_multiplier_for_slow_delivery_(static_cast<float>( |
| 109 GetQuicFlag(FLAGS_quic_bbr_slow_delivery_threshold_multiplier))), |
| 100 cycle_current_offset_(0), | 110 cycle_current_offset_(0), |
| 101 last_cycle_start_(QuicTime::Zero()), | 111 last_cycle_start_(QuicTime::Zero()), |
| 102 is_at_full_bandwidth_(false), | 112 is_at_full_bandwidth_(false), |
| 103 rounds_without_bandwidth_gain_(0), | 113 rounds_without_bandwidth_gain_(0), |
| 104 bandwidth_at_last_round_(QuicBandwidth::Zero()), | 114 bandwidth_at_last_round_(QuicBandwidth::Zero()), |
| 105 exiting_quiescence_(false), | 115 exiting_quiescence_(false), |
| 106 exit_probe_rtt_at_(QuicTime::Zero()), | 116 exit_probe_rtt_at_(QuicTime::Zero()), |
| 107 probe_rtt_round_passed_(false), | 117 probe_rtt_round_passed_(false), |
| 108 last_sample_is_app_limited_(false), | 118 last_sample_is_app_limited_(false), |
| 109 recovery_state_(NOT_IN_RECOVERY), | 119 recovery_state_(NOT_IN_RECOVERY), |
| 110 end_recovery_at_(0), | 120 end_recovery_at_(0), |
| 111 recovery_window_(max_congestion_window_) { | 121 recovery_window_(max_congestion_window_), |
| 122 bytes_recently_acked_(0) { |
| 112 EnterStartupMode(); | 123 EnterStartupMode(); |
| 113 } | 124 } |
| 114 | 125 |
| 115 BbrSender::~BbrSender() {} | 126 BbrSender::~BbrSender() {} |
| 116 | 127 |
| 117 bool BbrSender::InSlowStart() const { | 128 bool BbrSender::InSlowStart() const { |
| 118 return mode_ == STARTUP; | 129 return mode_ == STARTUP; |
| 119 } | 130 } |
| 120 | 131 |
| 121 bool BbrSender::OnPacketSent(QuicTime sent_time, | 132 bool BbrSender::OnPacketSent(QuicTime sent_time, |
| 122 QuicByteCount bytes_in_flight, | 133 QuicByteCount bytes_in_flight, |
| 123 QuicPacketNumber packet_number, | 134 QuicPacketNumber packet_number, |
| 124 QuicByteCount bytes, | 135 QuicByteCount bytes, |
| 125 HasRetransmittableData is_retransmittable) { | 136 HasRetransmittableData is_retransmittable) { |
| 126 last_sent_packet_ = packet_number; | 137 last_sent_packet_ = packet_number; |
| 127 | 138 |
| 128 if (bytes_in_flight == 0 && sampler_.is_app_limited()) { | 139 if (bytes_in_flight == 0 && sampler_.is_app_limited()) { |
| 129 exiting_quiescence_ = true; | 140 exiting_quiescence_ = true; |
| 130 } | 141 } |
| 131 | 142 |
| 132 sampler_.OnPacketSent(sent_time, packet_number, bytes, bytes_in_flight, | 143 sampler_.OnPacketSent(sent_time, packet_number, bytes, bytes_in_flight, |
| 133 is_retransmittable); | 144 is_retransmittable); |
| 134 return is_retransmittable == HAS_RETRANSMITTABLE_DATA; | 145 return is_retransmittable == HAS_RETRANSMITTABLE_DATA; |
| 135 } | 146 } |
| 136 | 147 |
| 137 QuicTime::Delta BbrSender::TimeUntilSend(QuicTime /* now */, | 148 bool BbrSender::SlowDeliveryAllowsSending(QuicTime now, |
| 138 QuicByteCount bytes_in_flight) const { | 149 QuicByteCount bytes_in_flight) { |
| 150 if (mode_ != BbrSender::PROBE_BW) { |
| 151 return false; |
| 152 } |
| 153 UpdateRecentlyAcked(now, 0u); |
| 154 // Set a (large) limit to how much we send into a blackhole. |
| 155 if (bytes_in_flight >= |
| 156 congestion_window_gain_for_slow_delivery_ * GetCongestionWindow()) { |
| 157 return false; |
| 158 } |
| 159 // If no acks were recorded in the recent past, continue sending. |
| 160 if (recently_acked_.empty()) { |
| 161 return true; |
| 162 } |
| 163 // Compute the time period over which acks should have been recorded. |
| 164 QuicTime::Delta ack_period = |
| 165 std::max(now - recently_acked_.front().ack_time, |
| 166 std::max(kMinAckHistory, |
| 167 kRecentlyAckedRttFraction * rtt_stats_->smoothed_rtt())); |
| 168 // If delivery rate is less than BW by a factor of threshold_multiplier_, |
| 169 // ack rate has suddenly decreased substantially. Continue sending. |
| 170 if (BandwidthEstimate() * ack_period > |
| 171 threshold_multiplier_for_slow_delivery_ * bytes_recently_acked_) { |
| 172 return true; |
| 173 } |
| 174 return false; |
| 175 } |
| 176 |
| 177 QuicTime::Delta BbrSender::TimeUntilSend(QuicTime now, |
| 178 QuicByteCount bytes_in_flight) { |
| 139 if (bytes_in_flight < GetCongestionWindow()) { | 179 if (bytes_in_flight < GetCongestionWindow()) { |
| 140 return QuicTime::Delta::Zero(); | 180 return QuicTime::Delta::Zero(); |
| 141 } | 181 } |
| 182 if (FLAGS_quic_reloadable_flag_quic_bbr_slow_recent_delivery && |
| 183 SlowDeliveryAllowsSending(now, bytes_in_flight)) { |
| 184 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_slow_recent_delivery, 2, 2); |
| 185 return QuicTime::Delta::Zero(); |
| 186 } |
| 142 return QuicTime::Delta::Infinite(); | 187 return QuicTime::Delta::Infinite(); |
| 143 } | 188 } |
| 144 | 189 |
| 145 QuicBandwidth BbrSender::PacingRate(QuicByteCount bytes_in_flight) const { | 190 QuicBandwidth BbrSender::PacingRate(QuicByteCount bytes_in_flight) const { |
| 146 if (pacing_rate_.IsZero()) { | 191 if (pacing_rate_.IsZero()) { |
| 147 return kHighGain * QuicBandwidth::FromBytesAndTimeDelta( | 192 return kHighGain * QuicBandwidth::FromBytesAndTimeDelta( |
| 148 initial_congestion_window_, GetMinRtt()); | 193 initial_congestion_window_, GetMinRtt()); |
| 149 } | 194 } |
| 150 if (FLAGS_quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate && | 195 if (FLAGS_quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate && |
| 151 mode_ == PROBE_BW && bytes_in_flight > congestion_window_) { | 196 mode_ == PROBE_BW && bytes_in_flight > congestion_window_) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 | 285 |
| 241 DiscardLostPackets(lost_packets); | 286 DiscardLostPackets(lost_packets); |
| 242 | 287 |
| 243 // Input the new data into the BBR model of the connection. | 288 // Input the new data into the BBR model of the connection. |
| 244 if (!acked_packets.empty()) { | 289 if (!acked_packets.empty()) { |
| 245 QuicPacketNumber last_acked_packet = acked_packets.rbegin()->first; | 290 QuicPacketNumber last_acked_packet = acked_packets.rbegin()->first; |
| 246 is_round_start = UpdateRoundTripCounter(last_acked_packet); | 291 is_round_start = UpdateRoundTripCounter(last_acked_packet); |
| 247 min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets); | 292 min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets); |
| 248 UpdateRecoveryState(last_acked_packet, !lost_packets.empty(), | 293 UpdateRecoveryState(last_acked_packet, !lost_packets.empty(), |
| 249 is_round_start); | 294 is_round_start); |
| 295 |
| 296 if (FLAGS_quic_reloadable_flag_quic_bbr_slow_recent_delivery) { |
| 297 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_slow_recent_delivery, 1, |
| 298 2); |
| 299 UpdateRecentlyAcked( |
| 300 event_time, sampler_.total_bytes_acked() - total_bytes_acked_before); |
| 301 } |
| 302 |
| 250 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes) { | 303 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes) { |
| 251 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 1, | 304 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 1, |
| 252 2); | 305 2); |
| 253 UpdateAckAggregationBytes( | 306 UpdateAckAggregationBytes( |
| 254 event_time, sampler_.total_bytes_acked() - total_bytes_acked_before); | 307 event_time, sampler_.total_bytes_acked() - total_bytes_acked_before); |
| 255 } | 308 } |
| 256 } | 309 } |
| 257 | 310 |
| 258 // Handle logic specific to PROBE_BW mode. | 311 // Handle logic specific to PROBE_BW mode. |
| 259 if (mode_ == PROBE_BW) { | 312 if (mode_ == PROBE_BW) { |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 if (cycle_current_offset_ == 0 || | 585 if (cycle_current_offset_ == 0 || |
| 533 cycle_current_offset_ == kGainCycleLength - 1) { | 586 cycle_current_offset_ == kGainCycleLength - 1) { |
| 534 recovery_state_ = GROWTH; | 587 recovery_state_ = GROWTH; |
| 535 } else { | 588 } else { |
| 536 recovery_state_ = CONSERVATION; | 589 recovery_state_ = CONSERVATION; |
| 537 } | 590 } |
| 538 break; | 591 break; |
| 539 } | 592 } |
| 540 } | 593 } |
| 541 | 594 |
| 595 void BbrSender::UpdateRecentlyAcked(QuicTime new_ack_time, |
| 596 QuicByteCount newly_acked_bytes) { |
| 597 // Discard information stored for acks received too far in the past. |
| 598 QuicTime::Delta recent_period = std::max( |
| 599 kMinAckHistory, kRecentlyAckedRttFraction * rtt_stats_->smoothed_rtt()); |
| 600 while (!recently_acked_.empty() && |
| 601 (recently_acked_.front().ack_time + recent_period < new_ack_time)) { |
| 602 DCHECK_GE(bytes_recently_acked_, recently_acked_.front().acked_bytes); |
| 603 bytes_recently_acked_ -= recently_acked_.front().acked_bytes; |
| 604 recently_acked_.pop_front(); |
| 605 } |
| 606 // Nothing to add to recently_acked_ if no new ack. |
| 607 if (newly_acked_bytes == 0) |
| 608 return; |
| 609 // Add information for new ack |
| 610 DataDelivered new_ack = {new_ack_time, newly_acked_bytes}; |
| 611 recently_acked_.push_back(new_ack); |
| 612 bytes_recently_acked_ += newly_acked_bytes; |
| 613 } |
| 614 |
| 615 // TODO(ianswett): Move this logic into BandwidthSampler. |
| 542 void BbrSender::UpdateAckAggregationBytes(QuicTime ack_time, | 616 void BbrSender::UpdateAckAggregationBytes(QuicTime ack_time, |
| 543 QuicByteCount newly_acked_bytes) { | 617 QuicByteCount newly_acked_bytes) { |
| 544 // Compute how many bytes are expected to be delivered, assuming max bandwidth | 618 // Compute how many bytes are expected to be delivered, assuming max bandwidth |
| 545 // is correct. | 619 // is correct. |
| 546 QuicByteCount expected_bytes_acked = | 620 QuicByteCount expected_bytes_acked = |
| 547 max_bandwidth_.GetBest() * (ack_time - aggregation_epoch_start_time_); | 621 max_bandwidth_.GetBest() * (ack_time - aggregation_epoch_start_time_); |
| 548 // Reset the current aggregation epoch as soon as the ack arrival rate is less | 622 // Reset the current aggregation epoch as soon as the ack arrival rate is less |
| 549 // than or equal to the max bandwidth. | 623 // than or equal to the max bandwidth. |
| 550 if (aggregation_epoch_bytes_ <= expected_bytes_acked) { | 624 if (aggregation_epoch_bytes_ <= expected_bytes_acked) { |
| 551 // Reset to start measuring a new aggregation epoch. | 625 // Reset to start measuring a new aggregation epoch. |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() | 782 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() |
| 709 << std::endl; | 783 << std::endl; |
| 710 | 784 |
| 711 os << "Last sample is app-limited: " | 785 os << "Last sample is app-limited: " |
| 712 << (state.last_sample_is_app_limited ? "yes" : "no"); | 786 << (state.last_sample_is_app_limited ? "yes" : "no"); |
| 713 | 787 |
| 714 return os; | 788 return os; |
| 715 } | 789 } |
| 716 | 790 |
| 717 } // namespace net | 791 } // namespace net |
| OLD | NEW |