Skip to content

Commit

Permalink
[202012][MuxOrch] disable pfcwd when switching over
Browse files Browse the repository at this point in the history
Why I did it:
to improve switchover performance

How I did it:
Added stopPFCWdOnAllPorts and startPFCWdOnAllPorts
function in PFCWdSwOrch. On each switchover, PFC Wd is stopped unless
there is a storm currently on the port. Then when switchover is
completed, PFC Wd is enabled again

How to test:
$ pytest test_mux.py::TestMuxTunnel::test_mux_pfcwd_switching

Signed-off-by: Nikola Dancejic <[email protected]>
  • Loading branch information
Ndancejic committed Oct 27, 2022
1 parent 08711a8 commit 32df126
Show file tree
Hide file tree
Showing 5 changed files with 336 additions and 15 deletions.
18 changes: 18 additions & 0 deletions orchagent/muxorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "routeorch.h"
#include "fdborch.h"
#include "qosorch.h"
#include "pfcwdorch.h"

/* Global variables */
extern Directory<Orch*> gDirectory;
Expand All @@ -34,6 +35,7 @@ extern AclOrch *gAclOrch;
extern PortsOrch *gPortsOrch;
extern FdbOrch *gFdbOrch;
extern QosOrch *gQosOrch;
extern PfcWdSwOrch<PfcWdActionHandler,PfcWdActionHandler> *gPfcWdSwOrch;

extern sai_object_id_t gVirtualRouterId;
extern sai_object_id_t gUnderlayIfId;
Expand Down Expand Up @@ -476,6 +478,7 @@ void MuxCable::setState(string new_state)
SWSS_LOG_INFO("Changed state to %s", new_state.c_str());

mux_cb_orch_->updateMuxState(mux_name_, new_state);

return;
}

Expand Down Expand Up @@ -1495,6 +1498,10 @@ bool MuxCableOrch::addOperation(const Request& request)
auto state = request.getAttrString("state");
auto mux_obj = mux_orch->getMuxCable(port_name);

/* Disable Pfc Watchdog for perfomance */
SWSS_LOG_INFO("Disabling PFCWD for Mux Switchover on %s", port_name.c_str());
gPfcWdSwOrch->stopWdOnAllPorts();

try
{
mux_obj->setState(state);
Expand All @@ -1505,6 +1512,9 @@ bool MuxCableOrch::addOperation(const Request& request)
state.c_str(), port_name.c_str(), error.what());
return true;
}
/* Enable Pfc Watchdog */
SWSS_LOG_INFO("Enabling PFCWD for Mux Switchover on %s", port_name.c_str());
gPfcWdSwOrch->startWdOnAllPorts();

SWSS_LOG_NOTICE("Mux State set to %s for port %s", state.c_str(), port_name.c_str());

Expand All @@ -1531,10 +1541,18 @@ MuxStateOrch::MuxStateOrch(DBConnector *db, const std::string& tableName) :

void MuxStateOrch::updateMuxState(string portName, string muxState)
{
/* Disable Pfc Watchdog for perfomance */
SWSS_LOG_INFO("Disabling PFCWD for Mux Switchover on %s", portName.c_str());
gPfcWdSwOrch->stopWdOnAllPorts();

vector<FieldValueTuple> tuples;
FieldValueTuple tuple("state", muxState);
tuples.push_back(tuple);
mux_state_table_.set(portName, tuples);

/* Enable Pfc Watchdog */
SWSS_LOG_INFO("Enabling PFCWD for Mux Switchover on %s", portName.c_str());
gPfcWdSwOrch->startWdOnAllPorts();
}

bool MuxStateOrch::addOperation(const Request& request)
Expand Down
46 changes: 31 additions & 15 deletions orchagent/orchdaemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Directory<Orch*> gDirectory;
NatOrch *gNatOrch;
BfdOrch *gBfdOrch;
QosOrch *gQosOrch;
PfcWdSwOrch<PfcWdActionHandler,PfcWdActionHandler> *gPfcWdSwOrch;

bool gIsNatSupported = false;
bool gSaiRedisLogRotate = false;
Expand Down Expand Up @@ -376,13 +377,16 @@ bool OrchDaemon::init()

static const vector<sai_queue_attr_t> queueAttrIds;

m_orchList.push_back(new PfcWdSwOrch<PfcWdZeroBufferHandler, PfcWdLossyHandler>(
gPfcWdSwOrch = (PfcWdSwOrch<PfcWdActionHandler,PfcWdActionHandler> *)
new PfcWdSwOrch<PfcWdZeroBufferHandler, PfcWdLossyHandler>(
m_configDb,
pfc_wd_tables,
portStatIds,
queueStatIds,
queueAttrIds,
PFC_WD_POLL_MSECS));
PFC_WD_POLL_MSECS);

m_orchList.push_back(gPfcWdSwOrch);
}
else if ((platform == INVM_PLATFORM_SUBSTRING)
|| (platform == CLX_PLATFORM_SUBSTRING)
Expand Down Expand Up @@ -421,23 +425,29 @@ bool OrchDaemon::init()
if ((platform == INVM_PLATFORM_SUBSTRING) || (platform == NPS_PLATFORM_SUBSTRING)
|| (platform == CLX_PLATFORM_SUBSTRING))
{
m_orchList.push_back(new PfcWdSwOrch<PfcWdZeroBufferHandler, PfcWdLossyHandler>(
gPfcWdSwOrch = (PfcWdSwOrch<PfcWdActionHandler,PfcWdActionHandler> *)
new PfcWdSwOrch<PfcWdZeroBufferHandler, PfcWdLossyHandler>(
m_configDb,
pfc_wd_tables,
portStatIds,
queueStatIds,
queueAttrIds,
PFC_WD_POLL_MSECS));
PFC_WD_POLL_MSECS);

m_orchList.push_back(gPfcWdSwOrch);
}
else if (platform == BFN_PLATFORM_SUBSTRING)
{
m_orchList.push_back(new PfcWdSwOrch<PfcWdAclHandler, PfcWdLossyHandler>(
gPfcWdSwOrch = (PfcWdSwOrch<PfcWdActionHandler,PfcWdActionHandler> *)
new PfcWdSwOrch<PfcWdAclHandler, PfcWdLossyHandler>(
m_configDb,
pfc_wd_tables,
portStatIds,
queueStatIds,
queueAttrIds,
PFC_WD_POLL_MSECS));
PFC_WD_POLL_MSECS);

m_orchList.push_back(gPfcWdSwOrch);
}
}
else if (platform == BRCM_PLATFORM_SUBSTRING)
Expand Down Expand Up @@ -473,13 +483,16 @@ bool OrchDaemon::init()
SAI_QUEUE_ATTR_PAUSE_STATUS,
};

m_orchList.push_back(new PfcWdSwOrch<PfcWdAclHandler, PfcWdLossyHandler>(
m_configDb,
pfc_wd_tables,
portStatIds,
queueStatIds,
queueAttrIds,
PFC_WD_POLL_MSECS));
gPfcWdSwOrch = (PfcWdSwOrch<PfcWdActionHandler,PfcWdActionHandler> *)
new PfcWdSwOrch<PfcWdAclHandler, PfcWdLossyHandler>(
m_configDb,
pfc_wd_tables,
portStatIds,
queueStatIds,
queueAttrIds,
PFC_WD_POLL_MSECS);

m_orchList.push_back(gPfcWdSwOrch);
} else if (platform == CISCO_8000_PLATFORM_SUBSTRING)
{
static const vector<sai_port_stat_t> portStatIds;
Expand All @@ -494,13 +507,16 @@ bool OrchDaemon::init()
SAI_QUEUE_ATTR_PAUSE_STATUS,
};

m_orchList.push_back(new PfcWdSwOrch<PfcWdSaiDlrInitHandler, PfcWdActionHandler>(
gPfcWdSwOrch = (PfcWdSwOrch<PfcWdActionHandler,PfcWdActionHandler> *)
new PfcWdSwOrch<PfcWdSaiDlrInitHandler, PfcWdActionHandler>(
m_configDb,
pfc_wd_tables,
portStatIds,
queueStatIds,
queueAttrIds,
PFC_WD_POLL_MSECS));
PFC_WD_POLL_MSECS);

m_orchList.push_back(gPfcWdSwOrch);
}

m_orchList.push_back(&CounterCheckOrch::getInstance(m_configDb));
Expand Down
146 changes: 146 additions & 0 deletions orchagent/pfcwdorch.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <limits.h>
#include <inttypes.h>
#include <unordered_map>
#include <tuple>
#include "pfcwdorch.h"
#include "sai_serialize.h"
#include "portsorch.h"
Expand Down Expand Up @@ -754,6 +755,151 @@ bool PfcWdSwOrch<DropHandler, ForwardHandler>::stopWdOnPort(const Port& port)
return true;
}

template <typename DropHandler, typename ForwardHandler>
bool PfcWdSwOrch<DropHandler, ForwardHandler>::continueWdOnPort(const Port& port)
{
SWSS_LOG_ENTER();

sai_object_id_t queueId = SAI_NULL_OBJECT_ID;

for (uint8_t i = 0; i < port.m_queue_ids.size(); i++)
{
queueId = port.m_queue_ids[i];

auto pos = m_pfcwdconfigs.find(queueId);
if (pos == m_pfcwdconfigs.end()) {
continue;
}

SWSS_LOG_INFO("Starting Wd on port %s", port.m_alias.c_str());
return PfcWdOrch<DropHandler, ForwardHandler>::createEntry(port.m_alias, pos->second);
}
return true;
}

template <typename DropHandler, typename ForwardHandler>
bool PfcWdSwOrch<DropHandler, ForwardHandler>::pauseWdOnPort(const Port& port)
{
SWSS_LOG_ENTER();

uint8_t pfcMask = 0;
sai_object_id_t queueId = SAI_NULL_OBJECT_ID;

for (uint8_t i = 0; i < port.m_queue_ids.size(); i++)
{
queueId = port.m_queue_ids[i];
if ((pfcMask & (1 << i)) == 0 && m_entryMap.find(queueId) == m_entryMap.end())
{
continue;
}

// Store configurations for enabling on all ports next time
// This is per-queue
const string countersKey = this->getCountersTable()->getTableName()
+ this->getCountersTable()->getTableNameSeparator()
+ sai_serialize_object_id(queueId);

uint32_t detection = stoi(*this->getCountersDb()->hget(countersKey, "PFC_WD_DETECTION_TIME"));
uint32_t restoration = stoi(*this->getCountersDb()->hget(countersKey, "PFC_WD_RESTORATION_TIME"));
string action = *this->getCountersDb()->hget(countersKey, "PFC_WD_ACTION");

vector<FieldValueTuple> configs;
configs.push_back(FieldValueTuple(PFC_WD_DETECTION_TIME, to_string(detection/1000)));
configs.push_back(FieldValueTuple(PFC_WD_RESTORATION_TIME, to_string(restoration/1000)));
configs.push_back(FieldValueTuple(PFC_WD_ACTION, action));

m_pfcwdconfigs.emplace(queueId, configs);

// Disable PfcWd on this port
PfcWdOrch<DropHandler, ForwardHandler>::deleteEntry(port.m_alias);
return true;
}

return false;
}

template <typename DropHandler, typename ForwardHandler>
bool PfcWdSwOrch<DropHandler, ForwardHandler>::startWdOnAllPorts()
{
SWSS_LOG_ENTER();

auto allPorts = gPortsOrch->getAllPorts();

for (auto &it: allPorts)
{
Port port = it.second;

if (port.m_type != Port::Type::PHY)
{
continue;
}

continueWdOnPort(port);
}

m_pfcwdconfigs.clear();

return true;
}

template <typename DropHandler, typename ForwardHandler>
bool PfcWdSwOrch<DropHandler, ForwardHandler>::stopWdOnAllPorts()
{
SWSS_LOG_ENTER();

auto allPorts = gPortsOrch->getAllPorts();
for (auto &it: allPorts)
{
Port port = it.second;

if (port.m_type != Port::Type::PHY)
{
continue;
}

// Check if port is currently storming
if (isStormingOnPort(port)) {
SWSS_LOG_INFO("Port %s is storming, skipping", port.m_alias.c_str());
continue;
}

pauseWdOnPort(port);
}

return true;
}

template <typename DropHandler, typename ForwardHandler>
bool PfcWdSwOrch<DropHandler, ForwardHandler>::isStormingOnPort(Port port) {
SWSS_LOG_ENTER();

string status;
sai_object_id_t queueId = SAI_NULL_OBJECT_ID;
uint8_t pfcMask = 0;

for (uint8_t i = 0; i < port.m_queue_ids.size(); i++)
{
queueId = port.m_queue_ids[i];
if ((pfcMask & (1 << i)) == 0 && m_entryMap.find(queueId) == m_entryMap.end())
{
continue;
}

string countersKey = this->getCountersTable()->getTableName()
+ this->getCountersTable()->getTableNameSeparator()
+ sai_serialize_object_id(queueId);

status = *this->getCountersDb()->hget(countersKey, "PFC_WD_STATUS");

if (status == "stormed")
{
SWSS_LOG_NOTICE("Storm active on port %s.", port.m_alias.c_str());
return true;
}
}
return false;
}

template <typename DropHandler, typename ForwardHandler>
void PfcWdSwOrch<DropHandler, ForwardHandler>::doTask(Consumer& consumer)
{
Expand Down
8 changes: 8 additions & 0 deletions orchagent/pfcwdorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class PfcWdSwOrch: public PfcWdOrch<DropHandler, ForwardHandler>
virtual bool startWdOnPort(const Port& port,
uint32_t detectionTime, uint32_t restorationTime, PfcWdAction action);
virtual bool stopWdOnPort(const Port& port);
virtual bool startWdOnAllPorts();
virtual bool stopWdOnAllPorts();

task_process_status createEntry(const string& key, const vector<FieldValueTuple>& data) override;
virtual void doTask(SelectableTimer &timer);
Expand Down Expand Up @@ -118,8 +120,14 @@ class PfcWdSwOrch: public PfcWdOrch<DropHandler, ForwardHandler>
void enableBigRedSwitchMode();
void setBigRedSwitchMode(string value);

bool isStormingOnPort(Port port);
bool continueWdOnPort(const Port& port);
bool pauseWdOnPort(const Port& port);

map<sai_object_id_t, PfcWdQueueEntry> m_entryMap;
map<sai_object_id_t, PfcWdQueueEntry> m_brsEntryMap;
// Track configs during disable
map<sai_object_id_t, vector<FieldValueTuple>> m_pfcwdconfigs;

const vector<sai_port_stat_t> c_portStatIds;
const vector<sai_queue_stat_t> c_queueStatIds;
Expand Down
Loading

0 comments on commit 32df126

Please sign in to comment.