Skip to content

Commit 3749e6d

Browse files
authored
Avoid notifying counter polling for duplicated priority groups or queues (#3885)
* Avoid notifying counter polling for duplicated priority groups or queues What I did Avoid notifying counter polling for duplicated PG or queue when create_only_config_db_buffers is False in the flow: Flex counter orchagent enables counter polling for PG or queue. It notifies counter polling for all PGs or queues since create_only_config_db_buffers is False Particular items in BUFFER_PG or BUFFER_QUEUE is configured. It notifies counter polling for the items again. In most cases, BUFFER_PG and BUFFER_QUEUE are handled ahead of counter polling (i.e., the order is 2, 1), and the issue won't occur. But in a rare scenario, it can be 1 and then 2.
1 parent 18b86b1 commit 3749e6d

File tree

7 files changed

+245
-47
lines changed

7 files changed

+245
-47
lines changed

orchagent/bufferorch.cpp

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,18 +1103,21 @@ task_process_status BufferOrch::processQueuePost(const QueueTask& task)
11031103
else if (gMySwitchType != "voq")
11041104
{
11051105
auto flexCounterOrch = gDirectory.get<FlexCounterOrch*>();
1106-
auto queues = tokens[1];
1107-
if (!queueContext.counter_was_added && queueContext.counter_needs_to_add &&
1108-
(flexCounterOrch->getQueueCountersState() || flexCounterOrch->getQueueWatermarkCountersState()))
1106+
if (flexCounterOrch->isCreateOnlyConfigDbBuffers())
11091107
{
1110-
SWSS_LOG_INFO("Creating counters for %s %zd", port_name.c_str(), ind);
1111-
gPortsOrch->createPortBufferQueueCounters(port, queues);
1112-
}
1113-
else if (queueContext.counter_was_added && !queueContext.counter_needs_to_add &&
1114-
(flexCounterOrch->getQueueCountersState() || flexCounterOrch->getQueueWatermarkCountersState()))
1115-
{
1116-
SWSS_LOG_INFO("Removing counters for %s %zd", port_name.c_str(), ind);
1117-
gPortsOrch->removePortBufferQueueCounters(port, queues);
1108+
auto queues = tokens[1];
1109+
if (!queueContext.counter_was_added && queueContext.counter_needs_to_add &&
1110+
(flexCounterOrch->getQueueCountersState() || flexCounterOrch->getQueueWatermarkCountersState()))
1111+
{
1112+
SWSS_LOG_INFO("Creating counters for %s %zd", port_name.c_str(), ind);
1113+
gPortsOrch->createPortBufferQueueCounters(port, queues);
1114+
}
1115+
else if (queueContext.counter_was_added && !queueContext.counter_needs_to_add &&
1116+
(flexCounterOrch->getQueueCountersState() || flexCounterOrch->getQueueWatermarkCountersState()))
1117+
{
1118+
SWSS_LOG_INFO("Removing counters for %s %zd", port_name.c_str(), ind);
1119+
gPortsOrch->removePortBufferQueueCounters(port, queues);
1120+
}
11181121
}
11191122
}
11201123
}
@@ -1471,18 +1474,21 @@ task_process_status BufferOrch::processPriorityGroupPost(const PriorityGroupTask
14711474
else
14721475
{
14731476
auto flexCounterOrch = gDirectory.get<FlexCounterOrch*>();
1474-
auto pgs = tokens[1];
1475-
if (!pg.counter_was_added && pg.counter_needs_to_add &&
1476-
(flexCounterOrch->getPgCountersState() || flexCounterOrch->getPgWatermarkCountersState()))
1477-
{
1478-
SWSS_LOG_INFO("Creating counters for priority group %s %zd", port_name.c_str(), ind);
1479-
gPortsOrch->createPortBufferPgCounters(port, pgs);
1480-
}
1481-
else if (pg.counter_was_added && !pg.counter_needs_to_add &&
1482-
(flexCounterOrch->getPgCountersState() || flexCounterOrch->getPgWatermarkCountersState()))
1477+
if (flexCounterOrch->isCreateOnlyConfigDbBuffers())
14831478
{
1484-
SWSS_LOG_INFO("Removing counters for priority group %s %zd", port_name.c_str(), ind);
1485-
gPortsOrch->removePortBufferPgCounters(port, pgs);
1479+
auto pgs = tokens[1];
1480+
if (!pg.counter_was_added && pg.counter_needs_to_add &&
1481+
(flexCounterOrch->getPgCountersState() || flexCounterOrch->getPgWatermarkCountersState()))
1482+
{
1483+
SWSS_LOG_INFO("Creating counters for priority group %s %zd", port_name.c_str(), ind);
1484+
gPortsOrch->createPortBufferPgCounters(port, pgs);
1485+
}
1486+
else if (pg.counter_was_added && !pg.counter_needs_to_add &&
1487+
(flexCounterOrch->getPgCountersState() || flexCounterOrch->getPgWatermarkCountersState()))
1488+
{
1489+
SWSS_LOG_INFO("Removing counters for priority group %s %zd", port_name.c_str(), ind);
1490+
gPortsOrch->removePortBufferPgCounters(port, pgs);
1491+
}
14861492
}
14871493
}
14881494
}

orchagent/flexcounterorch.cpp

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,24 @@ FlexCounterOrch::FlexCounterOrch(DBConnector *db, vector<string> &tableNames):
9898
m_deviceMetadataConfigTable(db, CFG_DEVICE_METADATA_TABLE_NAME)
9999
{
100100
SWSS_LOG_ENTER();
101+
102+
// Read create_only_config_db_buffers configuration once during initialization
103+
std::string createOnlyConfigDbBuffersValue;
104+
try
105+
{
106+
if (m_deviceMetadataConfigTable.hget("localhost", "create_only_config_db_buffers", createOnlyConfigDbBuffersValue))
107+
{
108+
if (createOnlyConfigDbBuffersValue == "true")
109+
{
110+
m_createOnlyConfigDbBuffers = true;
111+
}
112+
}
113+
}
114+
catch(const std::system_error& e)
115+
{
116+
SWSS_LOG_ERROR("System error reading create_only_config_db_buffers: %s", e.what());
117+
}
118+
101119
m_delayTimer = std::make_unique<SelectableTimer>(timespec{.tv_sec = FLEX_COUNTER_DELAY_SEC, .tv_nsec = 0});
102120
if (WarmStart::isWarmStart())
103121
{
@@ -120,6 +138,13 @@ void FlexCounterOrch::doTask(Consumer &consumer)
120138
{
121139
SWSS_LOG_ENTER();
122140

141+
// Handle DEVICE_METADATA table changes for create_only_config_db_buffers
142+
if (consumer.getTableName() == CFG_DEVICE_METADATA_TABLE_NAME)
143+
{
144+
handleDeviceMetadataTable(consumer);
145+
return;
146+
}
147+
123148
if (!m_delayTimerExpired)
124149
{
125150
return;
@@ -394,39 +419,59 @@ bool FlexCounterOrch::getWredPortCountersState() const
394419
return m_wred_port_counter_enabled;
395420
}
396421

397-
bool FlexCounterOrch::bake()
422+
bool FlexCounterOrch::isCreateOnlyConfigDbBuffers() const
398423
{
399-
/*
400-
* bake is called during warmreboot reconciling procedure.
401-
* By default, it should fetch items from the tables the sub agents listen to,
402-
* and then push them into m_toSync of each sub agent.
403-
* The motivation is to make sub agents handle the saved entries first and then handle the upcoming entries.
404-
* The FCs are not data plane configuration required during reconciling process, hence don't do anything in bake.
405-
*/
406-
407-
return true;
424+
return m_createOnlyConfigDbBuffers;
408425
}
409426

410-
static bool isCreateOnlyConfigDbBuffers(Table& deviceMetadataConfigTable)
427+
void FlexCounterOrch::handleDeviceMetadataTable(Consumer &consumer)
411428
{
412-
std::string createOnlyConfigDbBuffersValue;
429+
SWSS_LOG_ENTER();
413430

414-
try
431+
auto it = consumer.m_toSync.begin();
432+
while (it != consumer.m_toSync.end())
415433
{
416-
if (deviceMetadataConfigTable.hget("localhost", "create_only_config_db_buffers", createOnlyConfigDbBuffersValue))
434+
KeyOpFieldsValuesTuple t = it->second;
435+
string key = kfvKey(t);
436+
string op = kfvOp(t);
437+
auto data = kfvFieldsValues(t);
438+
439+
// Only process localhost entries
440+
if (key == "localhost" && op == SET_COMMAND)
417441
{
418-
if (createOnlyConfigDbBuffersValue == "true")
442+
for (auto valuePair : data)
419443
{
420-
return true;
444+
const auto &field = fvField(valuePair);
445+
const auto &value = fvValue(valuePair);
446+
447+
if (field == "create_only_config_db_buffers")
448+
{
449+
bool newValue = (value == "true");
450+
if (m_createOnlyConfigDbBuffers != newValue)
451+
{
452+
SWSS_LOG_NOTICE("Updating create_only_config_db_buffers from %s to %s",
453+
m_createOnlyConfigDbBuffers ? "true" : "false",
454+
value.c_str());
455+
m_createOnlyConfigDbBuffers = newValue;
456+
}
457+
}
421458
}
422459
}
460+
consumer.m_toSync.erase(it++);
423461
}
424-
catch(const std::system_error& e)
425-
{
426-
SWSS_LOG_ERROR("System error: %s", e.what());
427-
}
462+
}
428463

429-
return false;
464+
bool FlexCounterOrch::bake()
465+
{
466+
/*
467+
* bake is called during warmreboot reconciling procedure.
468+
* By default, it should fetch items from the tables the sub agents listen to,
469+
* and then push them into m_toSync of each sub agent.
470+
* The motivation is to make sub agents handle the saved entries first and then handle the upcoming entries.
471+
* The FCs are not data plane configuration required during reconciling process, hence don't do anything in bake.
472+
*/
473+
474+
return true;
430475
}
431476

432477
map<string, FlexCounterQueueStates> FlexCounterOrch::getQueueConfigurations()
@@ -435,7 +480,7 @@ map<string, FlexCounterQueueStates> FlexCounterOrch::getQueueConfigurations()
435480

436481
map<string, FlexCounterQueueStates> queuesStateVector;
437482

438-
if (!isCreateOnlyConfigDbBuffers(m_deviceMetadataConfigTable))
483+
if (!isCreateOnlyConfigDbBuffers())
439484
{
440485
FlexCounterQueueStates flexCounterQueueState(0);
441486
queuesStateVector.insert(make_pair(createAllAvailableBuffersStr, flexCounterQueueState));
@@ -504,7 +549,7 @@ map<string, FlexCounterPgStates> FlexCounterOrch::getPgConfigurations()
504549

505550
map<string, FlexCounterPgStates> pgsStateVector;
506551

507-
if (!isCreateOnlyConfigDbBuffers(m_deviceMetadataConfigTable))
552+
if (!isCreateOnlyConfigDbBuffers())
508553
{
509554
FlexCounterPgStates flexCounterPgState(0);
510555
pgsStateVector.insert(make_pair(createAllAvailableBuffersStr, flexCounterPgState));

orchagent/flexcounterorch.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,11 @@ class FlexCounterOrch: public Orch
5656
bool getRouteFlowCountersState() const {return m_route_flow_counter_enabled;}
5757
bool getWredQueueCountersState() const;
5858
bool getWredPortCountersState() const;
59+
bool isCreateOnlyConfigDbBuffers() const;
5960
bool bake() override;
6061

6162
private:
63+
void handleDeviceMetadataTable(Consumer &consumer);
6264
bool m_port_counter_enabled = false;
6365
bool m_port_buffer_drop_counter_enabled = false;
6466
bool m_queue_enabled = false;
@@ -76,6 +78,8 @@ class FlexCounterOrch: public Orch
7678
std::unique_ptr<SelectableTimer> m_delayTimer;
7779
std::unique_ptr<Executor> m_delayExecutor;
7880
std::unordered_set<std::string> m_groupsWithBulkChunkSize;
81+
82+
bool m_createOnlyConfigDbBuffers = false;
7983
};
8084

8185
#endif

orchagent/orchdaemon.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,8 @@ bool OrchDaemon::init()
592592
}
593593

594594
vector<string> flex_counter_tables = {
595-
CFG_FLEX_COUNTER_TABLE_NAME
595+
CFG_FLEX_COUNTER_TABLE_NAME,
596+
CFG_DEVICE_METADATA_TABLE_NAME
596597
};
597598

598599
auto* flexCounterOrch = new FlexCounterOrch(m_configDb, flex_counter_tables);

0 commit comments

Comments
 (0)