| 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 |