Skip to content

Commit

Permalink
Fix HW Write Behavior for Multiswitch Agent HW Test Runs
Browse files Browse the repository at this point in the history
Summary: To properly integrate zero SDK check with agent hw testing in multiswitch mode, I fetch the HwWriteBehavior from StateOperDelta in HwAgent and set the HW write behavior RAII object before applying initial state.

Reviewed By: zechengh09

Differential Revision:
D56329330

Privacy Context Container: L1125642

fbshipit-source-id: efe081f70d7301506fb24e20ab34f704754e96ed
  • Loading branch information
Jeff Kim authored and facebook-github-bot committed May 30, 2024
1 parent ed0d4c6 commit 9117ee4
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 20 deletions.
5 changes: 3 additions & 2 deletions fboss/agent/SwSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,7 @@ void SwSwitch::init(
this, std::move(tunMgr), hwSwitchInitFn, HwWriteBehavior::WRITE, flags);
}

void SwSwitch::init(SwitchFlags flags) {
void SwSwitch::init(const HwWriteBehavior& hwWriteBehavior, SwitchFlags flags) {
/* used for split Software Switch init */
auto initialState = preInit(flags);
initialState->publish();
Expand All @@ -1216,7 +1216,8 @@ void SwSwitch::init(SwitchFlags flags) {
// deleting any cold boot state entries that hwswitch has learned from sdk
if (bootType_ == BootType::WARM_BOOT) {
try {
getHwSwitchHandler()->stateChanged(initialStateDelta, false);
getHwSwitchHandler()->stateChanged(
initialStateDelta, false, hwWriteBehavior);
} catch (const std::exception& ex) {
throw FbossError("Failed to sync initial state to HwSwitch: ", ex.what());
}
Expand Down
4 changes: 3 additions & 1 deletion fboss/agent/SwSwitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,9 @@ class SwSwitch : public HwSwitchCallback {
const HwWriteBehavior& hwWriteBehavior,
SwitchFlags flags = SwitchFlags::DEFAULT);

void init(SwitchFlags flags = SwitchFlags::DEFAULT);
void init(
const HwWriteBehavior& hwWriteBehavior,
SwitchFlags flags = SwitchFlags::DEFAULT);

bool isFullyInitialized() const;

Expand Down
9 changes: 6 additions & 3 deletions fboss/agent/mnpu/MultiSwitchHwSwitchHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ MultiSwitchHwSwitchHandler::stateChanged(
const fsdb::OperDelta& delta,
bool transaction,
const std::shared_ptr<SwitchState>& newState,
const HwWriteBehavior& /* hwWriteBehavior */) {
const HwWriteBehavior& hwWriteBehavior) {
multiswitch::StateOperDelta stateDelta;
{
std::unique_lock<std::mutex> lk(stateUpdateMutex_);
Expand Down Expand Up @@ -126,7 +126,8 @@ MultiSwitchHwSwitchHandler::stateChanged(
prevUpdateSwitchState_,
delta,
transaction,
currOperDeltaSeqNum_);
currOperDeltaSeqNum_,
hwWriteBehavior);
++currOperDeltaSeqNum_;
nextOperDelta_ = &stateDelta;
}
Expand Down Expand Up @@ -327,7 +328,8 @@ void MultiSwitchHwSwitchHandler::fillMultiswitchOperDelta(
const std::shared_ptr<SwitchState>& state,
const fsdb::OperDelta& delta,
bool transaction,
int64_t lastSeqNum) {
int64_t lastSeqNum,
const HwWriteBehavior& hwWriteBehavior) {
// Send full delta if this is first switchstate update.
// Sequence number 0 indicates first update
if (lastSeqNum == 0) {
Expand All @@ -340,6 +342,7 @@ void MultiSwitchHwSwitchHandler::fillMultiswitchOperDelta(
}
stateDelta.transaction() = transaction;
stateDelta.seqNum() = lastSeqNum + 1;
stateDelta.hwWriteBehavior() = hwWriteBehavior;
}

void MultiSwitchHwSwitchHandler::operDeltaAckTimeout() {
Expand Down
3 changes: 2 additions & 1 deletion fboss/agent/mnpu/MultiSwitchHwSwitchHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ class MultiSwitchHwSwitchHandler : public HwSwitchHandler {
const std::shared_ptr<SwitchState>& state,
const fsdb::OperDelta& delta,
bool transaction,
int64_t lastSeqNum);
int64_t lastSeqNum,
const HwWriteBehavior& hwWriteBehavior = HwWriteBehavior::WRITE);
void operDeltaAckTimeout();

SwSwitch* sw_;
Expand Down
17 changes: 12 additions & 5 deletions fboss/agent/mnpu/OperDeltaSyncer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,17 @@ void OperDeltaSyncer::operSyncLoop() {
stateOperDelta.operDelta()->changes()->size()) {
if (*stateOperDelta.isFullState()) {
XLOG(DBG2) << "Received full state oper delta from swswitch";
lastUpdateResult = processFullOperDelta(*stateOperDelta.operDelta());
lastUpdateResult = processFullOperDelta(
*stateOperDelta.operDelta(), *stateOperDelta.hwWriteBehavior());
} else {
auto oldState = hw_->getProgrammedState();
lastUpdateResult = stateOperDelta.transaction().value()
? hw_->stateChangedTransaction(*stateOperDelta.operDelta())
: hw_->stateChanged(*stateOperDelta.operDelta());
? hw_->stateChangedTransaction(
*stateOperDelta.operDelta(),
HwWriteBehaviorRAII(*stateOperDelta.hwWriteBehavior()))
: hw_->stateChanged(
*stateOperDelta.operDelta(),
HwWriteBehaviorRAII(*stateOperDelta.hwWriteBehavior()));
if (lastUpdateResult.changes()->empty()) {
hw_->getPlatform()->stateChanged(
StateDelta(oldState, hw_->getProgrammedState()));
Expand All @@ -137,12 +142,14 @@ void OperDeltaSyncer::operSyncLoop() {
}

fsdb::OperDelta OperDeltaSyncer::processFullOperDelta(
fsdb::OperDelta& operDelta) {
fsdb::OperDelta& operDelta,
const HwWriteBehavior& hwWriteBehavior) {
// Enable deep comparison for full oper delta
DeltaComparison::PolicyRAII policyGuard{DeltaComparison::Policy::DEEP};
auto fullStateDelta = StateDelta(std::make_shared<SwitchState>(), operDelta);
auto delta = StateDelta(hw_->getProgrammedState(), fullStateDelta.newState());
auto appliedState = hw_->stateChanged(delta);
auto appliedState =
hw_->stateChanged(delta, HwWriteBehaviorRAII(hwWriteBehavior));
// return empty oper delta to indicate success. If update was not successful,
// hwswitch would have crashed.
CHECK(isStateDeltaEmpty(StateDelta(fullStateDelta.newState(), appliedState)));
Expand Down
4 changes: 3 additions & 1 deletion fboss/agent/mnpu/OperDeltaSyncer.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ class OperDeltaSyncer {
private:
void initOperDeltaSync();
void operSyncLoop();
fsdb::OperDelta processFullOperDelta(fsdb::OperDelta& operDelta);
fsdb::OperDelta processFullOperDelta(
fsdb::OperDelta& operDelta,
const HwWriteBehavior& hwWriteBehavior = HwWriteBehavior::WRITE);

uint16_t serverPort_;
SwitchID switchId_;
Expand Down
4 changes: 2 additions & 2 deletions fboss/agent/mnpu/SplitSwAgentInitializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ namespace facebook::fboss {

void SplitSwSwitchInitializer::initImpl(
HwSwitchCallback* /* callback */,
const HwWriteBehavior& /* hwWriteBehavior */) {
const HwWriteBehavior& hwWriteBehavior) {
// this blocks until at least one hardware switch is up
sw_->init(setupFlags());
sw_->init(hwWriteBehavior, setupFlags());
}

SplitSwAgentInitializer::SplitSwAgentInitializer() {
Expand Down
8 changes: 4 additions & 4 deletions fboss/agent/test/SwitchHandlerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ TEST_F(SwSwitchHandlerTest, partialUpdateAndFullSync) {
auto delta3 = StateDelta(stateV0, stateV2);

getHwSwitchHandler()->connected(SwitchID(1));
sw_->init(SwitchFlags::DEFAULT);
sw_->init(HwWriteBehavior::WRITE, SwitchFlags::DEFAULT);
sw_->initialConfigApplied(std::chrono::steady_clock::now());
getHwSwitchHandler()->stateChanged(
StateDelta(std::make_shared<SwitchState>(), sw_->getState()), false);
Expand Down Expand Up @@ -396,7 +396,7 @@ TEST_F(SwSwitchHandlerTest, reconnectingHwSwitch) {

getHwSwitchHandler()->connected(SwitchID(1));
getHwSwitchHandler()->connected(SwitchID(2));
sw_->init(SwitchFlags::DEFAULT);
sw_->init(HwWriteBehavior::WRITE, SwitchFlags::DEFAULT);
sw_->initialConfigApplied(std::chrono::steady_clock::now());
getHwSwitchHandler()->stateChanged(
StateDelta(std::make_shared<SwitchState>(), sw_->getState()), false);
Expand Down Expand Up @@ -657,7 +657,7 @@ TEST_F(SwSwitchHandlerTest, initialSync) {
folly::Baton<> client2Baton;
auto sw = sw_.get();
getHwSwitchHandler()->connected(SwitchID(1));
sw_->init(SwitchFlags::DEFAULT);
sw_->init(HwWriteBehavior::WRITE, SwitchFlags::DEFAULT);
getHwSwitchHandler()->stateChanged(
StateDelta(std::make_shared<SwitchState>(), sw->getState()), false);
sw_->initialConfigApplied(std::chrono::steady_clock::now());
Expand Down Expand Up @@ -738,7 +738,7 @@ TEST_F(SwSwitchHandlerTest, initialSyncSwSwitchNotConfigured) {
std::thread clientRequestThread1([&]() { clientThreadBody(1); });
std::thread clientRequestThread2([&]() { clientThreadBody(2); });
getHwSwitchHandler()->waitUntilHwSwitchConnected();
sw_->init(SwitchFlags::DEFAULT);
sw_->init(HwWriteBehavior::WRITE, SwitchFlags::DEFAULT);
getHwSwitchHandler()->stateChanged(
StateDelta(std::make_shared<SwitchState>(), sw->getState()), false);
sw_->initialConfigApplied(std::chrono::steady_clock::now());
Expand Down
2 changes: 1 addition & 1 deletion fboss/agent/test/TestUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ std::unique_ptr<SwSwitch> setupMockSwitchWithoutHW(
std::make_pair<std::string, std::string>("multi_switch", "true");
thrift.defaultCommandLineArgs()->emplace(std::move(multiSwitch));
swSwitch->setConfig(std::make_unique<AgentConfig>(thrift));
swSwitch->init(SwitchFlags::DEFAULT);
swSwitch->init(HwWriteBehavior::WRITE, SwitchFlags::DEFAULT);
swSwitch->applyConfig("initial config", *config);
swSwitch->initialConfigApplied(std::chrono::steady_clock::now());
return swSwitch;
Expand Down

0 comments on commit 9117ee4

Please sign in to comment.