1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-08-08 09:42:06 +03:00

Fall back to evb timer if no pacer timer set

Reviewed By: kvtsoy

Differential Revision: D65848549

fbshipit-source-id: 38c1e9b8c820dbe2848cb132d7e49079c45eb67d
This commit is contained in:
Crystal Jin
2024-11-13 16:57:21 -08:00
committed by Facebook GitHub Bot
parent a5fd828b90
commit 95898ef8b7
4 changed files with 29 additions and 39 deletions

View File

@@ -2751,23 +2751,18 @@ void QuicTransportBaseLite::setTransportSettings(
} }
return 0us; return 0us;
}); });
if (writeLooper_->hasPacingTimer()) { bool usingBbr =
bool usingBbr = (conn_->transportSettings.defaultCongestionController ==
(conn_->transportSettings.defaultCongestionController == CongestionControlType::BBR ||
CongestionControlType::BBR || conn_->transportSettings.defaultCongestionController ==
conn_->transportSettings.defaultCongestionController == CongestionControlType::BBRTesting ||
CongestionControlType::BBRTesting || conn_->transportSettings.defaultCongestionController ==
conn_->transportSettings.defaultCongestionController == CongestionControlType::BBR2);
CongestionControlType::BBR2); auto minCwnd =
auto minCwnd = usingBbr ? kMinCwndInMssForBbr usingBbr ? kMinCwndInMssForBbr : conn_->transportSettings.minCwndInMss;
: conn_->transportSettings.minCwndInMss; conn_->pacer = std::make_unique<TokenlessPacer>(*conn_, minCwnd);
conn_->pacer = std::make_unique<TokenlessPacer>(*conn_, minCwnd); conn_->pacer->setExperimental(conn_->transportSettings.experimentalPacer);
conn_->pacer->setExperimental(conn_->transportSettings.experimentalPacer); conn_->canBePaced = conn_->transportSettings.pacingEnabledFirstFlight;
conn_->canBePaced = conn_->transportSettings.pacingEnabledFirstFlight;
} else {
LOG(ERROR) << "Pacing cannot be enabled without a timer";
conn_->transportSettings.pacingEnabled = false;
}
} }
setCongestionControl(conn_->transportSettings.defaultCongestionController); setCongestionControl(conn_->transportSettings.defaultCongestionController);
if (conn_->transportSettings.datagramConfig.enabled) { if (conn_->transportSettings.datagramConfig.enabled) {
@@ -2840,8 +2835,7 @@ void QuicTransportBaseLite::validateCongestionAndPacing(
if ((type == CongestionControlType::BBR || if ((type == CongestionControlType::BBR ||
type == CongestionControlType::BBRTesting || type == CongestionControlType::BBRTesting ||
type == CongestionControlType::BBR2) && type == CongestionControlType::BBR2) &&
(!conn_->transportSettings.pacingEnabled || !conn_->transportSettings.pacingEnabled) {
!writeLooper_->hasPacingTimer())) {
LOG(ERROR) << "Unpaced BBR isn't supported"; LOG(ERROR) << "Unpaced BBR isn't supported";
type = CongestionControlType::Cubic; type = CongestionControlType::Cubic;
} }

View File

@@ -3916,12 +3916,12 @@ TEST_F(QuicTransportTest, NotifyPendingWriteConnBufferFreeUpSpace) {
NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data")))); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F(QuicTransportTest, NoPacingTimerNoPacing) { TEST_F(QuicTransportTest, NoPacingTimerStillPaced) {
TransportSettings transportSettings; TransportSettings transportSettings;
transportSettings.pacingEnabled = true; transportSettings.pacingEnabled = true;
transport_->setTransportSettings(transportSettings); transport_->setTransportSettings(transportSettings);
transport_->getConnectionState().canBePaced = true; transport_->getConnectionState().canBePaced = true;
EXPECT_FALSE(isConnectionPaced(transport_->getConnectionState())); EXPECT_TRUE(isConnectionPaced(transport_->getConnectionState()));
} }
TEST_F(QuicTransportTest, SetPacingTimerThenEnablesPacing) { TEST_F(QuicTransportTest, SetPacingTimerThenEnablesPacing) {

View File

@@ -29,10 +29,6 @@ void FunctionLooper::setPacingTimer(QuicTimer::SharedPtr pacingTimer) noexcept {
pacingTimer_ = std::move(pacingTimer); pacingTimer_ = std::move(pacingTimer);
} }
bool FunctionLooper::hasPacingTimer() const noexcept {
return pacingTimer_ != nullptr;
}
void FunctionLooper::setPacingFunction( void FunctionLooper::setPacingFunction(
folly::Function<std::chrono::microseconds()>&& pacingFunc) { folly::Function<std::chrono::microseconds()>&& pacingFunc) {
CHECK(pacingFunc); CHECK(pacingFunc);
@@ -59,12 +55,18 @@ void FunctionLooper::commonLoopBody() noexcept {
} }
bool FunctionLooper::schedulePacingTimeout() noexcept { bool FunctionLooper::schedulePacingTimeout() noexcept {
if (pacingFunc_ && pacingTimer_ && !isTimerCallbackScheduled()) { if (pacingFunc_ && (pacingTimer_ || evb_) && !isTimerCallbackScheduled()) {
auto timeUntilWrite = pacingFunc_(); auto timeUntilWrite = pacingFunc_();
if (timeUntilWrite != 0us) { if (timeUntilWrite != 0us) {
nextPacingTime_ = Clock::now() + timeUntilWrite; nextPacingTime_ = Clock::now() + timeUntilWrite;
pacingTimer_->scheduleTimeout(this, timeUntilWrite); if (pacingTimer_) {
return true; pacingTimer_->scheduleTimeout(this, timeUntilWrite);
return true;
}
if (evb_) {
evb_->scheduleTimeoutHighRes(this, timeUntilWrite);
return true;
}
} }
} }
return false; return false;
@@ -93,13 +95,13 @@ void FunctionLooper::run(bool thisIteration, bool runInline) noexcept {
return; return;
} }
if (isLoopCallbackScheduled() || if (isLoopCallbackScheduled() ||
(!fireLoopEarly_ && pacingTimer_ && isTimerCallbackScheduled())) { (!fireLoopEarly_ && pacingFunc_ && isTimerCallbackScheduled())) {
VLOG(10) << __func__ << ": " << type_ << " already scheduled"; VLOG(10) << __func__ << ": " << type_ << " already scheduled";
return; return;
} }
// If we are pacing, we're about to write again, if it's close, just write // If we are pacing, we're about to write again, if it's close, just write
// now. // now.
if (pacingTimer_ && isTimerCallbackScheduled()) { if (pacingFunc_ && isTimerCallbackScheduled()) {
auto n = Clock::now(); auto n = Clock::now();
auto timeUntilWrite = nextPacingTime_ < n auto timeUntilWrite = nextPacingTime_ < n
? 0us ? 0us
@@ -122,9 +124,7 @@ void FunctionLooper::stop() noexcept {
if (evb_) { if (evb_) {
cancelLoopCallback(); cancelLoopCallback();
} }
if (pacingTimer_) { cancelTimerCallback();
cancelTimerCallback();
}
} }
bool FunctionLooper::isRunning() const { bool FunctionLooper::isRunning() const {
@@ -132,7 +132,7 @@ bool FunctionLooper::isRunning() const {
} }
bool FunctionLooper::isPacingScheduled() { bool FunctionLooper::isPacingScheduled() {
return pacingTimer_ && isTimerCallbackScheduled(); return pacingFunc_ && isTimerCallbackScheduled();
} }
bool FunctionLooper::isLoopCallbackScheduled() { bool FunctionLooper::isLoopCallbackScheduled() {
@@ -150,9 +150,7 @@ void FunctionLooper::detachEventBase() {
VLOG(10) << __func__ << ": " << type_; VLOG(10) << __func__ << ": " << type_;
DCHECK(evb_ && evb_->isInEventBaseThread()); DCHECK(evb_ && evb_->isInEventBaseThread());
stop(); stop();
if (pacingTimer_) { cancelTimerCallback();
cancelTimerCallback();
}
evb_ = nullptr; evb_ = nullptr;
} }

View File

@@ -43,8 +43,6 @@ class FunctionLooper : public QuicEventBaseLoopCallback,
void setPacingTimer(QuicTimer::SharedPtr pacingTimer) noexcept; void setPacingTimer(QuicTimer::SharedPtr pacingTimer) noexcept;
bool hasPacingTimer() const noexcept;
void runLoopCallback() noexcept override; void runLoopCallback() noexcept override;
/** /**