Skip to content

Commit d95823d

Browse files
authored
[Buffermgr]Graceful handling of buffer model change (sonic-net#1956)
Signed-off-by: Sudharsan Dhamal Gopalarathnam [email protected] What I did Handled buffer model changes gracefully. The use case is when config_db.json is loaded initially with no buffer configurations and when user executes 'config qos reload', it would result in buffer model changing from traditional to dynamic. This transition requires swss restart which will be shown as message to user. Why I did it When config qos reload is given in platforms with dynamic buffer model, swss restart is required. However, if swss is not restarted the buffermgrd will stay in static model and will program the orchagent with 'size' field not set in buffer pool due to dynamic mode checks in jinja2 template. This will result in orchagent calling SAI without SAI_BUFFER_POOL_ATTR_SIZE which is mandatory attribute. Since this results in a SAI create API failure, it will result in orchagent crash. So when the mode is changed to dynamic, buffermgrd will not process any configurations when running in static mode. How I verified it Added UT. Manually verified that config qos reload doesn't crash.
1 parent b0aa6a0 commit d95823d

File tree

4 files changed

+75
-1
lines changed

4 files changed

+75
-1
lines changed

cfgmgr/buffermgr.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ BufferMgr::BufferMgr(DBConnector *cfgDb, DBConnector *applDb, string pg_lookup_f
3030
m_applBufferEgressProfileListTable(applDb, APP_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME)
3131
{
3232
readPgProfileLookupFile(pg_lookup_file);
33+
dynamic_buffer_model = false;
3334
}
3435

3536
//# speed, cable, size, xon, xoff, threshold, xon_offset
@@ -273,12 +274,62 @@ void BufferMgr::doBufferTableTask(Consumer &consumer, ProducerStateTable &applTa
273274
}
274275
}
275276

277+
void BufferMgr::doBufferMetaTask(Consumer &consumer)
278+
{
279+
SWSS_LOG_ENTER();
280+
281+
auto it = consumer.m_toSync.begin();
282+
while (it != consumer.m_toSync.end())
283+
{
284+
KeyOpFieldsValuesTuple t = it->second;
285+
string key = kfvKey(t);
286+
287+
string op = kfvOp(t);
288+
if (op == SET_COMMAND)
289+
{
290+
vector<FieldValueTuple> fvVector;
291+
292+
for (auto i : kfvFieldsValues(t))
293+
{
294+
if (fvField(i) == "buffer_model")
295+
{
296+
if (fvValue(i) == "dynamic")
297+
{
298+
dynamic_buffer_model = true;
299+
}
300+
else
301+
{
302+
dynamic_buffer_model = false;
303+
}
304+
break;
305+
}
306+
}
307+
}
308+
else if (op == DEL_COMMAND)
309+
{
310+
dynamic_buffer_model = false;
311+
}
312+
it = consumer.m_toSync.erase(it);
313+
}
314+
}
315+
276316
void BufferMgr::doTask(Consumer &consumer)
277317
{
278318
SWSS_LOG_ENTER();
279319

280320
string table_name = consumer.getTableName();
281321

322+
if (table_name == CFG_DEVICE_METADATA_TABLE_NAME)
323+
{
324+
doBufferMetaTask(consumer);
325+
return;
326+
}
327+
328+
if (dynamic_buffer_model)
329+
{
330+
SWSS_LOG_DEBUG("Dynamic buffer model enabled. Skipping further processing");
331+
return;
332+
}
282333
if (table_name == CFG_BUFFER_POOL_TABLE_NAME)
283334
{
284335
doBufferTableTask(consumer, m_applBufferPoolTable);

cfgmgr/buffermgr.h

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class BufferMgr : public Orch
5050
ProducerStateTable m_applBufferEgressProfileListTable;
5151

5252
bool m_pgfile_processed;
53+
bool dynamic_buffer_model;
5354

5455
pg_profile_lookup_t m_pgProfileLookup;
5556
port_cable_length_t m_cableLenLookup;
@@ -63,6 +64,7 @@ class BufferMgr : public Orch
6364
void transformSeperator(std::string &name);
6465

6566
void doTask(Consumer &consumer);
67+
void doBufferMetaTask(Consumer &consumer);
6668
};
6769

6870
}

cfgmgr/buffermgrd.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ int main(int argc, char **argv)
195195
CFG_BUFFER_PG_TABLE_NAME,
196196
CFG_BUFFER_QUEUE_TABLE_NAME,
197197
CFG_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME,
198-
CFG_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME
198+
CFG_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME,
199+
CFG_DEVICE_METADATA_TABLE_NAME
199200
};
200201
cfgOrchList.emplace_back(new BufferMgr(&cfgDb, &applDb, pg_lookup_file, cfg_buffer_tables));
201202
}

tests/test_buffer_mode.py

+20
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
11
import pytest
2+
import time
23

34
class TestBufferModel(object):
45
def test_bufferModel(self, dvs, testlog):
56
config_db = dvs.get_config_db()
67
metadata = config_db.get_entry("DEVICE_METADATA", "localhost")
78
assert metadata["buffer_model"] == "traditional"
9+
10+
def test_update_bufferModel(self, dvs, testlog):
11+
config_db = dvs.get_config_db()
12+
app_db = dvs.get_app_db()
13+
keys = app_db.get_keys("BUFFER_POOL_TABLE")
14+
num_keys = len(keys)
15+
16+
try:
17+
fvs = {'buffer_model' : 'dynamic'}
18+
config_db.update_entry("DEVICE_METADATA", "localhost", fvs)
19+
fvs = {'mode':'dynamic', 'type':'egress'}
20+
config_db.update_entry("BUFFER_POOL", "temp_pool", fvs)
21+
time.sleep(2)
22+
app_db.wait_for_n_keys("BUFFER_POOL_TABLE", num_keys)
23+
24+
finally:
25+
config_db.delete_entry("BUFFER_POOL", "temp_pool")
26+
fvs = {'buffer_model' : 'traditional'}
27+
config_db.update_entry("DEVICE_METADATA", "localhost", fvs)

0 commit comments

Comments
 (0)