Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: net/quic/core/congestion_control/bbr_sender.cc

Issue 2964583002: Landing Recent QUIC changes until Jun 27 19:50:48 2017 +0000 (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 random_(random), 82 random_(random),
83 mode_(STARTUP), 83 mode_(STARTUP),
84 sampler_(), 84 sampler_(),
85 round_trip_count_(0), 85 round_trip_count_(0),
86 last_sent_packet_(0), 86 last_sent_packet_(0),
87 current_round_trip_end_(0), 87 current_round_trip_end_(0),
88 max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0), 88 max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0),
89 max_ack_height_(kBandwidthWindowSize, 0, 0), 89 max_ack_height_(kBandwidthWindowSize, 0, 0),
90 aggregation_epoch_start_time_(QuicTime::Zero()), 90 aggregation_epoch_start_time_(QuicTime::Zero()),
91 aggregation_epoch_bytes_(0), 91 aggregation_epoch_bytes_(0),
92 bytes_acked_since_queue_drained_(0),
92 min_rtt_(QuicTime::Delta::Zero()), 93 min_rtt_(QuicTime::Delta::Zero()),
93 min_rtt_timestamp_(QuicTime::Zero()), 94 min_rtt_timestamp_(QuicTime::Zero()),
94 congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS), 95 congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
95 initial_congestion_window_(initial_tcp_congestion_window * 96 initial_congestion_window_(initial_tcp_congestion_window *
96 kDefaultTCPMSS), 97 kDefaultTCPMSS),
97 max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS), 98 max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS),
98 pacing_rate_(QuicBandwidth::Zero()), 99 pacing_rate_(QuicBandwidth::Zero()),
99 pacing_gain_(1), 100 pacing_gain_(1),
100 congestion_window_gain_(1), 101 congestion_window_gain_(1),
101 congestion_window_gain_constant_( 102 congestion_window_gain_constant_(
(...skipping 10 matching lines...) Expand all
112 is_at_full_bandwidth_(false), 113 is_at_full_bandwidth_(false),
113 rounds_without_bandwidth_gain_(0), 114 rounds_without_bandwidth_gain_(0),
114 bandwidth_at_last_round_(QuicBandwidth::Zero()), 115 bandwidth_at_last_round_(QuicBandwidth::Zero()),
115 exiting_quiescence_(false), 116 exiting_quiescence_(false),
116 exit_probe_rtt_at_(QuicTime::Zero()), 117 exit_probe_rtt_at_(QuicTime::Zero()),
117 probe_rtt_round_passed_(false), 118 probe_rtt_round_passed_(false),
118 last_sample_is_app_limited_(false), 119 last_sample_is_app_limited_(false),
119 recovery_state_(NOT_IN_RECOVERY), 120 recovery_state_(NOT_IN_RECOVERY),
120 end_recovery_at_(0), 121 end_recovery_at_(0),
121 recovery_window_(max_congestion_window_), 122 recovery_window_(max_congestion_window_),
122 bytes_recently_acked_(0) { 123 bytes_recently_acked_(0),
124 rate_based_recovery_(false) {
123 EnterStartupMode(); 125 EnterStartupMode();
124 } 126 }
125 127
126 BbrSender::~BbrSender() {} 128 BbrSender::~BbrSender() {}
127 129
128 bool BbrSender::InSlowStart() const { 130 bool BbrSender::InSlowStart() const {
129 return mode_ == STARTUP; 131 return mode_ == STARTUP;
130 } 132 }
131 133
132 bool BbrSender::OnPacketSent(QuicTime sent_time, 134 bool BbrSender::OnPacketSent(QuicTime sent_time,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 199
198 QuicBandwidth BbrSender::BandwidthEstimate() const { 200 QuicBandwidth BbrSender::BandwidthEstimate() const {
199 return max_bandwidth_.GetBest(); 201 return max_bandwidth_.GetBest();
200 } 202 }
201 203
202 QuicByteCount BbrSender::GetCongestionWindow() const { 204 QuicByteCount BbrSender::GetCongestionWindow() const {
203 if (mode_ == PROBE_RTT) { 205 if (mode_ == PROBE_RTT) {
204 return kMinimumCongestionWindow; 206 return kMinimumCongestionWindow;
205 } 207 }
206 208
207 if (InRecovery()) { 209 if (InRecovery() && !rate_based_recovery_) {
208 return std::min(congestion_window_, recovery_window_); 210 return std::min(congestion_window_, recovery_window_);
209 } 211 }
210 212
211 return congestion_window_; 213 return congestion_window_;
212 } 214 }
213 215
214 QuicByteCount BbrSender::GetSlowStartThreshold() const { 216 QuicByteCount BbrSender::GetSlowStartThreshold() const {
215 return 0; 217 return 0;
216 } 218 }
217 219
218 bool BbrSender::InRecovery() const { 220 bool BbrSender::InRecovery() const {
219 return recovery_state_ != NOT_IN_RECOVERY; 221 return recovery_state_ != NOT_IN_RECOVERY;
220 } 222 }
221 223
222 void BbrSender::SetFromConfig(const QuicConfig& config, 224 void BbrSender::SetFromConfig(const QuicConfig& config,
223 Perspective perspective) { 225 Perspective perspective) {
224 if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) { 226 if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) {
225 num_startup_rtts_ = 1; 227 num_startup_rtts_ = 1;
226 } 228 }
227 if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) { 229 if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
228 num_startup_rtts_ = 2; 230 num_startup_rtts_ = 2;
229 } 231 }
232 if (FLAGS_quic_reloadable_flag_quic_bbr_rate_recovery &&
233 config.HasClientRequestedIndependentOption(kBBRR, perspective)) {
234 rate_based_recovery_ = true;
235 }
230 } 236 }
231 237
232 void BbrSender::ResumeConnectionState( 238 void BbrSender::ResumeConnectionState(
233 const CachedNetworkParameters& cached_network_params, 239 const CachedNetworkParameters& cached_network_params,
234 bool max_bandwidth_resumption) { 240 bool max_bandwidth_resumption) {
235 if (!FLAGS_quic_reloadable_flag_quic_bbr_bandwidth_resumption) { 241 if (!FLAGS_quic_reloadable_flag_quic_bbr_bandwidth_resumption) {
236 return; 242 return;
237 } 243 }
238 244
239 QUIC_FLAG_COUNT(quic_reloadable_flag_quic_bbr_bandwidth_resumption); 245 QUIC_FLAG_COUNT(quic_reloadable_flag_quic_bbr_bandwidth_resumption);
(...skipping 24 matching lines...) Expand all
264 DiscardLostPackets(lost_packets); 270 DiscardLostPackets(lost_packets);
265 271
266 // Input the new data into the BBR model of the connection. 272 // Input the new data into the BBR model of the connection.
267 if (!acked_packets.empty()) { 273 if (!acked_packets.empty()) {
268 QuicPacketNumber last_acked_packet = acked_packets.rbegin()->first; 274 QuicPacketNumber last_acked_packet = acked_packets.rbegin()->first;
269 is_round_start = UpdateRoundTripCounter(last_acked_packet); 275 is_round_start = UpdateRoundTripCounter(last_acked_packet);
270 min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets); 276 min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets);
271 UpdateRecoveryState(last_acked_packet, !lost_packets.empty(), 277 UpdateRecoveryState(last_acked_packet, !lost_packets.empty(),
272 is_round_start); 278 is_round_start);
273 279
280 const QuicByteCount bytes_acked =
281 sampler_.total_bytes_acked() - total_bytes_acked_before;
274 if (FLAGS_quic_reloadable_flag_quic_bbr_slow_recent_delivery) { 282 if (FLAGS_quic_reloadable_flag_quic_bbr_slow_recent_delivery) {
275 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_slow_recent_delivery, 1, 283 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_slow_recent_delivery, 1,
276 2); 284 2);
277 UpdateRecentlyAcked( 285 UpdateRecentlyAcked(event_time, bytes_acked);
278 event_time, sampler_.total_bytes_acked() - total_bytes_acked_before);
279 } 286 }
280 287
281 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes) { 288 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes) {
282 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 1, 289 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 1,
283 2); 290 2);
284 UpdateAckAggregationBytes( 291 UpdateAckAggregationBytes(event_time, bytes_acked);
285 event_time, sampler_.total_bytes_acked() - total_bytes_acked_before); 292 }
293 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes2) {
294 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes2, 1,
295 2);
296 UpdateAckAggregationBytes(event_time, bytes_acked);
297 if (unacked_packets_->bytes_in_flight() <=
298 1.25 * GetTargetCongestionWindow(pacing_gain_)) {
299 bytes_acked_since_queue_drained_ = 0;
300 } else {
301 bytes_acked_since_queue_drained_ += bytes_acked;
302 }
286 } 303 }
287 } 304 }
288 305
289 // Handle logic specific to PROBE_BW mode. 306 // Handle logic specific to PROBE_BW mode.
290 if (mode_ == PROBE_BW) { 307 if (mode_ == PROBE_BW) {
291 UpdateGainCyclePhase(event_time, prior_in_flight, !lost_packets.empty()); 308 UpdateGainCyclePhase(event_time, prior_in_flight, !lost_packets.empty());
292 } 309 }
293 310
294 // Handle logic specific to STARTUP and DRAIN modes. 311 // Handle logic specific to STARTUP and DRAIN modes.
295 if (is_round_start && !is_at_full_bandwidth_) { 312 if (is_round_start && !is_at_full_bandwidth_) {
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 max_ack_height_.Update(aggregation_epoch_bytes_ - expected_bytes_acked, 620 max_ack_height_.Update(aggregation_epoch_bytes_ - expected_bytes_acked,
604 round_trip_count_); 621 round_trip_count_);
605 } 622 }
606 623
607 void BbrSender::CalculatePacingRate() { 624 void BbrSender::CalculatePacingRate() {
608 if (BandwidthEstimate().IsZero()) { 625 if (BandwidthEstimate().IsZero()) {
609 return; 626 return;
610 } 627 }
611 628
612 QuicBandwidth target_rate = pacing_gain_ * BandwidthEstimate(); 629 QuicBandwidth target_rate = pacing_gain_ * BandwidthEstimate();
630 if (rate_based_recovery_ && InRecovery()) {
631 QUIC_FLAG_COUNT(quic_reloadable_flag_quic_bbr_rate_recovery);
632 pacing_rate_ = pacing_gain_ * max_bandwidth_.GetThirdBest();
633 }
613 if (is_at_full_bandwidth_) { 634 if (is_at_full_bandwidth_) {
614 pacing_rate_ = target_rate; 635 pacing_rate_ = target_rate;
615 return; 636 return;
616 } 637 }
617 638
618 // Pace at the rate of initial_window / RTT as soon as RTT measurements are 639 // Pace at the rate of initial_window / RTT as soon as RTT measurements are
619 // available. 640 // available.
620 if (pacing_rate_.IsZero() && !rtt_stats_->min_rtt().IsZero()) { 641 if (pacing_rate_.IsZero() && !rtt_stats_->min_rtt().IsZero()) {
621 pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta( 642 pacing_rate_ = QuicBandwidth::FromBytesAndTimeDelta(
622 initial_congestion_window_, rtt_stats_->min_rtt()); 643 initial_congestion_window_, rtt_stats_->min_rtt());
(...skipping 13 matching lines...) Expand all
636 GetTargetCongestionWindow(congestion_window_gain_); 657 GetTargetCongestionWindow(congestion_window_gain_);
637 658
638 if (rtt_variance_weight_ > 0.f && !BandwidthEstimate().IsZero()) { 659 if (rtt_variance_weight_ > 0.f && !BandwidthEstimate().IsZero()) {
639 target_window += rtt_variance_weight_ * rtt_stats_->mean_deviation() * 660 target_window += rtt_variance_weight_ * rtt_stats_->mean_deviation() *
640 BandwidthEstimate(); 661 BandwidthEstimate();
641 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes && 662 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes &&
642 is_at_full_bandwidth_) { 663 is_at_full_bandwidth_) {
643 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 2, 664 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 2,
644 2); 665 2);
645 target_window += max_ack_height_.GetBest(); 666 target_window += max_ack_height_.GetBest();
667 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes2 &&
668 is_at_full_bandwidth_) {
669 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes2, 2,
670 2);
671 if (2 * max_ack_height_.GetBest() > bytes_acked_since_queue_drained_) {
672 target_window +=
673 2 * max_ack_height_.GetBest() - bytes_acked_since_queue_drained_;
674 }
646 } 675 }
647 if (FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd) { 676 if (FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd) {
648 // QUIC doesn't have TSO, but it does have similarly quantized pacing, so 677 // QUIC doesn't have TSO, but it does have similarly quantized pacing, so
649 // allow extra CWND to make QUIC's BBR CWND identical to TCP's. 678 // allow extra CWND to make QUIC's BBR CWND identical to TCP's.
650 QuicByteCount tso_segs_goal = 0; 679 QuicByteCount tso_segs_goal = 0;
651 if (pacing_rate_ < QuicBandwidth::FromKBitsPerSecond(1200)) { 680 if (pacing_rate_ < QuicBandwidth::FromKBitsPerSecond(1200)) {
652 tso_segs_goal = kDefaultTCPMSS; 681 tso_segs_goal = kDefaultTCPMSS;
653 } else if (pacing_rate_ < QuicBandwidth::FromKBitsPerSecond(24000)) { 682 } else if (pacing_rate_ < QuicBandwidth::FromKBitsPerSecond(24000)) {
654 tso_segs_goal = 2 * kDefaultTCPMSS; 683 tso_segs_goal = 2 * kDefaultTCPMSS;
655 } else { 684 } else {
(...skipping 17 matching lines...) Expand all
673 congestion_window_ = congestion_window_ + bytes_acked; 702 congestion_window_ = congestion_window_ + bytes_acked;
674 } 703 }
675 704
676 // Enforce the limits on the congestion window. 705 // Enforce the limits on the congestion window.
677 congestion_window_ = std::max(congestion_window_, kMinimumCongestionWindow); 706 congestion_window_ = std::max(congestion_window_, kMinimumCongestionWindow);
678 congestion_window_ = std::min(congestion_window_, max_congestion_window_); 707 congestion_window_ = std::min(congestion_window_, max_congestion_window_);
679 } 708 }
680 709
681 void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked, 710 void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked,
682 QuicByteCount bytes_lost) { 711 QuicByteCount bytes_lost) {
712 if (rate_based_recovery_) {
713 return;
714 }
683 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation2) { 715 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation2) {
684 if (recovery_state_ == NOT_IN_RECOVERY) { 716 if (recovery_state_ == NOT_IN_RECOVERY) {
685 return; 717 return;
686 } 718 }
687 719
688 // Set up the initial recovery window. 720 // Set up the initial recovery window.
689 if (recovery_window_ == 0) { 721 if (recovery_window_ == 0) {
690 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation2, 2, 3); 722 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation2, 2, 3);
691 recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked; 723 recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked;
692 recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_); 724 recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() 819 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue()
788 << std::endl; 820 << std::endl;
789 821
790 os << "Last sample is app-limited: " 822 os << "Last sample is app-limited: "
791 << (state.last_sample_is_app_limited ? "yes" : "no"); 823 << (state.last_sample_is_app_limited ? "yes" : "no");
792 824
793 return os; 825 return os;
794 } 826 }
795 827
796 } // namespace net 828 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/congestion_control/bbr_sender.h ('k') | net/quic/core/congestion_control/bbr_sender_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698