Skip to content

Commit 4f6cb05

Browse files
authored
[Reclaiming buffer] Support reclaiming buffer in traditional model (sonic-net#2011)
- What I did It's to port sonic-net#1837 to master to reclaim reserved buffer. As the way to do it differs among vendors, buffermgrd will: 1. Handle port admin down on Mellanox platform. - Not apply lossless buffer PG to an admin-down port - Remove lossless buffer PG (3-4) from a port when it is shut down. 2. Read lossless buffer PG (3-4) to a port when a port is started up. - Why I did it To support reclaiming reserved buffer when a port is shut down on Mellanox platform in traditional buffer model. - How I verified it sonic-mgmt test and vs test. Signed-off-by: Stephen Sun <[email protected]>
1 parent 32d7a69 commit 4f6cb05

File tree

2 files changed

+80
-36
lines changed

2 files changed

+80
-36
lines changed

cfgmgr/buffermgr.cpp

+77-35
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ 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+
34+
char *platform = getenv("ASIC_VENDOR");
35+
if (NULL == platform)
36+
{
37+
SWSS_LOG_WARN("Platform environment variable is not defined");
38+
}
39+
else
40+
{
41+
m_platform = platform;
42+
}
43+
3344
dynamic_buffer_model = false;
3445
}
3546

@@ -122,9 +133,9 @@ Create/update two tables: profile (in m_cfgBufferProfileTable) and port buffer (
122133
}
123134
}
124135
*/
125-
task_process_status BufferMgr::doSpeedUpdateTask(string port)
136+
task_process_status BufferMgr::doSpeedUpdateTask(string port, bool admin_up)
126137
{
127-
vector<FieldValueTuple> fvVector;
138+
vector<FieldValueTuple> fvVectorPg, fvVectorProfile;
128139
string cable;
129140
string speed;
130141

@@ -142,20 +153,50 @@ task_process_status BufferMgr::doSpeedUpdateTask(string port)
142153
}
143154

144155
speed = m_speedLookup[port];
156+
157+
string buffer_pg_key = port + m_cfgBufferPgTable.getTableNameSeparator() + LOSSLESS_PGS;
158+
// key format is pg_lossless_<speed>_<cable>_profile
159+
string buffer_profile_key = "pg_lossless_" + speed + "_" + cable + "_profile";
160+
string profile_ref = buffer_profile_key;
161+
162+
m_cfgBufferPgTable.get(buffer_pg_key, fvVectorPg);
163+
164+
if (!admin_up && m_platform == "mellanox")
165+
{
166+
// Remove the entry in BUFFER_PG table if any
167+
if (!fvVectorPg.empty())
168+
{
169+
for (auto &prop : fvVectorPg)
170+
{
171+
if (fvField(prop) == "profile")
172+
{
173+
if (fvValue(prop) == profile_ref)
174+
{
175+
SWSS_LOG_NOTICE("Removing PG %s from port %s which is administrative down", buffer_pg_key.c_str(), port.c_str());
176+
m_cfgBufferPgTable.del(buffer_pg_key);
177+
}
178+
else
179+
{
180+
SWSS_LOG_NOTICE("Not default profile %s is configured on PG %s, won't reclaim buffer", fvValue(prop).c_str(), buffer_pg_key.c_str());
181+
}
182+
}
183+
}
184+
}
185+
186+
return task_process_status::task_success;
187+
}
188+
145189
if (m_pgProfileLookup.count(speed) == 0 || m_pgProfileLookup[speed].count(cable) == 0)
146190
{
147191
SWSS_LOG_ERROR("Unable to create/update PG profile for port %s. No PG profile configured for speed %s and cable length %s",
148192
port.c_str(), speed.c_str(), cable.c_str());
149193
return task_process_status::task_invalid_entry;
150194
}
151195

152-
// Crete record in BUFFER_PROFILE table
153-
// key format is pg_lossless_<speed>_<cable>_profile
154-
string buffer_profile_key = "pg_lossless_" + speed + "_" + cable + "_profile";
155-
156196
// check if profile already exists - if yes - skip creation
157-
m_cfgBufferProfileTable.get(buffer_profile_key, fvVector);
158-
if (fvVector.size() == 0)
197+
m_cfgBufferProfileTable.get(buffer_profile_key, fvVectorProfile);
198+
// Create record in BUFFER_PROFILE table
199+
if (fvVectorProfile.size() == 0)
159200
{
160201
SWSS_LOG_NOTICE("Creating new profile '%s'", buffer_profile_key.c_str());
161202

@@ -170,32 +211,24 @@ task_process_status BufferMgr::doSpeedUpdateTask(string port)
170211
// profile threshold field name
171212
mode += "_th";
172213

173-
fvVector.push_back(make_pair("pool", INGRESS_LOSSLESS_PG_POOL_NAME));
174-
fvVector.push_back(make_pair("xon", m_pgProfileLookup[speed][cable].xon));
214+
fvVectorProfile.push_back(make_pair("pool", INGRESS_LOSSLESS_PG_POOL_NAME));
215+
fvVectorProfile.push_back(make_pair("xon", m_pgProfileLookup[speed][cable].xon));
175216
if (m_pgProfileLookup[speed][cable].xon_offset.length() > 0) {
176-
fvVector.push_back(make_pair("xon_offset",
217+
fvVectorProfile.push_back(make_pair("xon_offset",
177218
m_pgProfileLookup[speed][cable].xon_offset));
178219
}
179-
fvVector.push_back(make_pair("xoff", m_pgProfileLookup[speed][cable].xoff));
180-
fvVector.push_back(make_pair("size", m_pgProfileLookup[speed][cable].size));
181-
fvVector.push_back(make_pair(mode, m_pgProfileLookup[speed][cable].threshold));
182-
m_cfgBufferProfileTable.set(buffer_profile_key, fvVector);
220+
fvVectorProfile.push_back(make_pair("xoff", m_pgProfileLookup[speed][cable].xoff));
221+
fvVectorProfile.push_back(make_pair("size", m_pgProfileLookup[speed][cable].size));
222+
fvVectorProfile.push_back(make_pair(mode, m_pgProfileLookup[speed][cable].threshold));
223+
m_cfgBufferProfileTable.set(buffer_profile_key, fvVectorProfile);
183224
}
184225
else
185226
{
186227
SWSS_LOG_NOTICE("Reusing existing profile '%s'", buffer_profile_key.c_str());
187228
}
188229

189-
fvVector.clear();
190-
191-
string buffer_pg_key = port + m_cfgBufferPgTable.getTableNameSeparator() + LOSSLESS_PGS;
192-
193-
string profile_ref = buffer_profile_key;
194-
195230
/* Check if PG Mapping is already then log message and return. */
196-
m_cfgBufferPgTable.get(buffer_pg_key, fvVector);
197-
198-
for (auto& prop : fvVector)
231+
for (auto& prop : fvVectorPg)
199232
{
200233
if ((fvField(prop) == "profile") && (profile_ref == fvValue(prop)))
201234
{
@@ -204,10 +237,10 @@ task_process_status BufferMgr::doSpeedUpdateTask(string port)
204237
}
205238
}
206239

207-
fvVector.clear();
240+
fvVectorPg.clear();
208241

209-
fvVector.push_back(make_pair("profile", profile_ref));
210-
m_cfgBufferPgTable.set(buffer_pg_key, fvVector);
242+
fvVectorPg.push_back(make_pair("profile", profile_ref));
243+
m_cfgBufferPgTable.set(buffer_pg_key, fvVectorPg);
211244
return task_process_status::task_success;
212245
}
213246

@@ -379,26 +412,35 @@ void BufferMgr::doTask(Consumer &consumer)
379412
task_process_status task_status = task_process_status::task_success;
380413
if (op == SET_COMMAND)
381414
{
382-
for (auto i : kfvFieldsValues(t))
415+
if (table_name == CFG_PORT_CABLE_LEN_TABLE_NAME)
383416
{
384-
if (table_name == CFG_PORT_CABLE_LEN_TABLE_NAME)
417+
// receive and cache cable length table
418+
for (auto i : kfvFieldsValues(t))
385419
{
386-
// receive and cache cable length table
387420
task_status = doCableTask(fvField(i), fvValue(i));
388421
}
389-
if (m_pgfile_processed && table_name == CFG_PORT_TABLE_NAME && (fvField(i) == "speed" || fvField(i) == "admin_status"))
422+
}
423+
else if (m_pgfile_processed && table_name == CFG_PORT_TABLE_NAME)
424+
{
425+
bool admin_up = false;
426+
for (auto i : kfvFieldsValues(t))
390427
{
391428
if (fvField(i) == "speed")
392429
{
393430
m_speedLookup[port] = fvValue(i);
394431
}
395-
396-
if (m_speedLookup.count(port) != 0)
432+
if (fvField(i) == "admin_status")
397433
{
398-
// create/update profile for port
399-
task_status = doSpeedUpdateTask(port);
434+
admin_up = ("up" == fvValue(i));
400435
}
401436
}
437+
438+
if (m_speedLookup.count(port) != 0)
439+
{
440+
// create/update profile for port
441+
task_status = doSpeedUpdateTask(port, admin_up);
442+
}
443+
402444
if (task_status != task_process_status::task_success)
403445
{
404446
break;

cfgmgr/buffermgr.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class BufferMgr : public Orch
3636
using Orch::doTask;
3737

3838
private:
39+
std::string m_platform;
40+
3941
Table m_cfgPortTable;
4042
Table m_cfgCableLenTable;
4143
Table m_cfgBufferProfileTable;
@@ -58,7 +60,7 @@ class BufferMgr : public Orch
5860
std::string getPgPoolMode();
5961
void readPgProfileLookupFile(std::string);
6062
task_process_status doCableTask(std::string port, std::string cable_length);
61-
task_process_status doSpeedUpdateTask(std::string port);
63+
task_process_status doSpeedUpdateTask(std::string port, bool admin_up);
6264
void doBufferTableTask(Consumer &consumer, ProducerStateTable &applTable);
6365

6466
void transformSeperator(std::string &name);

0 commit comments

Comments
 (0)