Skip to content

Commit eba212d

Browse files
authored
[Counters] Improve performance by polling only configured ports buffer queue/pg counters (sonic-net#2143)
- 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: Shlomi Bitton <[email protected]>
1 parent 9999dae commit eba212d

11 files changed

+556
-223
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"
@@ -948,6 +950,20 @@ task_process_status BufferOrch::processQueue(KeyOpFieldsValuesTuple &tuple)
948950
return handle_status;
949951
}
950952
}
953+
// create/remove a port queue counter for the queue buffer
954+
else
955+
{
956+
auto flexCounterOrch = gDirectory.get<FlexCounterOrch*>();
957+
auto queues = tokens[1];
958+
if (op == SET_COMMAND && flexCounterOrch->getQueueCountersState())
959+
{
960+
gPortsOrch->createPortBufferQueueCounters(port, queues);
961+
}
962+
else if (op == DEL_COMMAND && flexCounterOrch->getQueueCountersState())
963+
{
964+
gPortsOrch->removePortBufferQueueCounters(port, queues);
965+
}
966+
}
951967
}
952968
}
953969
}
@@ -1007,7 +1023,7 @@ task_process_status BufferOrch::processPriorityGroup(KeyOpFieldsValuesTuple &tup
10071023
if (op == SET_COMMAND)
10081024
{
10091025
ref_resolve_status resolve_result = resolveFieldRefValue(m_buffer_type_maps, buffer_profile_field_name,
1010-
buffer_to_ref_table_map.at(buffer_profile_field_name), tuple,
1026+
buffer_to_ref_table_map.at(buffer_profile_field_name), tuple,
10111027
sai_buffer_profile, buffer_profile_name);
10121028
if (ref_resolve_status::success != resolve_result)
10131029
{
@@ -1087,6 +1103,20 @@ task_process_status BufferOrch::processPriorityGroup(KeyOpFieldsValuesTuple &tup
10871103
return handle_status;
10881104
}
10891105
}
1106+
// create or remove a port PG counter for the PG buffer
1107+
else
1108+
{
1109+
auto flexCounterOrch = gDirectory.get<FlexCounterOrch*>();
1110+
auto pgs = tokens[1];
1111+
if (op == SET_COMMAND && flexCounterOrch->getPgWatermarkCountersState())
1112+
{
1113+
gPortsOrch->createPortBufferPgCounters(port, pgs);
1114+
}
1115+
else if (op == DEL_COMMAND && flexCounterOrch->getPgWatermarkCountersState())
1116+
{
1117+
gPortsOrch->removePortBufferPgCounters(port, pgs);
1118+
}
1119+
}
10901120
}
10911121
}
10921122
}

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 "flowcounterrouteorch.h"
1516

@@ -58,6 +59,8 @@ unordered_map<string, string> flexCounterGroupMap =
5859
FlexCounterOrch::FlexCounterOrch(DBConnector *db, vector<string> &tableNames):
5960
Orch(db, tableNames),
6061
m_flexCounterConfigTable(db, CFG_FLEX_COUNTER_TABLE_NAME),
62+
m_bufferQueueConfigTable(db, CFG_BUFFER_QUEUE_TABLE_NAME),
63+
m_bufferPgConfigTable(db, CFG_BUFFER_PG_TABLE_NAME),
6164
m_flexCounterDb(new DBConnector("FLEX_COUNTER_DB", 0)),
6265
m_flexCounterGroupTable(new ProducerTable(m_flexCounterDb.get(), FLEX_COUNTER_GROUP_TABLE))
6366
{
@@ -144,11 +147,13 @@ void FlexCounterOrch::doTask(Consumer &consumer)
144147
}
145148
else if(key == QUEUE_KEY)
146149
{
147-
gPortsOrch->generateQueueMap();
150+
gPortsOrch->generateQueueMap(getQueueConfigurations());
151+
m_queue_enabled = true;
148152
}
149153
else if(key == PG_WATERMARK_KEY)
150154
{
151-
gPortsOrch->generatePriorityGroupMap();
155+
gPortsOrch->generatePriorityGroupMap(getPgConfigurations());
156+
m_pg_watermark_enabled = true;
152157
}
153158
}
154159
if(gIntfsOrch && (key == RIF_KEY) && (value == "enable"))
@@ -230,6 +235,16 @@ bool FlexCounterOrch::getPortBufferDropCountersState() const
230235
return m_port_buffer_drop_counter_enabled;
231236
}
232237

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

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+
map<string, FlexCounterQueueStates> getQueueConfigurations();
48+
map<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;
@@ -27,9 +55,13 @@ class FlexCounterOrch: public Orch
2755
std::shared_ptr<swss::ProducerTable> m_flexCounterGroupTable = nullptr;
2856
bool m_port_counter_enabled = false;
2957
bool m_port_buffer_drop_counter_enabled = false;
58+
bool m_pg_watermark_enabled = false;
59+
bool m_queue_enabled = false;
3060
bool m_hostif_trap_counter_enabled = false;
3161
bool m_route_flow_counter_enabled = false;
3262
Table m_flexCounterConfigTable;
63+
Table m_bufferQueueConfigTable;
64+
Table m_bufferPgConfigTable;
3365
};
3466

3567
#endif

0 commit comments

Comments
 (0)