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

Unified Diff: net/quic/core/congestion_control/bbr_sender.cc

Issue 2834723002: Landing Recent QUIC changes until Thu Apr 20 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/core/congestion_control/bbr_sender.cc
diff --git a/net/quic/core/congestion_control/bbr_sender.cc b/net/quic/core/congestion_control/bbr_sender.cc
index 666a9d7f62997bfc452ec7bb7a972cf50139ed2d..cd7e59c3186dbc7a4957af99d6abc6368709ecde 100644
--- a/net/quic/core/congestion_control/bbr_sender.cc
+++ b/net/quic/core/congestion_control/bbr_sender.cc
@@ -46,6 +46,12 @@ const QuicTime::Delta kProbeRttTime = QuicTime::Delta::FromMilliseconds(200);
// will exit the STARTUP mode.
const float kStartupGrowthTarget = 1.25;
const QuicRoundTripCount kRoundTripsWithoutGrowthBeforeExitingStartup = 3;
+
+// Maintain ack history for this fraction of the smoothed RTT.
+const float kRecentlyAckedRttFraction = 0.5f;
+// Minimum period over which ack history will be maintained.
+const QuicTime::Delta kMinAckHistory = QuicTime::Delta::FromMilliseconds(5);
+
} // namespace
BbrSender::DebugState::DebugState(const BbrSender& sender)
@@ -93,10 +99,14 @@ BbrSender::BbrSender(const RttStats* rtt_stats,
pacing_gain_(1),
congestion_window_gain_(1),
congestion_window_gain_constant_(
- static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_cwnd_gain))),
+ static_cast<float>(FLAGS_quic_bbr_cwnd_gain)),
rtt_variance_weight_(
- static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_rtt_variation_weight))),
+ static_cast<float>(FLAGS_quic_bbr_rtt_variation_weight)),
num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup),
+ congestion_window_gain_for_slow_delivery_(
+ static_cast<float>(FLAGS_quic_bbr_slow_delivery_cwnd_gain)),
+ threshold_multiplier_for_slow_delivery_(static_cast<float>(
+ FLAGS_quic_bbr_slow_delivery_threshold_multiplier)),
cycle_current_offset_(0),
last_cycle_start_(QuicTime::Zero()),
is_at_full_bandwidth_(false),
@@ -108,7 +118,8 @@ BbrSender::BbrSender(const RttStats* rtt_stats,
last_sample_is_app_limited_(false),
recovery_state_(NOT_IN_RECOVERY),
end_recovery_at_(0),
- recovery_window_(max_congestion_window_) {
+ recovery_window_(max_congestion_window_),
+ bytes_recently_acked_(0) {
EnterStartupMode();
}
@@ -134,11 +145,45 @@ bool BbrSender::OnPacketSent(QuicTime sent_time,
return is_retransmittable == HAS_RETRANSMITTABLE_DATA;
}
-QuicTime::Delta BbrSender::TimeUntilSend(QuicTime /* now */,
- QuicByteCount bytes_in_flight) const {
+bool BbrSender::SlowDeliveryAllowsSending(QuicTime now,
+ QuicByteCount bytes_in_flight) {
+ if (mode_ != BbrSender::PROBE_BW) {
+ return false;
+ }
+ UpdateRecentlyAcked(now, 0u);
+ // Set a (large) limit to how much we send into a blackhole.
+ if (bytes_in_flight >=
+ congestion_window_gain_for_slow_delivery_ * GetCongestionWindow()) {
+ return false;
+ }
+ // If no acks were recorded in the recent past, continue sending.
+ if (recently_acked_.empty()) {
+ return true;
+ }
+ // Compute the time period over which acks should have been recorded.
+ QuicTime::Delta ack_period =
+ std::max(now - recently_acked_.front().ack_time,
+ std::max(kMinAckHistory, kRecentlyAckedRttFraction *
+ rtt_stats_->smoothed_rtt()));
+ // If delivery rate is less than BW by a factor of threshold_multiplier_,
+ // ack rate has suddenly decreased substantially. Continue sending.
+ if (BandwidthEstimate() * ack_period >
+ threshold_multiplier_for_slow_delivery_ * bytes_recently_acked_) {
+ return true;
+ }
+ return false;
+}
+
+QuicTime::Delta BbrSender::TimeUntilSend(QuicTime now,
+ QuicByteCount bytes_in_flight) {
if (bytes_in_flight < GetCongestionWindow()) {
return QuicTime::Delta::Zero();
}
+ if (FLAGS_quic_reloadable_flag_quic_bbr_slow_recent_delivery &&
+ SlowDeliveryAllowsSending(now, bytes_in_flight)) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_slow_recent_delivery, 2, 2);
+ return QuicTime::Delta::Zero();
+ }
return QuicTime::Delta::Infinite();
}
@@ -247,6 +292,14 @@ void BbrSender::OnCongestionEvent(bool /*rtt_updated*/,
min_rtt_expired = UpdateBandwidthAndMinRtt(event_time, acked_packets);
UpdateRecoveryState(last_acked_packet, !lost_packets.empty(),
is_round_start);
+
+ if (FLAGS_quic_reloadable_flag_quic_bbr_slow_recent_delivery) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_slow_recent_delivery, 1,
+ 2);
+ UpdateRecentlyAcked(
+ event_time, sampler_.total_bytes_acked() - total_bytes_acked_before);
+ }
+
if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes) {
QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_bytes, 1,
2);
@@ -515,11 +568,51 @@ void BbrSender::UpdateRecoveryState(QuicPacketNumber last_acked_packet,
// Exit recovery if appropriate.
if (!has_losses && last_acked_packet > end_recovery_at_) {
recovery_state_ = NOT_IN_RECOVERY;
+ return;
+ }
+
+ if (!FLAGS_quic_reloadable_flag_quic_bbr_extra_conservation) {
+ return;
+ }
+
+ // Use "single round in conservation" approach outside of PROBE_BW.
+ if (mode_ != PROBE_BW) {
+ return;
+ }
+
+ // Switch between conservation and growth depending on position in the
+ // gain cycle.
+ if (cycle_current_offset_ == 0 ||
+ cycle_current_offset_ == kGainCycleLength - 1) {
+ recovery_state_ = GROWTH;
+ } else {
+ recovery_state_ = CONSERVATION;
}
break;
}
}
+void BbrSender::UpdateRecentlyAcked(QuicTime new_ack_time,
+ QuicByteCount newly_acked_bytes) {
+ // Discard information stored for acks received too far in the past.
+ QuicTime::Delta recent_period = std::max(
+ kMinAckHistory, kRecentlyAckedRttFraction * rtt_stats_->smoothed_rtt());
+ while (!recently_acked_.empty() &&
+ (recently_acked_.front().ack_time + recent_period < new_ack_time)) {
+ DCHECK_GE(bytes_recently_acked_, recently_acked_.front().acked_bytes);
+ bytes_recently_acked_ -= recently_acked_.front().acked_bytes;
+ recently_acked_.pop_front();
+ }
+ // Nothing to add to recently_acked_ if no new ack.
+ if (newly_acked_bytes == 0)
+ return;
+ // Add information for new ack
+ DataDelivered new_ack = {new_ack_time, newly_acked_bytes};
+ recently_acked_.push_back(new_ack);
+ bytes_recently_acked_ += newly_acked_bytes;
+}
+
+// TODO(ianswett): Move this logic into BandwidthSampler.
void BbrSender::UpdateAckAggregationBytes(QuicTime ack_time,
QuicByteCount newly_acked_bytes) {
// Compute how many bytes are expected to be delivered, assuming max bandwidth
« 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