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

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

Issue 2825083003: Landing Recent QUIC changes until Mon Apr 17 2017 (Closed)
Patch Set: Format Created 3 years, 8 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"
11 #include "net/quic/core/crypto/crypto_protocol.h" 11 #include "net/quic/core/crypto/crypto_protocol.h"
12 #include "net/quic/core/proto/cached_network_parameters.pb.h" 12 #include "net/quic/core/proto/cached_network_parameters.pb.h"
13 #include "net/quic/core/quic_flags.h"
14 #include "net/quic/platform/api/quic_bug_tracker.h" 13 #include "net/quic/platform/api/quic_bug_tracker.h"
15 #include "net/quic/platform/api/quic_flag_utils.h" 14 #include "net/quic/platform/api/quic_flag_utils.h"
15 #include "net/quic/platform/api/quic_flags.h"
16 #include "net/quic/platform/api/quic_logging.h" 16 #include "net/quic/platform/api/quic_logging.h"
17 17
18 namespace net { 18 namespace net {
19 19
20 namespace { 20 namespace {
21 // Constants based on TCP defaults. 21 // Constants based on TCP defaults.
22 const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS; 22 const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
23 // The minimum CWND to ensure delayed acks don't reduce bandwidth measurements. 23 // The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
24 // Does not inflate the pacing rate. 24 // Does not inflate the pacing rate.
25 const QuicByteCount kMinimumCongestionWindow = 4 * kMaxSegmentSize; 25 const QuicByteCount kMinimumCongestionWindow = 4 * kMaxSegmentSize;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 QuicRandom* random) 73 QuicRandom* random)
74 : rtt_stats_(rtt_stats), 74 : rtt_stats_(rtt_stats),
75 unacked_packets_(unacked_packets), 75 unacked_packets_(unacked_packets),
76 random_(random), 76 random_(random),
77 mode_(STARTUP), 77 mode_(STARTUP),
78 sampler_(), 78 sampler_(),
79 round_trip_count_(0), 79 round_trip_count_(0),
80 last_sent_packet_(0), 80 last_sent_packet_(0),
81 current_round_trip_end_(0), 81 current_round_trip_end_(0),
82 max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0), 82 max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0),
83 max_ack_spacing_(kBandwidthWindowSize, QuicTime::Delta::Zero(), 0),
84 largest_acked_time_(QuicTime::Zero()),
85 largest_acked_sent_time_(QuicTime::Zero()),
86 max_ack_height_(kBandwidthWindowSize, 0, 0), 83 max_ack_height_(kBandwidthWindowSize, 0, 0),
87 aggregation_epoch_start_time_(QuicTime::Zero()), 84 aggregation_epoch_start_time_(QuicTime::Zero()),
88 aggregation_epoch_bytes_(0), 85 aggregation_epoch_bytes_(0),
89 min_rtt_(QuicTime::Delta::Zero()), 86 min_rtt_(QuicTime::Delta::Zero()),
90 min_rtt_timestamp_(QuicTime::Zero()), 87 min_rtt_timestamp_(QuicTime::Zero()),
91 congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS), 88 congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
92 initial_congestion_window_(initial_tcp_congestion_window * 89 initial_congestion_window_(initial_tcp_congestion_window *
93 kDefaultTCPMSS), 90 kDefaultTCPMSS),
94 max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS), 91 max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS),
95 pacing_rate_(QuicBandwidth::Zero()), 92 pacing_rate_(QuicBandwidth::Zero()),
96 pacing_gain_(1), 93 pacing_gain_(1),
97 congestion_window_gain_(1), 94 congestion_window_gain_(1),
98 congestion_window_gain_constant_( 95 congestion_window_gain_constant_(
99 static_cast<float>(base::GetFlag(FLAGS_quic_bbr_cwnd_gain))), 96 static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_cwnd_gain))),
100 rtt_variance_weight_(static_cast<float>( 97 rtt_variance_weight_(
101 base::GetFlag(FLAGS_quic_bbr_rtt_variation_weight))), 98 static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_rtt_variation_weight))),
102 num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup), 99 num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup),
103 cycle_current_offset_(0), 100 cycle_current_offset_(0),
104 last_cycle_start_(QuicTime::Zero()), 101 last_cycle_start_(QuicTime::Zero()),
105 is_at_full_bandwidth_(false), 102 is_at_full_bandwidth_(false),
106 rounds_without_bandwidth_gain_(0), 103 rounds_without_bandwidth_gain_(0),
107 bandwidth_at_last_round_(QuicBandwidth::Zero()), 104 bandwidth_at_last_round_(QuicBandwidth::Zero()),
108 exiting_quiescence_(false), 105 exiting_quiescence_(false),
109 exit_probe_rtt_at_(QuicTime::Zero()), 106 exit_probe_rtt_at_(QuicTime::Zero()),
110 probe_rtt_round_passed_(false), 107 probe_rtt_round_passed_(false),
111 last_sample_is_app_limited_(false), 108 last_sample_is_app_limited_(false),
(...skipping 26 matching lines...) Expand all
138 } 135 }
139 136
140 QuicTime::Delta BbrSender::TimeUntilSend(QuicTime /* now */, 137 QuicTime::Delta BbrSender::TimeUntilSend(QuicTime /* now */,
141 QuicByteCount bytes_in_flight) const { 138 QuicByteCount bytes_in_flight) const {
142 if (bytes_in_flight < GetCongestionWindow()) { 139 if (bytes_in_flight < GetCongestionWindow()) {
143 return QuicTime::Delta::Zero(); 140 return QuicTime::Delta::Zero();
144 } 141 }
145 return QuicTime::Delta::Infinite(); 142 return QuicTime::Delta::Infinite();
146 } 143 }
147 144
148 QuicBandwidth BbrSender::PacingRate(QuicByteCount /*bytes_in_flight*/) const { 145 QuicBandwidth BbrSender::PacingRate(QuicByteCount bytes_in_flight) const {
149 if (pacing_rate_.IsZero()) { 146 if (pacing_rate_.IsZero()) {
150 return kHighGain * QuicBandwidth::FromBytesAndTimeDelta( 147 return kHighGain * QuicBandwidth::FromBytesAndTimeDelta(
151 initial_congestion_window_, GetMinRtt()); 148 initial_congestion_window_, GetMinRtt());
152 } 149 }
150 if (FLAGS_quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate &&
151 mode_ == PROBE_BW && bytes_in_flight > congestion_window_) {
152 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate,
153 1, 2);
154 if (pacing_gain_ > 1) {
155 return max_bandwidth_.GetBest();
156 } else {
157 return max_bandwidth_.GetThirdBest();
158 }
159 }
153 return pacing_rate_; 160 return pacing_rate_;
154 } 161 }
155 162
156 QuicBandwidth BbrSender::BandwidthEstimate() const { 163 QuicBandwidth BbrSender::BandwidthEstimate() const {
157 return max_bandwidth_.GetBest(); 164 return max_bandwidth_.GetBest();
158 } 165 }
159 166
160 QuicByteCount BbrSender::GetCongestionWindow() const { 167 QuicByteCount BbrSender::GetCongestionWindow() const {
161 if (mode_ == PROBE_RTT) { 168 if (mode_ == PROBE_RTT) {
162 return kMinimumCongestionWindow; 169 return kMinimumCongestionWindow;
163 } 170 }
164 171
165 if (InRecovery()) { 172 if (InRecovery()) {
166 return std::min(congestion_window_, recovery_window_); 173 return std::min(congestion_window_, recovery_window_);
167 } 174 }
168 175
176 if (FLAGS_quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate &&
177 mode_ == PROBE_BW && pacing_gain_ >= 1) {
178 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate,
179 2, 2);
180 // Send for another SRTT at a more recently measured bandwidth.
181 return congestion_window_ +
182 max_bandwidth_.GetThirdBest() * rtt_stats_->smoothed_rtt();
183 }
184
169 return congestion_window_; 185 return congestion_window_;
170 } 186 }
171 187
172 QuicByteCount BbrSender::GetSlowStartThreshold() const { 188 QuicByteCount BbrSender::GetSlowStartThreshold() const {
173 return 0; 189 return 0;
174 } 190 }
175 191
176 bool BbrSender::InRecovery() const { 192 bool BbrSender::InRecovery() const {
177 return recovery_state_ != NOT_IN_RECOVERY; 193 return recovery_state_ != NOT_IN_RECOVERY;
178 } 194 }
(...skipping 11 matching lines...) Expand all
190 } 206 }
191 } 207 }
192 208
193 void BbrSender::ResumeConnectionState( 209 void BbrSender::ResumeConnectionState(
194 const CachedNetworkParameters& cached_network_params, 210 const CachedNetworkParameters& cached_network_params,
195 bool max_bandwidth_resumption) { 211 bool max_bandwidth_resumption) {
196 if (!FLAGS_quic_reloadable_flag_quic_bbr_bandwidth_resumption) { 212 if (!FLAGS_quic_reloadable_flag_quic_bbr_bandwidth_resumption) {
197 return; 213 return;
198 } 214 }
199 215
216 QUIC_FLAG_COUNT(quic_reloadable_flag_quic_bbr_bandwidth_resumption);
217
200 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond( 218 QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
201 max_bandwidth_resumption 219 max_bandwidth_resumption
202 ? cached_network_params.max_bandwidth_estimate_bytes_per_second() 220 ? cached_network_params.max_bandwidth_estimate_bytes_per_second()
203 : cached_network_params.bandwidth_estimate_bytes_per_second()); 221 : cached_network_params.bandwidth_estimate_bytes_per_second());
204 QuicTime::Delta rtt = 222 QuicTime::Delta rtt =
205 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms()); 223 QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
206 224
207 max_bandwidth_.Update(bandwidth, round_trip_count_); 225 max_bandwidth_.Update(bandwidth, round_trip_count_);
208 if (!rtt.IsZero() && (min_rtt_ > rtt || min_rtt_.IsZero())) { 226 if (!rtt.IsZero() && (min_rtt_ > rtt || min_rtt_.IsZero())) {
209 min_rtt_ = rtt; 227 min_rtt_ = rtt;
(...skipping 12 matching lines...) Expand all
222 240
223 DiscardLostPackets(lost_packets); 241 DiscardLostPackets(lost_packets);
224 242
225 // Input the new data into the BBR model of the connection. 243 // Input the new data into the BBR model of the connection.
226 if (!acked_packets.empty()) { 244 if (!acked_packets.empty()) {
227 QuicPacketNumber last_acked_packet = acked_packets.rbegin()->first; 245 QuicPacketNumber last_acked_packet = acked_packets.rbegin()->first;
228 is_round_start = UpdateRoundTripCounter(last_acked_packet); 246 is_round_start = UpdateRoundTripCounter(last_acked_packet);
229 min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets); 247 min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets);
230 UpdateRecoveryState(last_acked_packet, !lost_packets.empty(), 248 UpdateRecoveryState(last_acked_packet, !lost_packets.empty(),
231 is_round_start); 249 is_round_start);
232 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_spacing2) {
233 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_spacing2, 1, 2);
234 UpdateAckSpacing(event_time, last_acked_packet, acked_packets);
235 }
236 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes) { 250 if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes) {
237 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 1, 251 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 1,
238 2); 252 2);
239 UpdateAckAggregationBytes( 253 UpdateAckAggregationBytes(
240 event_time, sampler_.total_bytes_acked() - total_bytes_acked_before); 254 event_time, sampler_.total_bytes_acked() - total_bytes_acked_before);
241 } 255 }
242 } 256 }
243 257
244 // Handle logic specific to PROBE_BW mode. 258 // Handle logic specific to PROBE_BW mode.
245 if (mode_ == PROBE_BW) { 259 if (mode_ == PROBE_BW) {
(...skipping 26 matching lines...) Expand all
272 } 286 }
273 287
274 QuicTime::Delta BbrSender::GetMinRtt() const { 288 QuicTime::Delta BbrSender::GetMinRtt() const {
275 return !min_rtt_.IsZero() 289 return !min_rtt_.IsZero()
276 ? min_rtt_ 290 ? min_rtt_
277 : QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us()); 291 : QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us());
278 } 292 }
279 293
280 QuicByteCount BbrSender::GetTargetCongestionWindow(float gain) const { 294 QuicByteCount BbrSender::GetTargetCongestionWindow(float gain) const {
281 QuicByteCount bdp = GetMinRtt() * BandwidthEstimate(); 295 QuicByteCount bdp = GetMinRtt() * BandwidthEstimate();
296 if (FLAGS_quic_reloadable_flag_quic_bbr_base_cwnd_on_srtt &&
297 mode_ == PROBE_BW && gain >= 1 && !rtt_stats_->smoothed_rtt().IsZero()) {
298 bdp = rtt_stats_->smoothed_rtt() * BandwidthEstimate();
299 }
282 QuicByteCount congestion_window = gain * bdp; 300 QuicByteCount congestion_window = gain * bdp;
283 301
284 // BDP estimate will be zero if no bandwidth samples are available yet. 302 // BDP estimate will be zero if no bandwidth samples are available yet.
285 if (congestion_window == 0) { 303 if (congestion_window == 0) {
286 congestion_window = gain * initial_congestion_window_; 304 congestion_window = gain * initial_congestion_window_;
287 } 305 }
288 306
289 return std::max(congestion_window, kMinimumCongestionWindow); 307 return std::max(congestion_window, kMinimumCongestionWindow);
290 } 308 }
291 309
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 513
496 case GROWTH: 514 case GROWTH:
497 // Exit recovery if appropriate. 515 // Exit recovery if appropriate.
498 if (!has_losses && last_acked_packet > end_recovery_at_) { 516 if (!has_losses && last_acked_packet > end_recovery_at_) {
499 recovery_state_ = NOT_IN_RECOVERY; 517 recovery_state_ = NOT_IN_RECOVERY;
500 } 518 }
501 break; 519 break;
502 } 520 }
503 } 521 }
504 522
505 // TODO(ianswett): Move this logic into BandwidthSampler.
506 void BbrSender::UpdateAckSpacing(QuicTime ack_time,
507 QuicPacketNumber largest_newly_acked,
508 const CongestionVector& acked_packets) {
509 // Ignore acks of reordered packets.
510 if (largest_newly_acked < unacked_packets_->largest_observed()) {
511 return;
512 }
513 // Ignore acks of only one packet to filter out delayed acks.
514 if (acked_packets.size() == 1) {
515 return;
516 }
517 QuicTime largest_newly_acked_sent_time =
518 unacked_packets_->GetTransmissionInfo(largest_newly_acked).sent_time;
519 // Initialize on the first ack.
520 if (!largest_acked_time_.IsInitialized()) {
521 largest_acked_time_ = ack_time;
522 largest_acked_sent_time_ = largest_newly_acked_sent_time;
523 return;
524 }
525 QuicTime::Delta ack_delta = ack_time - largest_acked_time_;
526 QuicTime::Delta send_delta =
527 largest_newly_acked_sent_time - largest_acked_sent_time_;
528 largest_acked_time_ = ack_time;
529 largest_acked_sent_time_ = largest_newly_acked_sent_time;
530 if (ack_delta <= send_delta) {
531 return;
532 }
533
534 // Limit the ack spacing to SRTT to filter outliers.
535 QuicTime::Delta ack_spacing =
536 std::min(ack_delta - send_delta, rtt_stats_->smoothed_rtt());
537 max_ack_spacing_.Update(ack_spacing, round_trip_count_);
538 }
539
540 // TODO(ianswett): Move this logic into BandwidthSampler.
541 void BbrSender::UpdateAckAggregationBytes(QuicTime ack_time, 523 void BbrSender::UpdateAckAggregationBytes(QuicTime ack_time,
542 QuicByteCount newly_acked_bytes) { 524 QuicByteCount newly_acked_bytes) {
543 // Compute how many bytes are expected to be delivered, assuming max bandwidth 525 // Compute how many bytes are expected to be delivered, assuming max bandwidth
544 // is correct. 526 // is correct.
545 QuicByteCount expected_bytes_acked = 527 QuicByteCount expected_bytes_acked =
546 max_bandwidth_.GetBest() * (ack_time - aggregation_epoch_start_time_); 528 max_bandwidth_.GetBest() * (ack_time - aggregation_epoch_start_time_);
547 // Reset the current aggregation epoch as soon as the ack arrival rate is less 529 // Reset the current aggregation epoch as soon as the ack arrival rate is less
548 // than or equal to the max bandwidth. 530 // than or equal to the max bandwidth.
549 if (aggregation_epoch_bytes_ <= expected_bytes_acked) { 531 if (aggregation_epoch_bytes_ <= expected_bytes_acked) {
550 // Reset to start measuring a new aggregation epoch. 532 // Reset to start measuring a new aggregation epoch.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 if (mode_ == PROBE_RTT) { 569 if (mode_ == PROBE_RTT) {
588 return; 570 return;
589 } 571 }
590 572
591 QuicByteCount target_window = 573 QuicByteCount target_window =
592 GetTargetCongestionWindow(congestion_window_gain_); 574 GetTargetCongestionWindow(congestion_window_gain_);
593 575
594 if (rtt_variance_weight_ > 0.f && !BandwidthEstimate().IsZero()) { 576 if (rtt_variance_weight_ > 0.f && !BandwidthEstimate().IsZero()) {
595 target_window += rtt_variance_weight_ * rtt_stats_->mean_deviation() * 577 target_window += rtt_variance_weight_ * rtt_stats_->mean_deviation() *
596 BandwidthEstimate(); 578 BandwidthEstimate();
597 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_spacing2 &&
598 is_at_full_bandwidth_) {
599 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_spacing2, 2, 2);
600 // Add CWND for inter-ack spacing once STARTUP has been exited.
601 target_window += max_ack_spacing_.GetBest() * BandwidthEstimate();
602 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes && 579 } else if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes &&
603 is_at_full_bandwidth_) { 580 is_at_full_bandwidth_) {
604 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 2, 581 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 2,
605 2); 582 2);
606 target_window += max_ack_height_.GetBest(); 583 target_window += max_ack_height_.GetBest();
607 } 584 }
608 if (FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd) { 585 if (FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd) {
609 // QUIC doesn't have TSO, but it does have similarly quantized pacing, so 586 // QUIC doesn't have TSO, but it does have similarly quantized pacing, so
610 // allow extra CWND to make QUIC's BBR CWND identical to TCP's. 587 // allow extra CWND to make QUIC's BBR CWND identical to TCP's.
611 QuicByteCount tso_segs_goal = 0; 588 QuicByteCount tso_segs_goal = 0;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() 689 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue()
713 << std::endl; 690 << std::endl;
714 691
715 os << "Last sample is app-limited: " 692 os << "Last sample is app-limited: "
716 << (state.last_sample_is_app_limited ? "yes" : "no"); 693 << (state.last_sample_is_app_limited ? "yes" : "no");
717 694
718 return os; 695 return os;
719 } 696 }
720 697
721 } // namespace net 698 } // 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