Skip to content

Commit 5071bec

Browse files
authored
Merge pull request #3519 from stepanblyschak/202411-fc-after-apply-view
[202411][FC] process FC after apply view
2 parents 5031aad + c3437bd commit 5071bec

4 files changed

Lines changed: 91 additions & 54 deletions

File tree

orchagent/flexcounterorch.cpp

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "macsecorch.h"
1616
#include "dash/dashorch.h"
1717
#include "flowcounterrouteorch.h"
18+
#include "warm_restart.h"
1819

1920
extern sai_port_api_t *sai_port_api;
2021
extern sai_switch_api_t *sai_switch_api;
@@ -28,6 +29,8 @@ extern CoppOrch *gCoppOrch;
2829
extern FlowCounterRouteOrch *gFlowCounterRouteOrch;
2930
extern sai_object_id_t gSwitchId;
3031

32+
#define FLEX_COUNTER_DELAY_SEC 60
33+
3134
#define BUFFER_POOL_WATERMARK_KEY "BUFFER_POOL_WATERMARK"
3235
#define PORT_KEY "PORT"
3336
#define PORT_BUFFER_DROP_KEY "PORT_BUFFER_DROP"
@@ -69,12 +72,22 @@ unordered_map<string, string> flexCounterGroupMap =
6972

7073
FlexCounterOrch::FlexCounterOrch(DBConnector *db, vector<string> &tableNames):
7174
Orch(db, tableNames),
72-
m_flexCounterConfigTable(db, CFG_FLEX_COUNTER_TABLE_NAME),
7375
m_bufferQueueConfigTable(db, CFG_BUFFER_QUEUE_TABLE_NAME),
7476
m_bufferPgConfigTable(db, CFG_BUFFER_PG_TABLE_NAME),
7577
m_deviceMetadataConfigTable(db, CFG_DEVICE_METADATA_TABLE_NAME)
7678
{
7779
SWSS_LOG_ENTER();
80+
m_delayTimer = std::make_unique<SelectableTimer>(timespec{.tv_sec = FLEX_COUNTER_DELAY_SEC, .tv_nsec = 0});
81+
if (WarmStart::isWarmStart())
82+
{
83+
m_delayExecutor = std::make_unique<ExecutableTimer>(m_delayTimer.get(), this, "FLEX_COUNTER_DELAY");
84+
Orch::addExecutor(m_delayExecutor.get());
85+
m_delayTimer->start();
86+
}
87+
else
88+
{
89+
m_delayTimerExpired = true;
90+
}
7891
}
7992

8093
FlexCounterOrch::~FlexCounterOrch(void)
@@ -86,6 +99,11 @@ void FlexCounterOrch::doTask(Consumer &consumer)
8699
{
87100
SWSS_LOG_ENTER();
88101

102+
if (!m_delayTimerExpired)
103+
{
104+
return;
105+
}
106+
89107
VxlanTunnelOrch* vxlan_tunnel_orch = gDirectory.get<VxlanTunnelOrch*>();
90108
DashOrch* dash_orch = gDirectory.get<DashOrch*>();
91109
if (gPortsOrch && !gPortsOrch->allPortsReady())
@@ -116,16 +134,9 @@ void FlexCounterOrch::doTask(Consumer &consumer)
116134

117135
if (op == SET_COMMAND)
118136
{
119-
auto itDelay = std::find(std::begin(data), std::end(data), FieldValueTuple(FLEX_COUNTER_DELAY_STATUS_FIELD, "true"));
120-
string poll_interval;
121137
string bulk_chunk_size;
122138
string bulk_chunk_size_per_counter;
123139

124-
if (itDelay != data.end())
125-
{
126-
consumer.m_toSync.erase(it++);
127-
continue;
128-
}
129140
for (auto valuePair:data)
130141
{
131142
const auto &field = fvField(valuePair);
@@ -255,12 +266,6 @@ void FlexCounterOrch::doTask(Consumer &consumer)
255266
}
256267
}
257268
}
258-
else if(field == FLEX_COUNTER_DELAY_STATUS_FIELD)
259-
{
260-
// This field is ignored since it is being used before getting into this loop.
261-
// If it is exist and the value is 'true' we need to skip the iteration in order to delay the counter creation.
262-
// The field will clear out and counter will be created when enable_counters script is called.
263-
}
264269
else
265270
{
266271
SWSS_LOG_NOTICE("Unsupported field %s", field.c_str());
@@ -285,6 +290,20 @@ void FlexCounterOrch::doTask(Consumer &consumer)
285290
}
286291
}
287292

293+
void FlexCounterOrch::doTask(SelectableTimer&)
294+
{
295+
SWSS_LOG_ENTER();
296+
297+
if (m_delayTimerExpired)
298+
{
299+
return;
300+
}
301+
302+
SWSS_LOG_NOTICE("Processing counters");
303+
m_delayTimer->stop();
304+
m_delayTimerExpired = true;
305+
}
306+
288307
bool FlexCounterOrch::getPortCountersState() const
289308
{
290309
return m_port_counter_enabled;
@@ -322,39 +341,10 @@ bool FlexCounterOrch::bake()
322341
* By default, it should fetch items from the tables the sub agents listen to,
323342
* and then push them into m_toSync of each sub agent.
324343
* The motivation is to make sub agents handle the saved entries first and then handle the upcoming entries.
344+
* The FCs are not data plane configuration required during reconciling process, hence don't do anything in bake.
325345
*/
326346

327-
std::deque<KeyOpFieldsValuesTuple> entries;
328-
vector<string> keys;
329-
m_flexCounterConfigTable.getKeys(keys);
330-
for (const auto &key: keys)
331-
{
332-
if (!flexCounterGroupMap.count(key))
333-
{
334-
SWSS_LOG_NOTICE("FlexCounterOrch: Invalid flex counter group intput %s is skipped during reconciling", key.c_str());
335-
continue;
336-
}
337-
338-
if (key == BUFFER_POOL_WATERMARK_KEY)
339-
{
340-
SWSS_LOG_NOTICE("FlexCounterOrch: Do not handle any FLEX_COUNTER table for %s update during reconciling",
341-
BUFFER_POOL_WATERMARK_KEY);
342-
continue;
343-
}
344-
345-
KeyOpFieldsValuesTuple kco;
346-
347-
kfvKey(kco) = key;
348-
kfvOp(kco) = SET_COMMAND;
349-
350-
if (!m_flexCounterConfigTable.get(key, kfvFieldsValues(kco)))
351-
{
352-
continue;
353-
}
354-
entries.push_back(kco);
355-
}
356-
Consumer* consumer = dynamic_cast<Consumer *>(getExecutor(CFG_FLEX_COUNTER_TABLE_NAME));
357-
return consumer->addToSync(entries);
347+
return true;
358348
}
359349

360350
static bool isCreateOnlyConfigDbBuffers(Table& deviceMetadataConfigTable)

orchagent/flexcounterorch.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "orch.h"
55
#include "port.h"
66
#include "producertable.h"
7+
#include "selectabletimer.h"
78
#include "table.h"
89

910
extern "C" {
@@ -40,6 +41,7 @@ class FlexCounterOrch: public Orch
4041
{
4142
public:
4243
void doTask(Consumer &consumer);
44+
void doTask(SelectableTimer &timer);
4345
FlexCounterOrch(swss::DBConnector *db, std::vector<std::string> &tableNames);
4446
virtual ~FlexCounterOrch(void);
4547
bool getPortCountersState() const;
@@ -63,11 +65,13 @@ class FlexCounterOrch: public Orch
6365
bool m_pg_watermark_enabled = false;
6466
bool m_hostif_trap_counter_enabled = false;
6567
bool m_route_flow_counter_enabled = false;
66-
Table m_flexCounterConfigTable;
68+
bool m_delayTimerExpired = false;
6769
Table m_bufferQueueConfigTable;
6870
Table m_bufferPgConfigTable;
6971
Table m_deviceMetadataConfigTable;
7072
std::unordered_set<std::string> m_groupsWithBulkChunkSize;
73+
std::unique_ptr<SelectableTimer> m_delayTimer;
74+
std::unique_ptr<Executor> m_delayExecutor;
7175
};
7276

7377
#endif

orchagent/p4orch/tests/fake_flexcounterorch.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include "flexcounterorch.h"
33

44
FlexCounterOrch::FlexCounterOrch(swss::DBConnector *db, std::vector<std::string> &tableNames)
5-
: Orch(db, tableNames), m_flexCounterConfigTable(db, CFG_FLEX_COUNTER_TABLE_NAME),
5+
: Orch(db, tableNames),
66
m_bufferQueueConfigTable(db, CFG_BUFFER_QUEUE_TABLE_NAME), m_bufferPgConfigTable(db, CFG_BUFFER_PG_TABLE_NAME),
77
m_deviceMetadataConfigTable(db, CFG_DEVICE_METADATA_TABLE_NAME)
88
{
@@ -16,6 +16,10 @@ void FlexCounterOrch::doTask(Consumer &consumer)
1616
{
1717
}
1818

19+
void FlexCounterOrch::doTask(SelectableTimer &timer)
20+
{
21+
}
22+
1923
bool FlexCounterOrch::getPortCountersState() const
2024
{
2125
return true;

tests/mock_tests/flexcounter_ut.cpp

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,13 @@ namespace flexcounter_test
220220
sai_switch_api = pold_sai_switch_api;
221221
}
222222

223-
struct FlexCounterTest : public ::testing::TestWithParam<std::tuple<bool, bool>>
223+
enum class StartType
224+
{
225+
Cold,
226+
Warm,
227+
};
228+
229+
struct FlexCounterTest : public ::testing::TestWithParam<std::tuple<bool, bool, StartType>>
224230
{
225231
shared_ptr<swss::DBConnector> m_app_db;
226232
shared_ptr<swss::DBConnector> m_config_db;
@@ -230,6 +236,7 @@ namespace flexcounter_test
230236
shared_ptr<swss::DBConnector> m_asic_db;
231237
shared_ptr<swss::DBConnector> m_flex_counter_db;
232238
bool create_only_config_db_buffers;
239+
StartType m_start_type;
233240

234241
FlexCounterTest()
235242
{
@@ -256,6 +263,8 @@ namespace flexcounter_test
256263

257264
gTraditionalFlexCounter = get<0>(GetParam());
258265
create_only_config_db_buffers = get<1>(GetParam());
266+
m_start_type = get<2>(GetParam());
267+
259268
if (gTraditionalFlexCounter)
260269
{
261270
initFlexCounterTables();
@@ -300,7 +309,19 @@ namespace flexcounter_test
300309
vector<string> flex_counter_tables = {
301310
CFG_FLEX_COUNTER_TABLE_NAME
302311
};
312+
313+
if (m_start_type == StartType::Warm)
314+
{
315+
WarmStart::getInstance().m_enabled = true;
316+
}
317+
303318
auto* flexCounterOrch = new FlexCounterOrch(m_config_db.get(), flex_counter_tables);
319+
320+
if (m_start_type == StartType::Warm)
321+
{
322+
WarmStart::getInstance().m_enabled = false;
323+
}
324+
304325
gDirectory.set(flexCounterOrch);
305326

306327
vector<string> buffer_tables = { APP_BUFFER_POOL_TABLE_NAME,
@@ -542,8 +563,7 @@ namespace flexcounter_test
542563
ASSERT_TRUE(gPortsOrch->allPortsReady());
543564

544565
// Enable and check counters
545-
const std::vector<FieldValueTuple> values({ {FLEX_COUNTER_DELAY_STATUS_FIELD, "false"},
546-
{FLEX_COUNTER_STATUS_FIELD, "enable"} });
566+
const std::vector<FieldValueTuple> values({ {FLEX_COUNTER_STATUS_FIELD, "enable"} });
547567
flexCounterCfg.set("PG_WATERMARK", values);
548568
flexCounterCfg.set("QUEUE_WATERMARK", values);
549569
flexCounterCfg.set("QUEUE", values);
@@ -557,6 +577,13 @@ namespace flexcounter_test
557577
flexCounterOrch->addExistingData(&flexCounterCfg);
558578
static_cast<Orch *>(flexCounterOrch)->doTask();
559579

580+
if (m_start_type == StartType::Warm)
581+
{
582+
// Expire timer
583+
flexCounterOrch->doTask(*flexCounterOrch->m_delayTimer);
584+
static_cast<Orch *>(flexCounterOrch)->doTask();
585+
}
586+
560587
ASSERT_TRUE(checkFlexCounterGroup(BUFFER_POOL_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP,
561588
{
562589
{POLL_INTERVAL_FIELD, "60000"},
@@ -878,16 +905,28 @@ namespace flexcounter_test
878905
entries.clear();
879906
static_cast<Orch *>(gBufferOrch)->doTask();
880907
ASSERT_TRUE(checkFlexCounter(BUFFER_POOL_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP, pool_oid));
908+
909+
// Warm/fast-boot case - no FC processing done before APPLY_VIEW
910+
std::vector<std::string> ts;
911+
912+
gDirectory.get<FlexCounterOrch*>()->bake();
913+
gDirectory.get<FlexCounterOrch*>()->dumpPendingTasks(ts);
914+
915+
ASSERT_TRUE(ts.empty());
881916
}
882917

883918
INSTANTIATE_TEST_CASE_P(
884919
FlexCounterTests,
885920
FlexCounterTest,
886921
::testing::Values(
887-
std::make_tuple(false, true),
888-
std::make_tuple(false, false),
889-
std::make_tuple(true, true),
890-
std::make_tuple(true, false))
922+
std::make_tuple(false, true, StartType::Cold),
923+
std::make_tuple(false, false, StartType::Cold),
924+
std::make_tuple(true, true, StartType::Cold),
925+
std::make_tuple(true, false, StartType::Cold),
926+
std::make_tuple(false, true, StartType::Warm),
927+
std::make_tuple(false, false, StartType::Warm),
928+
std::make_tuple(true, true, StartType::Warm),
929+
std::make_tuple(true, false, StartType::Warm))
891930
);
892931

893932
using namespace mock_orch_test;

0 commit comments

Comments
 (0)