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