diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-15 21:06:49 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-15 21:06:49 +0000 |
commit | fb35b0a23a69fd33a5320362d43b9b6e8df40b7d (patch) | |
tree | 1fa3f843a77fdc314e14012161a072b742d4858e /net/quic/congestion_control | |
parent | 47a7c002213e7008d7a989122acfe182a1114ad4 (diff) | |
download | chromium_src-fb35b0a23a69fd33a5320362d43b9b6e8df40b7d.zip chromium_src-fb35b0a23a69fd33a5320362d43b9b6e8df40b7d.tar.gz chromium_src-fb35b0a23a69fd33a5320362d43b9b6e8df40b7d.tar.bz2 |
Land Recent QUIC Changes
Add reordering statistics and min_rtt to QuicConnectionStats.
Merge internal change: 64582035
https://codereview.chromium.org/231733008/
Add a slowstart packets lost stat to allow QUIC to track how many
packets are lost when exiting slowstart.
Merge internal change: 64548567
https://codereview.chromium.org/231833004/
Added hooks to QUIC time wait list manager so that internal server
specific code could be separated.
Merge internal change: 64500752
https://codereview.chromium.org/231863006/
Cleanup changes found while merging the privacy mode changes into
the internal source tree.
Merge internal change: 64377731
https://codereview.chromium.org/232433002/
Add test-only MakeAckFrame method to quic_test_utils, and remove the
test-only QuicAckFrame constructor which was not using the 2nd argument.
Used MakeAckFrame method in chrome specific code also.
Merge internal change: 64373111
https://codereview.chromium.org/231863005/
Set the send and receive buffers for the QuicClient and QuicServer to
the default receive window for QUIC's TCP Sender.
QUIC cleanup to create SetSendBufferSize and SetReceiveBufferSize in
QuicSocketUtils.
Merge internal change: 64358078, 64380825
https://codereview.chromium.org/232243003/
Added writer() helper method to QuicConnection.
Made CreateQuicConnection of QuicDispatcher a virtual method and added
helper methods for helper, writer and initial_flow_control_window_bytes.
Merge internal change: 64357422
https://codereview.chromium.org/232013005/
When multiple streams have pending writes in QUICSession, bundle them
into as few packets as possible rather.
Previously the header stream and the body stream were always written in
separate packets.
Fixed chrome specific unit tests to accept extra ack frame.
Merge internal change: 64304809
https://codereview.chromium.org/232013005/
QUIC refactor to use the congestion window directly when calculating the
packet sequence number length, instead of calculating the window
indirectly.
Merge internal change: 64295053
https://codereview.chromium.org/232003003/
Refactor to isolate the PRR logic from the rest of TCPCubicSender.
Merge internal change: 64210335
https://codereview.chromium.org/232173002/
R=rch@chromium.org
Review URL: https://codereview.chromium.org/232463003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@263995 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic/congestion_control')
-rw-r--r-- | net/quic/congestion_control/inter_arrival_sender.cc | 3 | ||||
-rw-r--r-- | net/quic/congestion_control/tcp_cubic_sender.cc | 95 | ||||
-rw-r--r-- | net/quic/congestion_control/tcp_cubic_sender.h | 10 |
3 files changed, 72 insertions, 36 deletions
diff --git a/net/quic/congestion_control/inter_arrival_sender.cc b/net/quic/congestion_control/inter_arrival_sender.cc index 864db7d..0436c20 100644 --- a/net/quic/congestion_control/inter_arrival_sender.cc +++ b/net/quic/congestion_control/inter_arrival_sender.cc @@ -312,7 +312,8 @@ QuicTime::Delta InterArrivalSender::RetransmissionDelay() const { } QuicByteCount InterArrivalSender::GetCongestionWindow() const { - return 0; + // Return an estimate based on the bandwidth and rtt. + return BandwidthEstimate().ToBytesPerPeriod(rtt_stats_->SmoothedRtt()); } void InterArrivalSender::EstimateNewBandwidth(QuicTime feedback_receive_time, diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc index b08e3c6..2753172 100644 --- a/net/quic/congestion_control/tcp_cubic_sender.cc +++ b/net/quic/congestion_control/tcp_cubic_sender.cc @@ -34,6 +34,7 @@ TcpCubicSender::TcpCubicSender( : hybrid_slow_start_(clock), cubic_(clock, stats), rtt_stats_(rtt_stats), + stats_(stats), reno_(reno), congestion_window_count_(0), receive_window_(kDefaultReceiveWindow), @@ -47,6 +48,7 @@ TcpCubicSender::TcpCubicSender( largest_sent_at_last_cutback_(0), congestion_window_(kInitialCongestionWindow), slowstart_threshold_(max_tcp_congestion_window), + last_cutback_exited_slowstart_(false), max_tcp_congestion_window_(max_tcp_congestion_window) { } @@ -75,10 +77,12 @@ void TcpCubicSender::OnPacketAcked( QuicPacketSequenceNumber acked_sequence_number, QuicByteCount acked_bytes) { DCHECK_GE(bytes_in_flight_, acked_bytes); bytes_in_flight_ -= acked_bytes; - prr_delivered_ += acked_bytes; - ++ack_count_since_loss_; largest_acked_sequence_number_ = max(acked_sequence_number, largest_acked_sequence_number_); + if (InRecovery()) { + PrrOnPacketAcked(acked_bytes); + return; + } MaybeIncreaseCwnd(acked_sequence_number); // TODO(ianswett): Should this even be called when not in slow start? hybrid_slow_start_.OnPacketAcked(acked_sequence_number, InSlowStart()); @@ -89,22 +93,19 @@ void TcpCubicSender::OnPacketLost(QuicPacketSequenceNumber sequence_number, // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets // already sent should be treated as a single loss event, since it's expected. if (sequence_number <= largest_sent_at_last_cutback_) { + if (last_cutback_exited_slowstart_) { + ++stats_->slowstart_packets_lost; + } DVLOG(1) << "Ignoring loss for largest_missing:" << sequence_number << " because it was sent prior to the last CWND cutback."; return; } - - // Initialize proportional rate reduction(RFC 6937) variables. - prr_out_ = 0; - bytes_in_flight_before_loss_ = bytes_in_flight_; - // Since all losses are triggered by an incoming ack currently, and acks are - // registered before losses by the SentPacketManager, initialize the variables - // as though one ack was received directly after the loss. This is too low - // for stretch acks, but we expect missing packets to be immediately acked. - // This ensures 1 or 2 packets are immediately able to be sent, depending upon - // whether we're in PRR or PRR-SSRB mode. - prr_delivered_ = kMaxPacketSize; - ack_count_since_loss_ = 1; + ++stats_->tcp_loss_events; + last_cutback_exited_slowstart_ = InSlowStart(); + if (InSlowStart()) { + ++stats_->slowstart_packets_lost; + } + PrrOnPacketLost(); // In a normal TCP we would need to know the lowest missing packet to detect // if we receive 3 missing packets. Here we get a missing packet for which we @@ -163,24 +164,10 @@ QuicTime::Delta TcpCubicSender::TimeUntilSend( // tail loss probe (draft-dukkipati-tcpm-tcp-loss-probe-01). return QuicTime::Delta::Zero(); } - if (AvailableSendWindow() > 0) { - // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead - // of sending the entire available window. This prevents burst retransmits - // when more packets are lost than the CWND reduction. - // limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS - if (InRecovery() && - prr_delivered_ + ack_count_since_loss_ * kMaxSegmentSize < prr_out_) { - return QuicTime::Delta::Infinite(); - } - return QuicTime::Delta::Zero(); + if (InRecovery()) { + return PrrTimeUntilSend(); } - // Implement Proportional Rate Reduction (RFC6937) - // Checks a simplified version of the PRR formula that doesn't use division: - // AvailableSendWindow = - // CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent - if (InRecovery() && - prr_delivered_ * slowstart_threshold_ * kMaxSegmentSize > - prr_out_ * bytes_in_flight_before_loss_) { + if (AvailableSendWindow() > 0) { return QuicTime::Delta::Zero(); } return QuicTime::Delta::Infinite(); @@ -236,15 +223,12 @@ bool TcpCubicSender::InRecovery() const { // represents, but quic has a separate ack for each packet. void TcpCubicSender::MaybeIncreaseCwnd( QuicPacketSequenceNumber acked_sequence_number) { + LOG_IF(DFATAL, InRecovery()) << "Never increase the CWND during recovery."; if (!IsCwndLimited()) { // We don't update the congestion window unless we are close to using the // window we have available. return; } - if (acked_sequence_number <= largest_sent_at_last_cutback_) { - // We don't increase the congestion window during recovery. - return; - } if (InSlowStart()) { // congestion_window_cnt is the number of acks since last change of snd_cwnd if (congestion_window_ < max_tcp_congestion_window_) { @@ -297,4 +281,45 @@ void TcpCubicSender::UpdateRtt(QuicTime::Delta rtt) { } } +void TcpCubicSender::PrrOnPacketLost() { + prr_out_ = 0; + bytes_in_flight_before_loss_ = bytes_in_flight_; + // Since all losses are triggered by an incoming ack currently, and acks are + // registered before losses by the SentPacketManager, initialize the variables + // as though one ack was received directly after the loss. This is too low + // for stretch acks, but we expect missing packets to be immediately acked. + // This ensures 1 or 2 packets are immediately able to be sent, depending upon + // whether we're in PRR or PRR-SSRB mode. + prr_delivered_ = kMaxPacketSize; + ack_count_since_loss_ = 1; +} + +void TcpCubicSender::PrrOnPacketAcked(QuicByteCount acked_bytes) { + prr_delivered_ += acked_bytes; + ++ack_count_since_loss_; +} + +QuicTime::Delta TcpCubicSender::PrrTimeUntilSend() { + DCHECK(InRecovery()); + if (AvailableSendWindow() > 0) { + // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead + // of sending the entire available window. This prevents burst retransmits + // when more packets are lost than the CWND reduction. + // limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS + if (prr_delivered_ + ack_count_since_loss_ * kMaxSegmentSize < prr_out_) { + return QuicTime::Delta::Infinite(); + } + return QuicTime::Delta::Zero(); + } + // Implement Proportional Rate Reduction (RFC6937) + // Checks a simplified version of the PRR formula that doesn't use division: + // AvailableSendWindow = + // CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent + if (prr_delivered_ * slowstart_threshold_ * kMaxSegmentSize > + prr_out_ * bytes_in_flight_before_loss_) { + return QuicTime::Delta::Zero(); + } + return QuicTime::Delta::Infinite(); +} + } // namespace net diff --git a/net/quic/congestion_control/tcp_cubic_sender.h b/net/quic/congestion_control/tcp_cubic_sender.h index f70511e..14bb9e2 100644 --- a/net/quic/congestion_control/tcp_cubic_sender.h +++ b/net/quic/congestion_control/tcp_cubic_sender.h @@ -75,10 +75,16 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface { void MaybeIncreaseCwnd(QuicPacketSequenceNumber acked_sequence_number); bool IsCwndLimited() const; bool InRecovery() const; + // Methods for isolating PRR from the rest of TCP Cubic. + void PrrOnPacketLost(); + void PrrOnPacketAcked(QuicByteCount acked_bytes); + QuicTime::Delta PrrTimeUntilSend(); + HybridSlowStart hybrid_slow_start_; Cubic cubic_; const RttStats* rtt_stats_; + QuicConnectionStats* stats_; // Reno provided for testing. const bool reno_; @@ -115,6 +121,10 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface { // Slow start congestion window in packets, aka ssthresh. QuicTcpCongestionWindow slowstart_threshold_; + // Whether the last loss event caused us to exit slowstart. + // Used for stats collection of slowstart_packets_lost + bool last_cutback_exited_slowstart_; + // Maximum number of outstanding packets for tcp. QuicTcpCongestionWindow max_tcp_congestion_window_; |