mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-11-09 10:00:57 +03:00
Differentiate ACK_FREQUENCY policy early in connection.
Summary: This changes the experimental behavior of BBR sending ACK_FREQUENCY frames. Now instead of using the static ack eliciting threshold, early in the connection BBR will set the threshold to 2 which has been empirically shown to be a good "initial" value. Reviewed By: jbeshay Differential Revision: D40438721 fbshipit-source-id: 184b8025581b6152eea97f9b557b6343d980322d
This commit is contained in:
committed by
Facebook GitHub Bot
parent
5ed1febddc
commit
c8f357156e
@@ -268,13 +268,27 @@ void BbrCongestionController::onPacketAcked(
|
|||||||
auto updatedMaxAckDelay =
|
auto updatedMaxAckDelay =
|
||||||
std::chrono::duration_cast<std::chrono::milliseconds>(clampMaxAckDelay(
|
std::chrono::duration_cast<std::chrono::milliseconds>(clampMaxAckDelay(
|
||||||
conn_, minRtt() / ackFrequencyConfig->minRttDivisor));
|
conn_, minRtt() / ackFrequencyConfig->minRttDivisor));
|
||||||
if (!lastMaxAckDelay_ || lastMaxAckDelay_.value() != updatedMaxAckDelay) {
|
// If we are either in STARTUP or haven't sent enough packets, based on
|
||||||
|
// config.
|
||||||
|
bool shouldUseInitThreshold =
|
||||||
|
(ackFrequencyConfig->useSmallThresholdDuringStartup &&
|
||||||
|
state_ == BbrState::Startup) ||
|
||||||
|
(!ackFrequencyConfig->useSmallThresholdDuringStartup &&
|
||||||
|
(conn_.lossState.totalAckElicitingPacketsSent <=
|
||||||
|
conn_.transportSettings.rxPacketsBeforeAckInitThreshold));
|
||||||
|
// Default to 2 as the init threshold, which has been shown to be
|
||||||
|
// a good choice empirically.
|
||||||
|
uint32_t ackThreshold =
|
||||||
|
shouldUseInitThreshold ? 2 : ackFrequencyConfig->ackElicitingThreshold;
|
||||||
|
if ((!lastMaxAckDelay_ || lastMaxAckDelay_.value() != updatedMaxAckDelay) ||
|
||||||
|
(!lastAckThreshold_ || lastAckThreshold_.value() != ackThreshold)) {
|
||||||
requestPeerAckFrequencyChange(
|
requestPeerAckFrequencyChange(
|
||||||
conn_,
|
conn_,
|
||||||
ackFrequencyConfig->ackElicitingThreshold,
|
ackThreshold,
|
||||||
updatedMaxAckDelay,
|
updatedMaxAckDelay,
|
||||||
ackFrequencyConfig->reorderingThreshold);
|
ackFrequencyConfig->reorderingThreshold);
|
||||||
lastMaxAckDelay_ = updatedMaxAckDelay;
|
lastMaxAckDelay_ = updatedMaxAckDelay;
|
||||||
|
lastAckThreshold_ = ackThreshold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateCwnd(ack.ackedBytes, excessiveBytes);
|
updateCwnd(ack.ackedBytes, excessiveBytes);
|
||||||
|
|||||||
@@ -311,6 +311,7 @@ class BbrCongestionController : public CongestionController {
|
|||||||
// The last max ACK delay requested, so we don't end up sending
|
// The last max ACK delay requested, so we don't end up sending
|
||||||
// them too frequently.
|
// them too frequently.
|
||||||
folly::Optional<std::chrono::milliseconds> lastMaxAckDelay_;
|
folly::Optional<std::chrono::milliseconds> lastMaxAckDelay_;
|
||||||
|
folly::Optional<uint32_t> lastAckThreshold_;
|
||||||
|
|
||||||
friend std::ostream& operator<<(
|
friend std::ostream& operator<<(
|
||||||
std::ostream& os,
|
std::ostream& os,
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ TEST_F(BbrTest, Recovery) {
|
|||||||
EXPECT_FALSE(bbr.inRecovery());
|
EXPECT_FALSE(bbr.inRecovery());
|
||||||
// Only one update should have been issued.
|
// Only one update should have been issued.
|
||||||
ASSERT_EQ(conn.pendingEvents.frames.size(), 1);
|
ASSERT_EQ(conn.pendingEvents.frames.size(), 1);
|
||||||
AckFrequencyFrame expectedFrame{0, 10, 5000, 3};
|
AckFrequencyFrame expectedFrame{0, 2, 5000, 3};
|
||||||
auto ackFrequencyFrame =
|
auto ackFrequencyFrame =
|
||||||
conn.pendingEvents.frames.front().asAckFrequencyFrame();
|
conn.pendingEvents.frames.front().asAckFrequencyFrame();
|
||||||
EXPECT_EQ(expectedFrame, *ackFrequencyFrame);
|
EXPECT_EQ(expectedFrame, *ackFrequencyFrame);
|
||||||
|
|||||||
@@ -1048,7 +1048,8 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
|
|||||||
val,
|
val,
|
||||||
ackFrequencyConfig.ackElicitingThreshold,
|
ackFrequencyConfig.ackElicitingThreshold,
|
||||||
ackFrequencyConfig.reorderingThreshold,
|
ackFrequencyConfig.reorderingThreshold,
|
||||||
ackFrequencyConfig.minRttDivisor);
|
ackFrequencyConfig.minRttDivisor,
|
||||||
|
ackFrequencyConfig.useSmallThresholdDuringStartup);
|
||||||
// Sanity check the values.
|
// Sanity check the values.
|
||||||
parseSuccess = parseSuccess &&
|
parseSuccess = parseSuccess &&
|
||||||
ackFrequencyConfig.ackElicitingThreshold > 1 &&
|
ackFrequencyConfig.ackElicitingThreshold > 1 &&
|
||||||
@@ -1063,9 +1064,11 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
|
|||||||
"ackElicitingThreshold={}, "
|
"ackElicitingThreshold={}, "
|
||||||
"reorderingThreshold={}, "
|
"reorderingThreshold={}, "
|
||||||
"minRttDivisor={}",
|
"minRttDivisor={}",
|
||||||
|
"useSmallThresholdDuringStartup={}",
|
||||||
ackFrequencyConfig.ackElicitingThreshold,
|
ackFrequencyConfig.ackElicitingThreshold,
|
||||||
ackFrequencyConfig.reorderingThreshold,
|
ackFrequencyConfig.reorderingThreshold,
|
||||||
ackFrequencyConfig.minRttDivisor);
|
ackFrequencyConfig.minRttDivisor,
|
||||||
|
ackFrequencyConfig.useSmallThresholdDuringStartup);
|
||||||
serverTransport->conn_->transportSettings.bbrConfig
|
serverTransport->conn_->transportSettings.bbrConfig
|
||||||
.ackFrequencyConfig = ackFrequencyConfig;
|
.ackFrequencyConfig = ackFrequencyConfig;
|
||||||
serverTransport->conn_->transportSettings.autoAdaptiveForDsr = false;
|
serverTransport->conn_->transportSettings.autoAdaptiveForDsr = false;
|
||||||
|
|||||||
@@ -4805,11 +4805,11 @@ TEST_F(QuicServerTransportTest, TestAckFrequencyPolicyKnobHandler) {
|
|||||||
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
||||||
server->handleKnobParams(
|
server->handleKnobParams(
|
||||||
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
||||||
"1,1,1"}});
|
"1,1,1,1"}});
|
||||||
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
||||||
server->handleKnobParams(
|
server->handleKnobParams(
|
||||||
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
||||||
"10,3,1"}});
|
"10,3,1,1"}});
|
||||||
ASSERT_TRUE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
ASSERT_TRUE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
server->getTransportSettings()
|
server->getTransportSettings()
|
||||||
@@ -4823,31 +4823,35 @@ TEST_F(QuicServerTransportTest, TestAckFrequencyPolicyKnobHandler) {
|
|||||||
server->getTransportSettings()
|
server->getTransportSettings()
|
||||||
.bbrConfig.ackFrequencyConfig->minRttDivisor,
|
.bbrConfig.ackFrequencyConfig->minRttDivisor,
|
||||||
1);
|
1);
|
||||||
|
EXPECT_EQ(
|
||||||
|
server->getTransportSettings()
|
||||||
|
.bbrConfig.ackFrequencyConfig->useSmallThresholdDuringStartup,
|
||||||
|
true);
|
||||||
server->getNonConstConn()
|
server->getNonConstConn()
|
||||||
.transportSettings.bbrConfig.ackFrequencyConfig.reset();
|
.transportSettings.bbrConfig.ackFrequencyConfig.reset();
|
||||||
server->handleKnobParams(
|
server->handleKnobParams(
|
||||||
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
||||||
"10,3,-1"}});
|
"10,3,-1,1"}});
|
||||||
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
||||||
server->handleKnobParams(
|
server->handleKnobParams(
|
||||||
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
||||||
"10,-1,1"}});
|
"10,-1,1,1"}});
|
||||||
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
||||||
server->handleKnobParams(
|
server->handleKnobParams(
|
||||||
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
||||||
"-1,3,1"}});
|
"-1,3,1,1"}});
|
||||||
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
||||||
server->handleKnobParams(
|
server->handleKnobParams(
|
||||||
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
||||||
"10,3,0"}});
|
"10,3,0,1"}});
|
||||||
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
||||||
server->handleKnobParams(
|
server->handleKnobParams(
|
||||||
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
||||||
"10,1,1"}});
|
"10,1,1,1"}});
|
||||||
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
||||||
server->handleKnobParams(
|
server->handleKnobParams(
|
||||||
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
{{static_cast<uint64_t>(TransportKnobParamId::ACK_FREQUENCY_POLICY),
|
||||||
"1,3,1"}});
|
"1,3,1,1"}});
|
||||||
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
EXPECT_FALSE(server->getTransportSettings().bbrConfig.ackFrequencyConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ struct BbrConfig {
|
|||||||
uint64_t ackElicitingThreshold{kDefaultRxPacketsBeforeAckAfterInit};
|
uint64_t ackElicitingThreshold{kDefaultRxPacketsBeforeAckAfterInit};
|
||||||
uint64_t reorderingThreshold{kReorderingThreshold};
|
uint64_t reorderingThreshold{kReorderingThreshold};
|
||||||
uint32_t minRttDivisor{2};
|
uint32_t minRttDivisor{2};
|
||||||
|
// Threshold to use early in the connection.
|
||||||
|
bool useSmallThresholdDuringStartup{false};
|
||||||
};
|
};
|
||||||
folly::Optional<AckFrequencyConfig> ackFrequencyConfig;
|
folly::Optional<AckFrequencyConfig> ackFrequencyConfig;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user