Skip to content

Commit

Permalink
[202205][counters] Improve performance by polling only configured por…
Browse files Browse the repository at this point in the history
…ts buffer queue/pg counters (#2432)

* Filter unconfigured ports buffers queue/pg counters configurations on init

    commit 6f1199a
    Author: Shlomi Bitton <shlomibi@nvidia.com>
    Date:   Sun Jan 2 16:55:58 2022 +0000

    Filter unconfigured ports buffers queue/pg counters configurations on init.
    If no buffer configurations available, no counters will be created.
    Allow creating/removing counters on runtime if buffer PG/Queue is created or removed.
    New UT added to verify new flow.

    Signed-off-by: Shlomi Bitton <shlomibi@nvidia.com>
  • Loading branch information
nazariig authored Sep 8, 2022
1 parent 39f5cdf commit 2c5116e
Show file tree
Hide file tree
Showing 13 changed files with 592 additions and 230 deletions.
1 change: 1 addition & 0 deletions lgtm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extraction:
- flex
- graphviz
- autoconf-archive
- uuid-dev
after_prepare:
- git clone https://github.com/Azure/sonic-buildimage; pushd sonic-buildimage/src/libnl3
- git clone https://github.com/thom311/libnl libnl3-3.5.0; pushd libnl3-3.5.0; git checkout tags/libnl3_5_0
Expand Down
32 changes: 31 additions & 1 deletion orchagent/bufferorch.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "tokenize.h"
#include "bufferorch.h"
#include "directory.h"
#include "logger.h"
#include "sai_serialize.h"
#include "warm_restart.h"
Expand All @@ -16,6 +17,7 @@ extern sai_switch_api_t *sai_switch_api;
extern sai_buffer_api_t *sai_buffer_api;

extern PortsOrch *gPortsOrch;
extern Directory<Orch*> gDirectory;
extern sai_object_id_t gSwitchId;

#define BUFFER_POOL_WATERMARK_FLEX_STAT_COUNTER_POLL_MSECS "60000"
Expand Down Expand Up @@ -815,6 +817,20 @@ task_process_status BufferOrch::processQueue(KeyOpFieldsValuesTuple &tuple)
return handle_status;
}
}
// create/remove a port queue counter for the queue buffer
else
{
auto flexCounterOrch = gDirectory.get<FlexCounterOrch*>();
auto queues = tokens[1];
if (op == SET_COMMAND && flexCounterOrch->getQueueCountersState())
{
gPortsOrch->createPortBufferQueueCounters(port, queues);
}
else if (op == DEL_COMMAND && flexCounterOrch->getQueueCountersState())
{
gPortsOrch->removePortBufferQueueCounters(port, queues);
}
}
}

/* when we apply buffer configuration we need to increase the ref counter of this port
Expand Down Expand Up @@ -907,7 +923,7 @@ task_process_status BufferOrch::processPriorityGroup(KeyOpFieldsValuesTuple &tup
if (op == SET_COMMAND)
{
ref_resolve_status resolve_result = resolveFieldRefValue(m_buffer_type_maps, buffer_profile_field_name,
buffer_to_ref_table_map.at(buffer_profile_field_name), tuple,
buffer_to_ref_table_map.at(buffer_profile_field_name), tuple,
sai_buffer_profile, buffer_profile_name);
if (ref_resolve_status::success != resolve_result)
{
Expand Down Expand Up @@ -980,6 +996,20 @@ task_process_status BufferOrch::processPriorityGroup(KeyOpFieldsValuesTuple &tup
return handle_status;
}
}
// create or remove a port PG counter for the PG buffer
else
{
auto flexCounterOrch = gDirectory.get<FlexCounterOrch*>();
auto pgs = tokens[1];
if (op == SET_COMMAND && flexCounterOrch->getPgWatermarkCountersState())
{
gPortsOrch->createPortBufferPgCounters(port, pgs);
}
else if (op == DEL_COMMAND && flexCounterOrch->getPgWatermarkCountersState())
{
gPortsOrch->removePortBufferPgCounters(port, pgs);
}
}
}
}

Expand Down
181 changes: 179 additions & 2 deletions orchagent/flexcounterorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "debugcounterorch.h"
#include "directory.h"
#include "copporch.h"
#include <swss/tokenize.h>
#include "routeorch.h"
#include "macsecorch.h"
#include "flowcounterrouteorch.h"
Expand Down Expand Up @@ -62,6 +63,8 @@ unordered_map<string, string> flexCounterGroupMap =
FlexCounterOrch::FlexCounterOrch(DBConnector *db, vector<string> &tableNames):
Orch(db, tableNames),
m_flexCounterConfigTable(db, CFG_FLEX_COUNTER_TABLE_NAME),
m_bufferQueueConfigTable(db, CFG_BUFFER_QUEUE_TABLE_NAME),
m_bufferPgConfigTable(db, CFG_BUFFER_PG_TABLE_NAME),
m_flexCounterDb(new DBConnector("FLEX_COUNTER_DB", 0)),
m_flexCounterGroupTable(new ProducerTable(m_flexCounterDb.get(), FLEX_COUNTER_GROUP_TABLE)),
m_gbflexCounterDb(new DBConnector("GB_FLEX_COUNTER_DB", 0)),
Expand Down Expand Up @@ -157,11 +160,13 @@ void FlexCounterOrch::doTask(Consumer &consumer)
}
else if(key == QUEUE_KEY)
{
gPortsOrch->generateQueueMap();
gPortsOrch->generateQueueMap(getQueueConfigurations());
m_queue_enabled = true;
}
else if(key == PG_WATERMARK_KEY)
{
gPortsOrch->generatePriorityGroupMap();
gPortsOrch->generatePriorityGroupMap(getPgConfigurations());
m_pg_watermark_enabled = true;
}
}
if(gIntfsOrch && (key == RIF_KEY) && (value == "enable"))
Expand Down Expand Up @@ -245,6 +250,16 @@ bool FlexCounterOrch::getPortBufferDropCountersState() const
return m_port_buffer_drop_counter_enabled;
}

bool FlexCounterOrch::getPgWatermarkCountersState() const
{
return m_pg_watermark_enabled;
}

bool FlexCounterOrch::getQueueCountersState() const
{
return m_queue_enabled;
}

bool FlexCounterOrch::bake()
{
/*
Expand Down Expand Up @@ -286,3 +301,165 @@ bool FlexCounterOrch::bake()
Consumer* consumer = dynamic_cast<Consumer *>(getExecutor(CFG_FLEX_COUNTER_TABLE_NAME));
return consumer->addToSync(entries);
}

map<string, FlexCounterQueueStates> FlexCounterOrch::getQueueConfigurations()
{
SWSS_LOG_ENTER();

map<string, FlexCounterQueueStates> queuesStateVector;
std::vector<std::string> portQueueKeys;
m_bufferQueueConfigTable.getKeys(portQueueKeys);

for (const auto& portQueueKey : portQueueKeys)
{
auto toks = tokenize(portQueueKey, '|');
if (toks.size() != 2)
{
SWSS_LOG_ERROR("Invalid BUFFER_QUEUE key: [%s]", portQueueKey.c_str());
continue;
}

auto configPortNames = tokenize(toks[0], ',');
auto configPortQueues = toks[1];
toks = tokenize(configPortQueues, '-');

for (const auto& configPortName : configPortNames)
{
uint32_t maxQueueNumber = gPortsOrch->getNumberOfPortSupportedQueueCounters(configPortName);
uint32_t maxQueueIndex = maxQueueNumber - 1;
uint32_t minQueueIndex = 0;

if (!queuesStateVector.count(configPortName))
{
FlexCounterQueueStates flexCounterQueueState(maxQueueNumber);
queuesStateVector.insert(make_pair(configPortName, flexCounterQueueState));
}

try {
auto startIndex = to_uint<uint32_t>(toks[0], minQueueIndex, maxQueueIndex);
if (toks.size() > 1)
{
auto endIndex = to_uint<uint32_t>(toks[1], minQueueIndex, maxQueueIndex);
queuesStateVector.at(configPortName).enableQueueCounters(startIndex, endIndex);
}
else
{
queuesStateVector.at(configPortName).enableQueueCounter(startIndex);
}
} catch (std::invalid_argument const& e) {
SWSS_LOG_ERROR("Invalid queue index [%s] for port [%s]", configPortQueues.c_str(), configPortName.c_str());
continue;
}
}
}

return queuesStateVector;
}

map<string, FlexCounterPgStates> FlexCounterOrch::getPgConfigurations()
{
SWSS_LOG_ENTER();

map<string, FlexCounterPgStates> pgsStateVector;
std::vector<std::string> portPgKeys;
m_bufferPgConfigTable.getKeys(portPgKeys);

for (const auto& portPgKey : portPgKeys)
{
auto toks = tokenize(portPgKey, '|');
if (toks.size() != 2)
{
SWSS_LOG_ERROR("Invalid BUFFER_PG key: [%s]", portPgKey.c_str());
continue;
}

auto configPortNames = tokenize(toks[0], ',');
auto configPortPgs = toks[1];
toks = tokenize(configPortPgs, '-');

for (const auto& configPortName : configPortNames)
{
uint32_t maxPgNumber = gPortsOrch->getNumberOfPortSupportedPgCounters(configPortName);
uint32_t maxPgIndex = maxPgNumber - 1;
uint32_t minPgIndex = 0;

if (!pgsStateVector.count(configPortName))
{
FlexCounterPgStates flexCounterPgState(maxPgNumber);
pgsStateVector.insert(make_pair(configPortName, flexCounterPgState));
}

try {
auto startIndex = to_uint<uint32_t>(toks[0], minPgIndex, maxPgIndex);
if (toks.size() > 1)
{
auto endIndex = to_uint<uint32_t>(toks[1], minPgIndex, maxPgIndex);
pgsStateVector.at(configPortName).enablePgCounters(startIndex, endIndex);
}
else
{
pgsStateVector.at(configPortName).enablePgCounter(startIndex);
}
} catch (std::invalid_argument const& e) {
SWSS_LOG_ERROR("Invalid pg index [%s] for port [%s]", configPortPgs.c_str(), configPortName.c_str());
continue;
}
}
}

return pgsStateVector;
}

FlexCounterQueueStates::FlexCounterQueueStates(uint32_t maxQueueNumber)
{
SWSS_LOG_ENTER();
m_queueStates.resize(maxQueueNumber, false);
}

bool FlexCounterQueueStates::isQueueCounterEnabled(uint32_t index) const
{
SWSS_LOG_ENTER();
return m_queueStates[index];
}

void FlexCounterQueueStates::enableQueueCounters(uint32_t startIndex, uint32_t endIndex)
{
SWSS_LOG_ENTER();
for (uint32_t queueIndex = startIndex; queueIndex <= endIndex; queueIndex++)
{
enableQueueCounter(queueIndex);
}
}

void FlexCounterQueueStates::enableQueueCounter(uint32_t queueIndex)
{
SWSS_LOG_ENTER();
m_queueStates[queueIndex] = true;
}

FlexCounterPgStates::FlexCounterPgStates(uint32_t maxPgNumber)
{
SWSS_LOG_ENTER();
m_pgStates.resize(maxPgNumber, false);
}

bool FlexCounterPgStates::isPgCounterEnabled(uint32_t index) const
{
SWSS_LOG_ENTER();
return m_pgStates[index];
}

void FlexCounterPgStates::enablePgCounters(uint32_t startIndex, uint32_t endIndex)
{
SWSS_LOG_ENTER();
for (uint32_t pgIndex = startIndex; pgIndex <= endIndex; pgIndex++)
{
enablePgCounter(pgIndex);
}
}

void FlexCounterPgStates::enablePgCounter(uint32_t pgIndex)
{
SWSS_LOG_ENTER();
m_pgStates[pgIndex] = true;
}
32 changes: 32 additions & 0 deletions orchagent/flexcounterorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,30 @@ extern "C" {
#include "sai.h"
}

class FlexCounterQueueStates
{
public:
FlexCounterQueueStates(uint32_t maxQueueNumber);
bool isQueueCounterEnabled(uint32_t index) const;
void enableQueueCounters(uint32_t startIndex, uint32_t endIndex);
void enableQueueCounter(uint32_t queueIndex);

private:
std::vector<bool> m_queueStates{};
};

class FlexCounterPgStates
{
public:
FlexCounterPgStates(uint32_t maxPgNumber);
bool isPgCounterEnabled(uint32_t index) const;
void enablePgCounters(uint32_t startIndex, uint32_t endIndex);
void enablePgCounter(uint32_t pgIndex);

private:
std::vector<bool> m_pgStates{};
};

class FlexCounterOrch: public Orch
{
public:
Expand All @@ -18,6 +42,10 @@ class FlexCounterOrch: public Orch
virtual ~FlexCounterOrch(void);
bool getPortCountersState() const;
bool getPortBufferDropCountersState() const;
bool getPgWatermarkCountersState() const;
bool getQueueCountersState() const;
std::map<std::string, FlexCounterQueueStates> getQueueConfigurations();
std::map<std::string, FlexCounterPgStates> getPgConfigurations();
bool getHostIfTrapCounterState() const {return m_hostif_trap_counter_enabled;}
bool getRouteFlowCountersState() const {return m_route_flow_counter_enabled;}
bool bake() override;
Expand All @@ -29,9 +57,13 @@ class FlexCounterOrch: public Orch
shared_ptr<ProducerTable> m_gbflexCounterGroupTable = nullptr;
bool m_port_counter_enabled = false;
bool m_port_buffer_drop_counter_enabled = false;
bool m_pg_watermark_enabled = false;
bool m_queue_enabled = false;
bool m_hostif_trap_counter_enabled = false;
bool m_route_flow_counter_enabled = false;
Table m_flexCounterConfigTable;
Table m_bufferQueueConfigTable;
Table m_bufferPgConfigTable;
};

#endif
36 changes: 26 additions & 10 deletions orchagent/p4orch/tests/fake_portorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,35 @@ bool PortsOrch::setPortPfc(sai_object_id_t portId, uint8_t pfc_bitmask)
return true;
}

void PortsOrch::generateQueueMap()
void PortsOrch::generateQueueMap(std::map<string, FlexCounterQueueStates> queuesStateVector)
{
}

void PortsOrch::generatePriorityGroupMap()
void PortsOrch::generateQueueMapPerPort(const Port& port, FlexCounterQueueStates& queuesState)
{
}

void PortsOrch::createPortBufferQueueCounters(const Port &port, string queues)
{
}

void PortsOrch::removePortBufferQueueCounters(const Port &port, string queues)
{
}

void PortsOrch::generatePriorityGroupMap(std::map<string, FlexCounterPgStates> pgsStateVector)
{
}

void PortsOrch::generatePriorityGroupMapPerPort(const Port& port, FlexCounterPgStates& pgsState)
{
}

void PortsOrch::createPortBufferPgCounters(const Port& port, string pgs)
{
}

void PortsOrch::removePortBufferPgCounters(const Port& port, string pgs)
{
}

Expand Down Expand Up @@ -581,14 +605,6 @@ bool PortsOrch::getQueueTypeAndIndex(sai_object_id_t queue_id, string &type, uin
return true;
}

void PortsOrch::generateQueueMapPerPort(const Port &port)
{
}

void PortsOrch::generatePriorityGroupMapPerPort(const Port &port)
{
}

task_process_status PortsOrch::setPortAutoNeg(sai_object_id_t id, int an)
{
return task_success;
Expand Down
Loading

0 comments on commit 2c5116e

Please sign in to comment.