Skip to content

Commit 54725e7

Browse files
wendanilguohan
authored andcommitted
Use pointer to member function to reduce the footprint of collectCounters() (sonic-net#488)
Each time a new counter/attribute type is added to flex counter infrastructure, collectCounters() is tailed with the logic of collecting the stats for the new type. As more and more possible id lists are being added to the flex counter, the collectCounters() member function is becoming bulky to check against all possible id lists, both existing and newly added ones. Current list is already significantly long---port counters, queue counters, queue attributes, pg counters, pg attributes, and buffer pool counters. And most of them are irrelevant to a particular flex counter instance thread. E.g., For buffer pool watermark thread, only buffer pool counters matter, not the rest, port counters, queue counters, queue attributes, pg counters, pg attributes. Improvement: Separate each counter/attribute type to be a member function of FlexCounter with the same function prototype. Have a data member (unordered_map) to maintain pointers to member functions for each flex counter instance, and install only the essential counter collection member functions at the counter/attribute list set operation. Choice of data member structure: Originally considered unordered_set with element T to be a pointer to member function. However, the element type does not support a certain operations, and thus can not be taken as a key, but only as a value. In doing so, we can avoid checking against irrelevant counter/attribute id lists, and keep a fixed size for collectCounters function. Signed-off-by: Wenda Ni <[email protected]>
1 parent 6204031 commit 54725e7

File tree

2 files changed

+117
-2
lines changed

2 files changed

+117
-2
lines changed

syncd/syncd_flex_counter.cpp

+100-2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,20 @@ void FlexCounter::updateFlexCounterStatsMode(
132132
}
133133
}
134134

135+
void FlexCounter::addCollectCountersHandler(const std::string &key, const collect_counters_handler_t &handler)
136+
{
137+
SWSS_LOG_ENTER();
138+
139+
m_collectCountersHandlers.emplace(key, handler);
140+
}
141+
142+
void FlexCounter::removeCollectCountersHandler(const std::string &key)
143+
{
144+
SWSS_LOG_ENTER();
145+
146+
m_collectCountersHandlers.erase(key);
147+
}
148+
135149
/* The current implementation of 'setPortCounterList' and 'setQueueCounterList' are
136150
* not the same. Need to refactor these two functions to have the similar logic.
137151
* Either the full SAI attributes are queried once, or each of the needed counters
@@ -188,6 +202,8 @@ void FlexCounter::setPortCounterList(
188202
auto portCounterIds = std::make_shared<PortCounterIds>(portId, supportedIds);
189203
fc.m_portCounterIdsMap.emplace(portVid, portCounterIds);
190204

205+
fc.addCollectCountersHandler(PORT_COUNTER_ID_LIST, &FlexCounter::collectPortCounters);
206+
191207
// Start flex counter thread in case it was not running due to empty counter IDs map
192208
if (fc.m_pollInterval > 0)
193209
{
@@ -263,6 +279,8 @@ void FlexCounter::setQueueCounterList(
263279
auto queueCounterIds = std::make_shared<QueueCounterIds>(queueId, supportedIds);
264280
fc.m_queueCounterIdsMap.emplace(queueVid, queueCounterIds);
265281

282+
fc.addCollectCountersHandler(QUEUE_COUNTER_ID_LIST, &FlexCounter::collectQueueCounters);
283+
266284
// Start flex counter thread in case it was not running due to empty counter IDs map
267285
if (fc.m_pollInterval > 0)
268286
{
@@ -292,6 +310,8 @@ void FlexCounter::setQueueAttrList(
292310
auto queueAttrIds = std::make_shared<QueueAttrIds>(queueId, attrIds);
293311
fc.m_queueAttrIdsMap.emplace(queueVid, queueAttrIds);
294312

313+
fc.addCollectCountersHandler(QUEUE_ATTR_ID_LIST, &FlexCounter::collectQueueAttrs);
314+
295315
// Start flex counter thread in case it was not running due to empty counter IDs map
296316
if (fc.m_pollInterval > 0)
297317
{
@@ -367,6 +387,8 @@ void FlexCounter::setPriorityGroupCounterList(
367387
auto priorityGroupCounterIds = std::make_shared<IngressPriorityGroupCounterIds>(priorityGroupId, supportedIds);
368388
fc.m_priorityGroupCounterIdsMap.emplace(priorityGroupVid, priorityGroupCounterIds);
369389

390+
fc.addCollectCountersHandler(PG_COUNTER_ID_LIST, &FlexCounter::collectPriorityGroupCounters);
391+
370392
// Start flex counter thread in case it was not running due to empty counter IDs map
371393
if (fc.m_pollInterval > 0)
372394
{
@@ -396,6 +418,8 @@ void FlexCounter::setPriorityGroupAttrList(
396418
auto priorityGroupAttrIds = std::make_shared<IngressPriorityGroupAttrIds>(priorityGroupId, attrIds);
397419
fc.m_priorityGroupAttrIdsMap.emplace(priorityGroupVid, priorityGroupAttrIds);
398420

421+
fc.addCollectCountersHandler(PG_ATTR_ID_LIST, &FlexCounter::collectPriorityGroupAttrs);
422+
399423
// Start flex counter thread in case it was not running due to empty counter IDs map
400424
if (fc.m_pollInterval > 0)
401425
{
@@ -454,6 +478,8 @@ void FlexCounter::setRifCounterList(
454478
auto rifCounterIds = std::make_shared<RifCounterIds>(rifId, supportedIds);
455479
fc.m_rifCounterIdsMap.emplace(rifVid, rifCounterIds);
456480

481+
fc.addCollectCountersHandler(RIF_COUNTER_ID_LIST, &FlexCounter::collectRifCounters);
482+
457483
// Start flex counter thread in case it was not running due to empty counter IDs map
458484
if (fc.m_pollInterval > 0)
459485
{
@@ -523,6 +549,8 @@ void FlexCounter::setBufferPoolCounterList(
523549
auto bufferPoolCounterIds = std::make_shared<BufferPoolCounterIds>(bufferPoolId, supportedIds, bufferPoolStatsMode);
524550
fc.m_bufferPoolCounterIdsMap.emplace(bufferPoolVid, bufferPoolCounterIds);
525551

552+
fc.addCollectCountersHandler(BUFFER_POOL_COUNTER_ID_LIST, &FlexCounter::collectBufferPoolCounters);
553+
526554
// Start flex counter thread in case it was not running due to empty counter IDs map
527555
if (fc.m_pollInterval > 0)
528556
{
@@ -544,6 +572,7 @@ void FlexCounter::removePort(
544572
if (it == fc.m_portCounterIdsMap.end())
545573
{
546574
SWSS_LOG_NOTICE("Trying to remove nonexisting port counter Ids 0x%lx", portVid);
575+
547576
// Remove flex counter if all counter IDs and plugins are unregistered
548577
if (fc.isEmpty())
549578
{
@@ -554,6 +583,10 @@ void FlexCounter::removePort(
554583
}
555584

556585
fc.m_portCounterIdsMap.erase(it);
586+
if (fc.m_portCounterIdsMap.empty())
587+
{
588+
fc.removeCollectCountersHandler(PORT_COUNTER_ID_LIST);
589+
}
557590

558591
// Remove flex counter if all counter IDs and plugins are unregistered
559592
if (fc.isEmpty())
@@ -578,13 +611,21 @@ void FlexCounter::removeQueue(
578611
if (counterIter != fc.m_queueCounterIdsMap.end())
579612
{
580613
fc.m_queueCounterIdsMap.erase(counterIter);
614+
if (fc.m_queueCounterIdsMap.empty())
615+
{
616+
fc.removeCollectCountersHandler(QUEUE_COUNTER_ID_LIST);
617+
}
581618
found = true;
582619
}
583620

584621
auto attrIter = fc.m_queueAttrIdsMap.find(queueVid);
585622
if (attrIter != fc.m_queueAttrIdsMap.end())
586623
{
587624
fc.m_queueAttrIdsMap.erase(attrIter);
625+
if (fc.m_queueAttrIdsMap.empty())
626+
{
627+
fc.removeCollectCountersHandler(QUEUE_ATTR_ID_LIST);
628+
}
588629
found = true;
589630
}
590631

@@ -617,13 +658,21 @@ void FlexCounter::removePriorityGroup(
617658
if (counterIter != fc.m_priorityGroupCounterIdsMap.end())
618659
{
619660
fc.m_priorityGroupCounterIdsMap.erase(counterIter);
661+
if (fc.m_priorityGroupCounterIdsMap.empty())
662+
{
663+
fc.removeCollectCountersHandler(PG_COUNTER_ID_LIST);
664+
}
620665
found = true;
621666
}
622667

623668
auto attrIter = fc.m_priorityGroupAttrIdsMap.find(priorityGroupVid);
624669
if (attrIter != fc.m_priorityGroupAttrIdsMap.end())
625670
{
626671
fc.m_priorityGroupAttrIdsMap.erase(attrIter);
672+
if (fc.m_priorityGroupAttrIdsMap.empty())
673+
{
674+
fc.removeCollectCountersHandler(PG_ATTR_ID_LIST);
675+
}
627676
found = true;
628677
}
629678

@@ -655,6 +704,7 @@ void FlexCounter::removeRif(
655704
if (it == fc.m_rifCounterIdsMap.end())
656705
{
657706
SWSS_LOG_NOTICE("Trying to remove nonexisting router interface counter from Id 0x%lx", rifVid);
707+
658708
// Remove flex counter if all counter IDs and plugins are unregistered
659709
if (fc.isEmpty())
660710
{
@@ -665,6 +715,10 @@ void FlexCounter::removeRif(
665715
}
666716

667717
fc.m_rifCounterIdsMap.erase(it);
718+
if (fc.m_rifCounterIdsMap.empty())
719+
{
720+
fc.removeCollectCountersHandler(RIF_COUNTER_ID_LIST);
721+
}
668722

669723
// Remove flex counter if all counter IDs and plugins are unregistered
670724
if (fc.isEmpty())
@@ -689,6 +743,10 @@ void FlexCounter::removeBufferPool(
689743
if (it != fc.m_bufferPoolCounterIdsMap.end())
690744
{
691745
fc.m_bufferPoolCounterIdsMap.erase(it);
746+
if (fc.m_bufferPoolCounterIdsMap.empty())
747+
{
748+
fc.removeCollectCountersHandler(BUFFER_POOL_COUNTER_ID_LIST);
749+
}
692750
found = true;
693751
}
694752

@@ -943,6 +1001,18 @@ void FlexCounter::collectCounters(
9431001
{
9441002
SWSS_LOG_ENTER();
9451003

1004+
for (const auto &it : m_collectCountersHandlers)
1005+
{
1006+
(this->*(it.second))(countersTable);
1007+
}
1008+
1009+
countersTable.flush();
1010+
}
1011+
1012+
void FlexCounter::collectPortCounters(_In_ swss::Table &countersTable)
1013+
{
1014+
SWSS_LOG_ENTER();
1015+
9461016
// Collect stats for every registered port
9471017
for (const auto &kv: m_portCounterIdsMap)
9481018
{
@@ -978,6 +1048,11 @@ void FlexCounter::collectCounters(
9781048

9791049
countersTable.set(portVidStr, values, "");
9801050
}
1051+
}
1052+
1053+
void FlexCounter::collectQueueCounters(_In_ swss::Table &countersTable)
1054+
{
1055+
SWSS_LOG_ENTER();
9811056

9821057
// Collect stats for every registered queue
9831058
for (const auto &kv: m_queueCounterIdsMap)
@@ -1034,6 +1109,11 @@ void FlexCounter::collectCounters(
10341109

10351110
countersTable.set(queueVidStr, values, "");
10361111
}
1112+
}
1113+
1114+
void FlexCounter::collectQueueAttrs(_In_ swss::Table &countersTable)
1115+
{
1116+
SWSS_LOG_ENTER();
10371117

10381118
// Collect attrs for every registered queue
10391119
for (const auto &kv: m_queueAttrIdsMap)
@@ -1076,6 +1156,11 @@ void FlexCounter::collectCounters(
10761156

10771157
countersTable.set(queueVidStr, values, "");
10781158
}
1159+
}
1160+
1161+
void FlexCounter::collectPriorityGroupCounters(_In_ swss::Table &countersTable)
1162+
{
1163+
SWSS_LOG_ENTER();
10791164

10801165
// Collect stats for every registered ingress priority group
10811166
for (const auto &kv: m_priorityGroupCounterIdsMap)
@@ -1125,6 +1210,11 @@ void FlexCounter::collectCounters(
11251210

11261211
countersTable.set(priorityGroupVidStr, values, "");
11271212
}
1213+
}
1214+
1215+
void FlexCounter::collectPriorityGroupAttrs(_In_ swss::Table &countersTable)
1216+
{
1217+
SWSS_LOG_ENTER();
11281218

11291219
// Collect attrs for every registered priority group
11301220
for (const auto &kv: m_priorityGroupAttrIdsMap)
@@ -1167,6 +1257,11 @@ void FlexCounter::collectCounters(
11671257

11681258
countersTable.set(priorityGroupVidStr, values, "");
11691259
}
1260+
}
1261+
1262+
void FlexCounter::collectRifCounters(_In_ swss::Table &countersTable)
1263+
{
1264+
SWSS_LOG_ENTER();
11701265

11711266
// Collect stats for every registered router interface
11721267
for (const auto &kv: m_rifCounterIdsMap)
@@ -1203,6 +1298,11 @@ void FlexCounter::collectCounters(
12031298

12041299
countersTable.set(rifVidStr, values, "");
12051300
}
1301+
}
1302+
1303+
void FlexCounter::collectBufferPoolCounters(_In_ swss::Table &countersTable)
1304+
{
1305+
SWSS_LOG_ENTER();
12061306

12071307
// Collect stats for every registered buffer pool
12081308
for (const auto &it : m_bufferPoolCounterIdsMap)
@@ -1259,8 +1359,6 @@ void FlexCounter::collectCounters(
12591359

12601360
countersTable.set(sai_serialize_object_id(bufferPoolVid), fvTuples);
12611361
}
1262-
1263-
countersTable.flush();
12641362
}
12651363

12661364
void FlexCounter::runPlugins(

syncd/syncd_flex_counter.h

+17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern "C" {
99
#include <vector>
1010
#include <set>
1111
#include <condition_variable>
12+
#include <unordered_map>
1213
#include "swss/table.h"
1314

1415
class FlexCounter
@@ -198,6 +199,20 @@ class FlexCounter
198199
bool allIdsEmpty();
199200
bool allPluginsEmpty();
200201

202+
typedef void (FlexCounter::*collect_counters_handler_t)(_In_ swss::Table &countersTable);
203+
typedef std::unordered_map<std::string, collect_counters_handler_t> collect_counters_handler_unordered_map_t;
204+
205+
void collectPortCounters(_In_ swss::Table &countersTable);
206+
void collectQueueCounters(_In_ swss::Table &countersTable);
207+
void collectQueueAttrs(_In_ swss::Table &countersTable);
208+
void collectPriorityGroupCounters(_In_ swss::Table &countersTable);
209+
void collectPriorityGroupAttrs(_In_ swss::Table &countersTable);
210+
void collectRifCounters(_In_ swss::Table &countersTable);
211+
void collectBufferPoolCounters(_In_ swss::Table &countersTable);
212+
213+
void addCollectCountersHandler(const std::string &key, const collect_counters_handler_t &handler);
214+
void removeCollectCountersHandler(const std::string &key);
215+
201216
// Key is a Virtual ID
202217
std::map<sai_object_id_t, std::shared_ptr<PortCounterIds>> m_portCounterIdsMap;
203218
std::map<sai_object_id_t, std::shared_ptr<QueueCounterIds>> m_queueCounterIdsMap;
@@ -224,6 +239,8 @@ class FlexCounter
224239
std::string m_instanceId;
225240
sai_stats_mode_t m_statsMode;
226241
bool m_enable = false;
242+
243+
collect_counters_handler_unordered_map_t m_collectCountersHandlers;
227244
};
228245

229246
#endif

0 commit comments

Comments
 (0)