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

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

Issue 2862563003: Landing Recent QUIC changes until Sat Apr 29 00:22:04 2017 +0000 (Closed)
Patch Set: rebase and fix test bugs detected by swarm bot. Created 3 years, 7 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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 return QuicTime::Delta::Zero(); 185 return QuicTime::Delta::Zero();
186 } 186 }
187 return QuicTime::Delta::Infinite(); 187 return QuicTime::Delta::Infinite();
188 } 188 }
189 189
190 QuicBandwidth BbrSender::PacingRate(QuicByteCount bytes_in_flight) const { 190 QuicBandwidth BbrSender::PacingRate(QuicByteCount bytes_in_flight) const {
191 if (pacing_rate_.IsZero()) { 191 if (pacing_rate_.IsZero()) {
192 return kHighGain * QuicBandwidth::FromBytesAndTimeDelta( 192 return kHighGain * QuicBandwidth::FromBytesAndTimeDelta(
193 initial_congestion_window_, GetMinRtt()); 193 initial_congestion_window_, GetMinRtt());
194 } 194 }
195 if (FLAGS_quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate &&
196 mode_ == PROBE_BW && bytes_in_flight > congestion_window_) {
197 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate,
198 1, 2);
199 if (pacing_gain_ > 1) {
200 return max_bandwidth_.GetBest();
201 } else {
202 return max_bandwidth_.GetThirdBest();
203 }
204 }
205 return pacing_rate_; 195 return pacing_rate_;
206 } 196 }
207 197
208 QuicBandwidth BbrSender::BandwidthEstimate() const { 198 QuicBandwidth BbrSender::BandwidthEstimate() const {
209 return max_bandwidth_.GetBest(); 199 return max_bandwidth_.GetBest();
210 } 200 }
211 201
212 QuicByteCount BbrSender::GetCongestionWindow() const { 202 QuicByteCount BbrSender::GetCongestionWindow() const {
213 if (mode_ == PROBE_RTT) { 203 if (mode_ == PROBE_RTT) {
214 return kMinimumCongestionWindow; 204 return kMinimumCongestionWindow;
215 } 205 }
216 206
217 if (InRecovery()) { 207 if (InRecovery()) {
218 return std::min(congestion_window_, recovery_window_); 208 return std::min(congestion_window_, recovery_window_);
219 } 209 }
220 210
221 if (FLAGS_quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate &&
222 mode_ == PROBE_BW && pacing_gain_ >= 1) {
223 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate,
224 2, 2);
225 // Send for another SRTT at a more recently measured bandwidth.
226 return congestion_window_ +
227 max_bandwidth_.GetThirdBest() * rtt_stats_->smoothed_rtt();
228 }
229
230 return congestion_window_; 211 return congestion_window_;
231 } 212 }
232 213
233 QuicByteCount BbrSender::GetSlowStartThreshold() const { 214 QuicByteCount BbrSender::GetSlowStartThreshold() const {
234 return 0; 215 return 0;
235 } 216 }
236 217
237 bool BbrSender::InRecovery() const { 218 bool BbrSender::InRecovery() const {
238 return recovery_state_ != NOT_IN_RECOVERY; 219 return recovery_state_ != NOT_IN_RECOVERY;
239 } 220 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 296
316 // Handle logic specific to STARTUP and DRAIN modes. 297 // Handle logic specific to STARTUP and DRAIN modes.
317 if (is_round_start && !is_at_full_bandwidth_) { 298 if (is_round_start && !is_at_full_bandwidth_) {
318 CheckIfFullBandwidthReached(); 299 CheckIfFullBandwidthReached();
319 } 300 }
320 MaybeExitStartupOrDrain(event_time); 301 MaybeExitStartupOrDrain(event_time);
321 302
322 // Handle logic specific to PROBE_RTT. 303 // Handle logic specific to PROBE_RTT.
323 MaybeEnterOrExitProbeRtt(event_time, is_round_start, min_rtt_expired); 304 MaybeEnterOrExitProbeRtt(event_time, is_round_start, min_rtt_expired);
324 305
306 // Calculate number of packets acked and lost.
307 QuicByteCount bytes_acked =
308 sampler_.total_bytes_acked() - total_bytes_acked_before;
309 QuicByteCount bytes_lost = 0;
310 for (const auto& packet : lost_packets) {
311 bytes_lost += packet.second;
312 }
313
325 // After the model is updated, recalculate the pacing rate and congestion 314 // After the model is updated, recalculate the pacing rate and congestion
326 // window. 315 // window.
327 QuicByteCount bytes_acked =
328 sampler_.total_bytes_acked() - total_bytes_acked_before;
329 CalculatePacingRate(); 316 CalculatePacingRate();
330 CalculateCongestionWindow(bytes_acked); 317 CalculateCongestionWindow(bytes_acked);
331 CalculateRecoveryWindow(bytes_acked); 318 CalculateRecoveryWindow(bytes_acked, bytes_lost);
332 319
333 // Cleanup internal state. 320 // Cleanup internal state.
334 sampler_.RemoveObsoletePackets(unacked_packets_->GetLeastUnacked()); 321 sampler_.RemoveObsoletePackets(unacked_packets_->GetLeastUnacked());
335 } 322 }
336 323
337 CongestionControlType BbrSender::GetCongestionControlType() const { 324 CongestionControlType BbrSender::GetCongestionControlType() const {
338 return kBBR; 325 return kBBR;
339 } 326 }
340 327
341 QuicTime::Delta BbrSender::GetMinRtt() const { 328 QuicTime::Delta BbrSender::GetMinRtt() const {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 // Exit recovery when there are no losses for a round. 533 // Exit recovery when there are no losses for a round.
547 if (has_losses) { 534 if (has_losses) {
548 end_recovery_at_ = last_sent_packet_; 535 end_recovery_at_ = last_sent_packet_;
549 } 536 }
550 537
551 switch (recovery_state_) { 538 switch (recovery_state_) {
552 case NOT_IN_RECOVERY: 539 case NOT_IN_RECOVERY:
553 // Enter conservation on the first loss. 540 // Enter conservation on the first loss.
554 if (has_losses) { 541 if (has_losses) {
555 recovery_state_ = CONSERVATION; 542 recovery_state_ = CONSERVATION;
556 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation) { 543 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation ||
544 FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation2) {
557 // This will cause the |recovery_window_| to be set to the correct 545 // This will cause the |recovery_window_| to be set to the correct
558 // value in CalculateRecoveryWindow(). 546 // value in CalculateRecoveryWindow().
559 recovery_window_ = 0; 547 recovery_window_ = 0;
560 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation, 1, 548 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation, 1,
561 3); 549 3);
550 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation2, 1,
551 3);
562 } 552 }
563 // Since the conservation phase is meant to be lasting for a whole 553 // Since the conservation phase is meant to be lasting for a whole
564 // round, extend the current round as if it were started right now. 554 // round, extend the current round as if it were started right now.
565 current_round_trip_end_ = last_sent_packet_; 555 current_round_trip_end_ = last_sent_packet_;
566 } 556 }
567 break; 557 break;
568 558
569 case CONSERVATION: 559 case CONSERVATION:
570 if (is_round_start) { 560 if (is_round_start) {
571 recovery_state_ = GROWTH; 561 recovery_state_ = GROWTH;
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 // If the connection is not yet out of startup phase, do not decrease the 699 // If the connection is not yet out of startup phase, do not decrease the
710 // window. 700 // window.
711 congestion_window_ = congestion_window_ + bytes_acked; 701 congestion_window_ = congestion_window_ + bytes_acked;
712 } 702 }
713 703
714 // Enforce the limits on the congestion window. 704 // Enforce the limits on the congestion window.
715 congestion_window_ = std::max(congestion_window_, kMinimumCongestionWindow); 705 congestion_window_ = std::max(congestion_window_, kMinimumCongestionWindow);
716 congestion_window_ = std::min(congestion_window_, max_congestion_window_); 706 congestion_window_ = std::min(congestion_window_, max_congestion_window_);
717 } 707 }
718 708
719 void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked) { 709 void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked,
710 QuicByteCount bytes_lost) {
711 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation2) {
712 if (recovery_state_ == NOT_IN_RECOVERY) {
713 return;
714 }
715
716 // Set up the initial recovery window.
717 if (recovery_window_ == 0) {
718 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation2, 2, 3);
719 recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked;
720 recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_);
721 return;
722 }
723
724 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation2, 3, 3);
725
726 // Remove losses from the recovery window, while accounting for a potential
727 // integer underflow.
728 recovery_window_ = recovery_window_ >= bytes_lost
729 ? recovery_window_ - bytes_lost
730 : kMaxSegmentSize;
731
732 // In CONSERVATION mode, just subtracting losses is sufficient. In GROWTH,
733 // release additional |bytes_acked| to achieve a slow-start-like behavior.
734 if (recovery_state_ == GROWTH) {
735 recovery_window_ += bytes_acked;
736 }
737
738 // Sanity checks. Ensure that we always allow to send at least
739 // |bytes_acked| in response.
740 recovery_window_ = std::max(
741 recovery_window_, unacked_packets_->bytes_in_flight() + bytes_acked);
742 recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_);
743 return;
744 }
745
720 switch (recovery_state_) { 746 switch (recovery_state_) {
721 case CONSERVATION: 747 case CONSERVATION:
722 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation) { 748 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation) {
723 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation, 2, 3); 749 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation, 2, 3);
724 recovery_window_ = 750 recovery_window_ =
725 std::max(unacked_packets_->bytes_in_flight() + bytes_acked, 751 std::max(unacked_packets_->bytes_in_flight() + bytes_acked,
726 recovery_window_); 752 recovery_window_);
727 } else { 753 } else {
728 recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked; 754 recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked;
729 } 755 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() 830 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue()
805 << std::endl; 831 << std::endl;
806 832
807 os << "Last sample is app-limited: " 833 os << "Last sample is app-limited: "
808 << (state.last_sample_is_app_limited ? "yes" : "no"); 834 << (state.last_sample_is_app_limited ? "yes" : "no");
809 835
810 return os; 836 return os;
811 } 837 }
812 838
813 } // namespace net 839 } // 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