Skip to content

Commit a4b8992

Browse files
authored
[counters] Improve performance by polling only configured ports buffer queue/pg counters (sonic-net#2360)
Propagating sonic-net#2143 with resolved merge conflicts Depends on: sonic-net/sonic-utilities#2239 - What I did Currently in SONiC all ports queue and pg counters are created by default with the max possible amount of counters. This feature change this behavior to poll only configured counters provided by the config DB BUFFER_PG and BUFFER_QUEUE tables. If no tables are present in the DB, no counters will be created for ports. Filter the unwanted queues/pgs returned by SAI API calls and skip the creation of these queue/pg counters. Also allow creating/removing counters on runtime if buffer PG/Queue is configured or removed. - Why I did it Improve performance by filtering unconfigured queue/pg counters on init. - How I verified it Check after enabling the counters, if configured counters created in Counters DB according to the configurations. Add/Remove buffer PG/Queue configurations and observe the corresponding counters created/removed accordingly. New UT added to verify this flow. Signed-off-by: Nazarii Hnydyn <[email protected]>
1 parent 4aaeec9 commit a4b8992

13 files changed

+596
-232
lines changed

orchagent/bufferorch.cpp

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "tokenize.h"
22
#include "bufferorch.h"
3+
#include "directory.h"
34
#include "logger.h"
45
#include "sai_serialize.h"
56
#include "warm_restart.h"
@@ -16,6 +17,7 @@ extern sai_switch_api_t *sai_switch_api;
1617
extern sai_buffer_api_t *sai_buffer_api;
1718

1819
extern PortsOrch *gPortsOrch;
20+
extern Directory<Orch*> gDirectory;
1921
extern sai_object_id_t gSwitchId;
2022

2123
#define BUFFER_POOL_WATERMARK_FLEX_STAT_COUNTER_POLL_MSECS "60000"
@@ -812,6 +814,20 @@ task_process_status BufferOrch::processQueue(KeyOpFieldsValuesTuple &tuple)
812814
return handle_status;
813815
}
814816
}
817+
// create/remove a port queue counter for the queue buffer
818+
else
819+
{
820+
auto flexCounterOrch = gDirectory.get<FlexCounterOrch*>();
821+
auto queues = tokens[1];
822+
if (op == SET_COMMAND && flexCounterOrch->getQueueCountersState())
823+
{
824+
gPortsOrch->createPortBufferQueueCounters(port, queues);
825+
}
826+
else if (op == DEL_COMMAND && flexCounterOrch->getQueueCountersState())
827+
{
828+
gPortsOrch->removePortBufferQueueCounters(port, queues);
829+
}
830+
}
815831
}
816832
}
817833
}
@@ -871,7 +887,7 @@ task_process_status BufferOrch::processPriorityGroup(KeyOpFieldsValuesTuple &tup
871887
if (op == SET_COMMAND)
872888
{
873889
ref_resolve_status resolve_result = resolveFieldRefValue(m_buffer_type_maps, buffer_profile_field_name,
874-
buffer_to_ref_table_map.at(buffer_profile_field_name), tuple,
890+
buffer_to_ref_table_map.at(buffer_profile_field_name), tuple,
875891
sai_buffer_profile, buffer_profile_name);
876892
if (ref_resolve_status::success != resolve_result)
877893
{
@@ -944,6 +960,20 @@ task_process_status BufferOrch::processPriorityGroup(KeyOpFieldsValuesTuple &tup
944960
return handle_status;
945961
}
946962
}
963+
// create or remove a port PG counter for the PG buffer
964+
else
965+
{
966+
auto flexCounterOrch = gDirectory.get<FlexCounterOrch*>();
967+
auto pgs = tokens[1];
968+
if (op == SET_COMMAND && flexCounterOrch->getPgWatermarkCountersState())
969+
{
970+
gPortsOrch->createPortBufferPgCounters(port, pgs);
971+
}
972+
else if (op == DEL_COMMAND && flexCounterOrch->getPgWatermarkCountersState())
973+
{
974+
gPortsOrch->removePortBufferPgCounters(port, pgs);
975+
}
976+
}
947977
}
948978
}
949979
}

orchagent/flexcounterorch.cpp

+179-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "debugcounterorch.h"
1111
#include "directory.h"
1212
#include "copporch.h"
13+
#include <swss/tokenize.h>
1314
#include "routeorch.h"
1415
#include "macsecorch.h"
1516
#include "flowcounterrouteorch.h"
@@ -62,6 +63,8 @@ unordered_map<string, string> flexCounterGroupMap =
6263
FlexCounterOrch::FlexCounterOrch(DBConnector *db, vector<string> &tableNames):
6364
Orch(db, tableNames),
6465
m_flexCounterConfigTable(db, CFG_FLEX_COUNTER_TABLE_NAME),
66+
m_bufferQueueConfigTable(db, CFG_BUFFER_QUEUE_TABLE_NAME),
67+
m_bufferPgConfigTable(db, CFG_BUFFER_PG_TABLE_NAME),
6568
m_flexCounterDb(new DBConnector("FLEX_COUNTER_DB", 0)),
6669
m_flexCounterGroupTable(new ProducerTable(m_flexCounterDb.get(), FLEX_COUNTER_GROUP_TABLE)),
6770
m_gbflexCounterDb(new DBConnector("GB_FLEX_COUNTER_DB", 0)),
@@ -157,11 +160,13 @@ void FlexCounterOrch::doTask(Consumer &consumer)
157160
}
158161
else if(key == QUEUE_KEY)
159162
{
160-
gPortsOrch->generateQueueMap();
163+
gPortsOrch->generateQueueMap(getQueueConfigurations());
164+
m_queue_enabled = true;
161165
}
162166
else if(key == PG_WATERMARK_KEY)
163167
{
164-
gPortsOrch->generatePriorityGroupMap();
168+
gPortsOrch->generatePriorityGroupMap(getPgConfigurations());
169+
m_pg_watermark_enabled = true;
165170
}
166171
}
167172
if(gIntfsOrch && (key == RIF_KEY) && (value == "enable"))
@@ -245,6 +250,16 @@ bool FlexCounterOrch::getPortBufferDropCountersState() const
245250
return m_port_buffer_drop_counter_enabled;
246251
}
247252

253+
bool FlexCounterOrch::getPgWatermarkCountersState() const
254+
{
255+
return m_pg_watermark_enabled;
256+
}
257+
258+
bool FlexCounterOrch::getQueueCountersState() const
259+
{
260+
return m_queue_enabled;
261+
}
262+
248263
bool FlexCounterOrch::bake()
249264
{
250265
/*
@@ -286,3 +301,165 @@ bool FlexCounterOrch::bake()
286301
Consumer* consumer = dynamic_cast<Consumer *>(getExecutor(CFG_FLEX_COUNTER_TABLE_NAME));
287302
return consumer->addToSync(entries);
288303
}
304+
305+
map<string, FlexCounterQueueStates> FlexCounterOrch::getQueueConfigurations()
306+
{
307+
SWSS_LOG_ENTER();
308+
309+
map<string, FlexCounterQueueStates> queuesStateVector;
310+
std::vector<std::string> portQueueKeys;
311+
m_bufferQueueConfigTable.getKeys(portQueueKeys);
312+
313+
for (const auto& portQueueKey : portQueueKeys)
314+
{
315+
auto toks = tokenize(portQueueKey, '|');
316+
if (toks.size() != 2)
317+
{
318+
SWSS_LOG_ERROR("Invalid BUFFER_QUEUE key: [%s]", portQueueKey.c_str());
319+
continue;
320+
}
321+
322+
auto configPortNames = tokenize(toks[0], ',');
323+
auto configPortQueues = toks[1];
324+
toks = tokenize(configPortQueues, '-');
325+
326+
for (const auto& configPortName : configPortNames)
327+
{
328+
uint32_t maxQueueNumber = gPortsOrch->getNumberOfPortSupportedQueueCounters(configPortName);
329+
uint32_t maxQueueIndex = maxQueueNumber - 1;
330+
uint32_t minQueueIndex = 0;
331+
332+
if (!queuesStateVector.count(configPortName))
333+
{
334+
FlexCounterQueueStates flexCounterQueueState(maxQueueNumber);
335+
queuesStateVector.insert(make_pair(configPortName, flexCounterQueueState));
336+
}
337+
338+
try {
339+
auto startIndex = to_uint<uint32_t>(toks[0], minQueueIndex, maxQueueIndex);
340+
if (toks.size() > 1)
341+
{
342+
auto endIndex = to_uint<uint32_t>(toks[1], minQueueIndex, maxQueueIndex);
343+
queuesStateVector.at(configPortName).enableQueueCounters(startIndex, endIndex);
344+
}
345+
else
346+
{
347+
queuesStateVector.at(configPortName).enableQueueCounter(startIndex);
348+
}
349+
} catch (std::invalid_argument const& e) {
350+
SWSS_LOG_ERROR("Invalid queue index [%s] for port [%s]", configPortQueues.c_str(), configPortName.c_str());
351+
continue;
352+
}
353+
}
354+
}
355+
356+
return queuesStateVector;
357+
}
358+
359+
map<string, FlexCounterPgStates> FlexCounterOrch::getPgConfigurations()
360+
{
361+
SWSS_LOG_ENTER();
362+
363+
map<string, FlexCounterPgStates> pgsStateVector;
364+
std::vector<std::string> portPgKeys;
365+
m_bufferPgConfigTable.getKeys(portPgKeys);
366+
367+
for (const auto& portPgKey : portPgKeys)
368+
{
369+
auto toks = tokenize(portPgKey, '|');
370+
if (toks.size() != 2)
371+
{
372+
SWSS_LOG_ERROR("Invalid BUFFER_PG key: [%s]", portPgKey.c_str());
373+
continue;
374+
}
375+
376+
auto configPortNames = tokenize(toks[0], ',');
377+
auto configPortPgs = toks[1];
378+
toks = tokenize(configPortPgs, '-');
379+
380+
for (const auto& configPortName : configPortNames)
381+
{
382+
uint32_t maxPgNumber = gPortsOrch->getNumberOfPortSupportedPgCounters(configPortName);
383+
uint32_t maxPgIndex = maxPgNumber - 1;
384+
uint32_t minPgIndex = 0;
385+
386+
if (!pgsStateVector.count(configPortName))
387+
{
388+
FlexCounterPgStates flexCounterPgState(maxPgNumber);
389+
pgsStateVector.insert(make_pair(configPortName, flexCounterPgState));
390+
}
391+
392+
try {
393+
auto startIndex = to_uint<uint32_t>(toks[0], minPgIndex, maxPgIndex);
394+
if (toks.size() > 1)
395+
{
396+
auto endIndex = to_uint<uint32_t>(toks[1], minPgIndex, maxPgIndex);
397+
pgsStateVector.at(configPortName).enablePgCounters(startIndex, endIndex);
398+
}
399+
else
400+
{
401+
pgsStateVector.at(configPortName).enablePgCounter(startIndex);
402+
}
403+
} catch (std::invalid_argument const& e) {
404+
SWSS_LOG_ERROR("Invalid pg index [%s] for port [%s]", configPortPgs.c_str(), configPortName.c_str());
405+
continue;
406+
}
407+
}
408+
}
409+
410+
return pgsStateVector;
411+
}
412+
413+
FlexCounterQueueStates::FlexCounterQueueStates(uint32_t maxQueueNumber)
414+
{
415+
SWSS_LOG_ENTER();
416+
m_queueStates.resize(maxQueueNumber, false);
417+
}
418+
419+
bool FlexCounterQueueStates::isQueueCounterEnabled(uint32_t index) const
420+
{
421+
SWSS_LOG_ENTER();
422+
return m_queueStates[index];
423+
}
424+
425+
void FlexCounterQueueStates::enableQueueCounters(uint32_t startIndex, uint32_t endIndex)
426+
{
427+
SWSS_LOG_ENTER();
428+
for (uint32_t queueIndex = startIndex; queueIndex <= endIndex; queueIndex++)
429+
{
430+
enableQueueCounter(queueIndex);
431+
}
432+
}
433+
434+
void FlexCounterQueueStates::enableQueueCounter(uint32_t queueIndex)
435+
{
436+
SWSS_LOG_ENTER();
437+
m_queueStates[queueIndex] = true;
438+
}
439+
440+
FlexCounterPgStates::FlexCounterPgStates(uint32_t maxPgNumber)
441+
{
442+
SWSS_LOG_ENTER();
443+
m_pgStates.resize(maxPgNumber, false);
444+
}
445+
446+
bool FlexCounterPgStates::isPgCounterEnabled(uint32_t index) const
447+
{
448+
SWSS_LOG_ENTER();
449+
return m_pgStates[index];
450+
}
451+
452+
void FlexCounterPgStates::enablePgCounters(uint32_t startIndex, uint32_t endIndex)
453+
{
454+
SWSS_LOG_ENTER();
455+
for (uint32_t pgIndex = startIndex; pgIndex <= endIndex; pgIndex++)
456+
{
457+
enablePgCounter(pgIndex);
458+
}
459+
}
460+
461+
void FlexCounterPgStates::enablePgCounter(uint32_t pgIndex)
462+
{
463+
SWSS_LOG_ENTER();
464+
m_pgStates[pgIndex] = true;
465+
}

orchagent/flexcounterorch.h

+32
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,30 @@ extern "C" {
1010
#include "sai.h"
1111
}
1212

13+
class FlexCounterQueueStates
14+
{
15+
public:
16+
FlexCounterQueueStates(uint32_t maxQueueNumber);
17+
bool isQueueCounterEnabled(uint32_t index) const;
18+
void enableQueueCounters(uint32_t startIndex, uint32_t endIndex);
19+
void enableQueueCounter(uint32_t queueIndex);
20+
21+
private:
22+
std::vector<bool> m_queueStates{};
23+
};
24+
25+
class FlexCounterPgStates
26+
{
27+
public:
28+
FlexCounterPgStates(uint32_t maxPgNumber);
29+
bool isPgCounterEnabled(uint32_t index) const;
30+
void enablePgCounters(uint32_t startIndex, uint32_t endIndex);
31+
void enablePgCounter(uint32_t pgIndex);
32+
33+
private:
34+
std::vector<bool> m_pgStates{};
35+
};
36+
1337
class FlexCounterOrch: public Orch
1438
{
1539
public:
@@ -18,6 +42,10 @@ class FlexCounterOrch: public Orch
1842
virtual ~FlexCounterOrch(void);
1943
bool getPortCountersState() const;
2044
bool getPortBufferDropCountersState() const;
45+
bool getPgWatermarkCountersState() const;
46+
bool getQueueCountersState() const;
47+
std::map<std::string, FlexCounterQueueStates> getQueueConfigurations();
48+
std::map<std::string, FlexCounterPgStates> getPgConfigurations();
2149
bool getHostIfTrapCounterState() const {return m_hostif_trap_counter_enabled;}
2250
bool getRouteFlowCountersState() const {return m_route_flow_counter_enabled;}
2351
bool bake() override;
@@ -29,9 +57,13 @@ class FlexCounterOrch: public Orch
2957
std::shared_ptr<ProducerTable> m_gbflexCounterGroupTable = nullptr;
3058
bool m_port_counter_enabled = false;
3159
bool m_port_buffer_drop_counter_enabled = false;
60+
bool m_pg_watermark_enabled = false;
61+
bool m_queue_enabled = false;
3262
bool m_hostif_trap_counter_enabled = false;
3363
bool m_route_flow_counter_enabled = false;
3464
Table m_flexCounterConfigTable;
65+
Table m_bufferQueueConfigTable;
66+
Table m_bufferPgConfigTable;
3567
};
3668

3769
#endif

orchagent/p4orch/tests/fake_flexcounterorch.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
#include "copporch.h"
22
#include "flexcounterorch.h"
33

4-
FlexCounterOrch::FlexCounterOrch(swss::DBConnector *db, std::vector<std::string> &tableNames)
5-
: Orch(db, tableNames), m_flexCounterConfigTable(db, CFG_FLEX_COUNTER_TABLE_NAME)
4+
FlexCounterOrch::FlexCounterOrch(swss::DBConnector *db, std::vector<std::string> &tableNames) :
5+
Orch(db, tableNames),
6+
m_flexCounterConfigTable(db, CFG_FLEX_COUNTER_TABLE_NAME),
7+
m_bufferQueueConfigTable(db, CFG_BUFFER_QUEUE_TABLE_NAME),
8+
m_bufferPgConfigTable(db, CFG_BUFFER_PG_TABLE_NAME)
69
{
710
}
811

0 commit comments

Comments
 (0)