Fix the bug where loss parameters are chosen but not applied in loss algorithms. protected by existing --gfe2_reloadable_flag_quic_enable_loss_detection_experiment_at_gfe. PiperOrigin-RevId: 313824964 Change-Id: If1a12d46a04ae54383347ac5b0494f7e8f2a3216
diff --git a/quic/core/congestion_control/uber_loss_algorithm.cc b/quic/core/congestion_control/uber_loss_algorithm.cc index 6fd23d6..28463cb 100644 --- a/quic/core/congestion_control/uber_loss_algorithm.cc +++ b/quic/core/congestion_control/uber_loss_algorithm.cc
@@ -103,6 +103,21 @@ } tuner_started_ = tuner_->Start(&tuned_parameters_); + if (!tuner_started_) { + return; + } + + if (tuned_parameters_.reordering_shift.has_value() && + tuned_parameters_.reordering_threshold.has_value()) { + QUIC_DLOG(INFO) << "Setting reordering shift to " + << *tuned_parameters_.reordering_shift + << ", and reordering threshold to " + << *tuned_parameters_.reordering_threshold; + SetReorderingShift(*tuned_parameters_.reordering_shift); + SetReorderingThreshold(*tuned_parameters_.reordering_threshold); + } else { + QUIC_BUG << "Tuner started but some parameters are missing"; + } } void UberLossAlgorithm::OnConfigNegotiated() {} @@ -153,6 +168,10 @@ return general_loss_algorithms_[APPLICATION_DATA].reordering_threshold(); } +int UberLossAlgorithm::GetPacketReorderingShift() const { + return general_loss_algorithms_[APPLICATION_DATA].reordering_shift(); +} + void UberLossAlgorithm::DisablePacketThresholdForRuntPackets() { for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) { general_loss_algorithms_[i].disable_packet_threshold_for_runt_packets();
diff --git a/quic/core/congestion_control/uber_loss_algorithm.h b/quic/core/congestion_control/uber_loss_algorithm.h index 86b6525..7dacb66 100644 --- a/quic/core/congestion_control/uber_loss_algorithm.h +++ b/quic/core/congestion_control/uber_loss_algorithm.h
@@ -93,12 +93,25 @@ // Always 3 when adaptive reordering is not enabled. QuicPacketCount GetPacketReorderingThreshold() const; + // Get the packet reordering shift from the APPLICATION_DATA PN space. + int GetPacketReorderingShift() const; + // Disable packet threshold loss detection for *runt* packets. void DisablePacketThresholdForRuntPackets(); // Called to reset loss detection of |space|. void ResetLossDetection(PacketNumberSpace space); + bool use_adaptive_reordering_threshold() const { + return general_loss_algorithms_[APPLICATION_DATA] + .use_adaptive_reordering_threshold(); + } + + bool use_adaptive_time_threshold() const { + return general_loss_algorithms_[APPLICATION_DATA] + .use_adaptive_time_threshold(); + } + private: friend class test::QuicSentPacketManagerPeer;
diff --git a/quic/core/congestion_control/uber_loss_algorithm_test.cc b/quic/core/congestion_control/uber_loss_algorithm_test.cc index 6fd949f..318e730 100644 --- a/quic/core/congestion_control/uber_loss_algorithm_test.cc +++ b/quic/core/congestion_control/uber_loss_algorithm_test.cc
@@ -4,9 +4,12 @@ #include "net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h" +#include <memory> #include <utility> #include "net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h" +#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" +#include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" @@ -204,6 +207,137 @@ VerifyLosses(6, packets_acked_, std::vector<uint64_t>{2}); } +class TestLossTuner : public LossDetectionTunerInterface { + public: + TestLossTuner(bool forced_start_result, + LossDetectionParameters forced_parameters) + : forced_start_result_(forced_start_result), + forced_parameters_(std::move(forced_parameters)) {} + + ~TestLossTuner() override = default; + + bool Start(LossDetectionParameters* params) override { + start_called_ = true; + *params = forced_parameters_; + return forced_start_result_; + } + + void Finish(const LossDetectionParameters& /*params*/) override {} + + bool start_called() const { return start_called_; } + + private: + bool forced_start_result_; + LossDetectionParameters forced_parameters_; + bool start_called_ = false; +}; + +// Verify the parameters are changed if first call SetFromConfig(), then call +// OnMinRttAvailable(). +TEST_F(UberLossAlgorithmTest, LossDetectionTuning_SetFromConfigFirst) { + const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift(); + const QuicPacketCount old_reordering_threshold = + loss_algorithm_.GetPacketReorderingThreshold(); + + // Not owned. + TestLossTuner* test_tuner = new TestLossTuner( + /*forced_start_result=*/true, + LossDetectionParameters{ + /*reordering_shift=*/old_reordering_shift + 1, + /*reordering_threshold=*/old_reordering_threshold * 2}); + loss_algorithm_.SetLossDetectionTuner( + std::unique_ptr<LossDetectionTunerInterface>(test_tuner)); + + QuicConfig config; + QuicTagVector connection_options; + connection_options.push_back(kELDT); + config.SetInitialReceivedConnectionOptions(connection_options); + loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER); + + // MinRtt was not available when SetFromConfig was called. + EXPECT_FALSE(test_tuner->start_called()); + EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift()); + EXPECT_EQ(old_reordering_threshold, + loss_algorithm_.GetPacketReorderingThreshold()); + + // Tuning should start when MinRtt becomes available. + loss_algorithm_.OnMinRttAvailable(); + EXPECT_TRUE(test_tuner->start_called()); + EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift()); + EXPECT_NE(old_reordering_threshold, + loss_algorithm_.GetPacketReorderingThreshold()); +} + +// Verify the parameters are changed if first call OnMinRttAvailable(), then +// call SetFromConfig(). +TEST_F(UberLossAlgorithmTest, LossDetectionTuning_OnMinRttAvailableFirst) { + const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift(); + const QuicPacketCount old_reordering_threshold = + loss_algorithm_.GetPacketReorderingThreshold(); + + // Not owned. + TestLossTuner* test_tuner = new TestLossTuner( + /*forced_start_result=*/true, + LossDetectionParameters{ + /*reordering_shift=*/old_reordering_shift + 1, + /*reordering_threshold=*/old_reordering_threshold * 2}); + loss_algorithm_.SetLossDetectionTuner( + std::unique_ptr<LossDetectionTunerInterface>(test_tuner)); + + loss_algorithm_.OnMinRttAvailable(); + EXPECT_FALSE(test_tuner->start_called()); + EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift()); + EXPECT_EQ(old_reordering_threshold, + loss_algorithm_.GetPacketReorderingThreshold()); + + QuicConfig config; + QuicTagVector connection_options; + connection_options.push_back(kELDT); + config.SetInitialReceivedConnectionOptions(connection_options); + // Should start tuning since MinRtt is available. + loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER); + + EXPECT_TRUE(test_tuner->start_called()); + EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift()); + EXPECT_NE(old_reordering_threshold, + loss_algorithm_.GetPacketReorderingThreshold()); +} + +// Verify the parameters are not changed if Tuner.Start() returns false. +TEST_F(UberLossAlgorithmTest, LossDetectionTuning_StartFailed) { + const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift(); + const QuicPacketCount old_reordering_threshold = + loss_algorithm_.GetPacketReorderingThreshold(); + + // Not owned. + TestLossTuner* test_tuner = new TestLossTuner( + /*forced_start_result=*/false, + LossDetectionParameters{ + /*reordering_shift=*/old_reordering_shift + 1, + /*reordering_threshold=*/old_reordering_threshold * 2}); + loss_algorithm_.SetLossDetectionTuner( + std::unique_ptr<LossDetectionTunerInterface>(test_tuner)); + + QuicConfig config; + QuicTagVector connection_options; + connection_options.push_back(kELDT); + config.SetInitialReceivedConnectionOptions(connection_options); + loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER); + + // MinRtt was not available when SetFromConfig was called. + EXPECT_FALSE(test_tuner->start_called()); + EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift()); + EXPECT_EQ(old_reordering_threshold, + loss_algorithm_.GetPacketReorderingThreshold()); + + // Parameters should not change since test_tuner->Start() returns false. + loss_algorithm_.OnMinRttAvailable(); + EXPECT_TRUE(test_tuner->start_called()); + EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift()); + EXPECT_EQ(old_reordering_threshold, + loss_algorithm_.GetPacketReorderingThreshold()); +} + } // namespace } // namespace test } // namespace quic