OLD | NEW |
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 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 | 315 |
316 // Handle logic specific to STARTUP and DRAIN modes. | 316 // Handle logic specific to STARTUP and DRAIN modes. |
317 if (is_round_start && !is_at_full_bandwidth_) { | 317 if (is_round_start && !is_at_full_bandwidth_) { |
318 CheckIfFullBandwidthReached(); | 318 CheckIfFullBandwidthReached(); |
319 } | 319 } |
320 MaybeExitStartupOrDrain(event_time); | 320 MaybeExitStartupOrDrain(event_time); |
321 | 321 |
322 // Handle logic specific to PROBE_RTT. | 322 // Handle logic specific to PROBE_RTT. |
323 MaybeEnterOrExitProbeRtt(event_time, is_round_start, min_rtt_expired); | 323 MaybeEnterOrExitProbeRtt(event_time, is_round_start, min_rtt_expired); |
324 | 324 |
| 325 // Calculate number of packets acked and lost. |
| 326 QuicByteCount bytes_acked = |
| 327 sampler_.total_bytes_acked() - total_bytes_acked_before; |
| 328 QuicByteCount bytes_lost = 0; |
| 329 for (const auto& packet : lost_packets) { |
| 330 bytes_lost += packet.second; |
| 331 } |
| 332 |
325 // After the model is updated, recalculate the pacing rate and congestion | 333 // After the model is updated, recalculate the pacing rate and congestion |
326 // window. | 334 // window. |
327 QuicByteCount bytes_acked = | |
328 sampler_.total_bytes_acked() - total_bytes_acked_before; | |
329 CalculatePacingRate(); | 335 CalculatePacingRate(); |
330 CalculateCongestionWindow(bytes_acked); | 336 CalculateCongestionWindow(bytes_acked); |
331 CalculateRecoveryWindow(bytes_acked); | 337 CalculateRecoveryWindow(bytes_acked, bytes_lost); |
332 | 338 |
333 // Cleanup internal state. | 339 // Cleanup internal state. |
334 sampler_.RemoveObsoletePackets(unacked_packets_->GetLeastUnacked()); | 340 sampler_.RemoveObsoletePackets(unacked_packets_->GetLeastUnacked()); |
335 } | 341 } |
336 | 342 |
337 CongestionControlType BbrSender::GetCongestionControlType() const { | 343 CongestionControlType BbrSender::GetCongestionControlType() const { |
338 return kBBR; | 344 return kBBR; |
339 } | 345 } |
340 | 346 |
341 QuicTime::Delta BbrSender::GetMinRtt() const { | 347 QuicTime::Delta BbrSender::GetMinRtt() const { |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 // Exit recovery when there are no losses for a round. | 552 // Exit recovery when there are no losses for a round. |
547 if (has_losses) { | 553 if (has_losses) { |
548 end_recovery_at_ = last_sent_packet_; | 554 end_recovery_at_ = last_sent_packet_; |
549 } | 555 } |
550 | 556 |
551 switch (recovery_state_) { | 557 switch (recovery_state_) { |
552 case NOT_IN_RECOVERY: | 558 case NOT_IN_RECOVERY: |
553 // Enter conservation on the first loss. | 559 // Enter conservation on the first loss. |
554 if (has_losses) { | 560 if (has_losses) { |
555 recovery_state_ = CONSERVATION; | 561 recovery_state_ = CONSERVATION; |
556 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation) { | 562 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation || |
| 563 FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation2) { |
557 // This will cause the |recovery_window_| to be set to the correct | 564 // This will cause the |recovery_window_| to be set to the correct |
558 // value in CalculateRecoveryWindow(). | 565 // value in CalculateRecoveryWindow(). |
559 recovery_window_ = 0; | 566 recovery_window_ = 0; |
560 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation, 1, | 567 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation, 1, |
561 3); | 568 3); |
| 569 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation2, 1, |
| 570 3); |
562 } | 571 } |
563 // Since the conservation phase is meant to be lasting for a whole | 572 // 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. | 573 // round, extend the current round as if it were started right now. |
565 current_round_trip_end_ = last_sent_packet_; | 574 current_round_trip_end_ = last_sent_packet_; |
566 } | 575 } |
567 break; | 576 break; |
568 | 577 |
569 case CONSERVATION: | 578 case CONSERVATION: |
570 if (is_round_start) { | 579 if (is_round_start) { |
571 recovery_state_ = GROWTH; | 580 recovery_state_ = GROWTH; |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 // If the connection is not yet out of startup phase, do not decrease the | 718 // If the connection is not yet out of startup phase, do not decrease the |
710 // window. | 719 // window. |
711 congestion_window_ = congestion_window_ + bytes_acked; | 720 congestion_window_ = congestion_window_ + bytes_acked; |
712 } | 721 } |
713 | 722 |
714 // Enforce the limits on the congestion window. | 723 // Enforce the limits on the congestion window. |
715 congestion_window_ = std::max(congestion_window_, kMinimumCongestionWindow); | 724 congestion_window_ = std::max(congestion_window_, kMinimumCongestionWindow); |
716 congestion_window_ = std::min(congestion_window_, max_congestion_window_); | 725 congestion_window_ = std::min(congestion_window_, max_congestion_window_); |
717 } | 726 } |
718 | 727 |
719 void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked) { | 728 void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked, |
| 729 QuicByteCount bytes_lost) { |
| 730 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation2) { |
| 731 if (recovery_state_ == NOT_IN_RECOVERY) { |
| 732 return; |
| 733 } |
| 734 |
| 735 // Set up the initial recovery window. |
| 736 if (recovery_window_ == 0) { |
| 737 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation2, 2, 3); |
| 738 recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked; |
| 739 recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_); |
| 740 return; |
| 741 } |
| 742 |
| 743 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation2, 3, 3); |
| 744 |
| 745 // Remove losses from the recovery window, while accounting for a potential |
| 746 // integer underflow. |
| 747 recovery_window_ = recovery_window_ >= bytes_lost |
| 748 ? recovery_window_ - bytes_lost |
| 749 : kMaxSegmentSize; |
| 750 |
| 751 // In CONSERVATION mode, just subtracting losses is sufficient. In GROWTH, |
| 752 // release additional |bytes_acked| to achieve a slow-start-like behavior. |
| 753 if (recovery_state_ == GROWTH) { |
| 754 recovery_window_ += bytes_acked; |
| 755 } |
| 756 |
| 757 // Sanity checks. Ensure that we always allow to send at least |
| 758 // |bytes_acked| in response. |
| 759 recovery_window_ = std::max( |
| 760 recovery_window_, unacked_packets_->bytes_in_flight() + bytes_acked); |
| 761 recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_); |
| 762 return; |
| 763 } |
| 764 |
720 switch (recovery_state_) { | 765 switch (recovery_state_) { |
721 case CONSERVATION: | 766 case CONSERVATION: |
722 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation) { | 767 if (FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation) { |
723 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation, 2, 3); | 768 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_fix_conservation, 2, 3); |
724 recovery_window_ = | 769 recovery_window_ = |
725 std::max(unacked_packets_->bytes_in_flight() + bytes_acked, | 770 std::max(unacked_packets_->bytes_in_flight() + bytes_acked, |
726 recovery_window_); | 771 recovery_window_); |
727 } else { | 772 } else { |
728 recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked; | 773 recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked; |
729 } | 774 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() | 849 os << "Minimum RTT timestamp: " << state.min_rtt_timestamp.ToDebuggingValue() |
805 << std::endl; | 850 << std::endl; |
806 | 851 |
807 os << "Last sample is app-limited: " | 852 os << "Last sample is app-limited: " |
808 << (state.last_sample_is_app_limited ? "yes" : "no"); | 853 << (state.last_sample_is_app_limited ? "yes" : "no"); |
809 | 854 |
810 return os; | 855 return os; |
811 } | 856 } |
812 | 857 |
813 } // namespace net | 858 } // namespace net |
OLD | NEW |