Skip to content

Commit 1bb5070

Browse files
authored
Enhance mock test for dynamic buffer manager for port removing and qos reload flows (#2262)
What I did Enhance the mock test of the dynamic buffer manager in port remove and config qos clear flow and fix bugs during mock test implementation Implement mock method ProduceStateTable::del Signed-off-by: Stephen Sun [email protected] How I verified it Run regression test, mock test, vs test, and manual test. Details if related 1. Support mock test for dynamic buffer manager config qos clear and reclaiming buffer Remove port 2. Handle port remove/create flow Cache cable length for a port Try reclaiming unused buffer when maximum buffer parameters are received for a port whose state is ADMIN_DOWN and m_bufferCompletelyInitialized is true 3. Handle config qos clear If all buffer pools are removed when m_bufferPoolReady is true, remove all zero pools and profiles. Reload zero profiles and pools if they have not been loaded when reclaiming buffer
1 parent 700492f commit 1bb5070

File tree

4 files changed

+610
-0
lines changed

4 files changed

+610
-0
lines changed

cfgmgr/buffermgrdyn.cpp

+114
Original file line numberDiff line numberDiff line change
@@ -1862,6 +1862,14 @@ task_process_status BufferMgrDynamic::handleBufferMaxParam(KeyOpFieldsValuesTupl
18621862
SWSS_LOG_INFO("BUFFER_MAX_PARAM: Got port %s's max priority group %s", key.c_str(), value.c_str());
18631863

18641864
portInfo.maximum_buffer_objects[BUFFER_PG] = (sai_uint32_t)pgCount;
1865+
1866+
if (m_bufferCompletelyInitialized && portInfo.state == PORT_ADMIN_DOWN)
1867+
{
1868+
// This is mostly for the case where the port is created only-the-fly
1869+
// The maximum buffer parameters can be received after buffer items
1870+
reclaimReservedBufferForPort(key, m_portPgLookup, BUFFER_PG);
1871+
SWSS_LOG_NOTICE("Admin-down port %s is handled after maximum buffer parameter has been received", key.c_str());
1872+
}
18651873
}
18661874
else if (fvField(i) == "max_queues")
18671875
{
@@ -1875,6 +1883,14 @@ task_process_status BufferMgrDynamic::handleBufferMaxParam(KeyOpFieldsValuesTupl
18751883
SWSS_LOG_INFO("BUFFER_MAX_PARAM: Got port %s's max queue %s", key.c_str(), value.c_str());
18761884

18771885
portInfo.maximum_buffer_objects[BUFFER_QUEUE] = (sai_uint32_t)queueCount;
1886+
1887+
if (m_bufferCompletelyInitialized && portInfo.state == PORT_ADMIN_DOWN)
1888+
{
1889+
// This is mostly for the case where the port is created only-the-fly
1890+
// The maximum buffer parameters can be received after buffer items
1891+
reclaimReservedBufferForPort(key, m_portQueueLookup, BUFFER_QUEUE);
1892+
SWSS_LOG_NOTICE("Admin-down port %s is handled after maximum buffer parameter has been received", key.c_str());
1893+
}
18781894
}
18791895
}
18801896
}
@@ -1961,6 +1977,7 @@ task_process_status BufferMgrDynamic::handleCableLenTable(KeyOpFieldsValuesTuple
19611977
int failed_item_count = 0;
19621978
if (op == SET_COMMAND)
19631979
{
1980+
m_cableLengths.clear();
19641981
for (auto i : kfvFieldsValues(tuple))
19651982
{
19661983
// receive and cache cable length table
@@ -1975,6 +1992,8 @@ task_process_status BufferMgrDynamic::handleCableLenTable(KeyOpFieldsValuesTuple
19751992
port.c_str(),
19761993
portInfo.effective_speed.c_str(), portInfo.cable_length.c_str(), portInfo.gearbox_model.c_str());
19771994

1995+
m_cableLengths[port] = cable_length;
1996+
19781997
if (portInfo.cable_length == cable_length)
19791998
{
19801999
continue;
@@ -2183,6 +2202,11 @@ task_process_status BufferMgrDynamic::handlePortTable(KeyOpFieldsValuesTuple &tu
21832202
string &mtu = portInfo.mtu;
21842203
string &effective_speed = portInfo.effective_speed;
21852204

2205+
if (cable_length.empty() && !m_cableLengths[port].empty())
2206+
{
2207+
cable_length = m_cableLengths[port];
2208+
}
2209+
21862210
bool need_refresh_all_buffer_objects = false, need_handle_admin_down = false, was_admin_down = false;
21872211

21882212
if (effective_speed_updated || mtu_updated)
@@ -2304,6 +2328,28 @@ task_process_status BufferMgrDynamic::handlePortTable(KeyOpFieldsValuesTuple &tu
23042328
task_status = refreshPgsForPort(port, portInfo.effective_speed, portInfo.cable_length, portInfo.mtu);
23052329
}
23062330
}
2331+
else if (op == DEL_COMMAND)
2332+
{
2333+
cleanUpItemsForReclaimingBuffer(port);
2334+
if ((m_portPgLookup.find(port) != m_portPgLookup.end()
2335+
&& !m_portPgLookup[port].empty())
2336+
|| (m_portQueueLookup.find(port) != m_portQueueLookup.end()
2337+
&& !m_portQueueLookup[port].empty())
2338+
|| (m_portProfileListLookups[BUFFER_INGRESS].find(port) != m_portProfileListLookups[BUFFER_INGRESS].end()
2339+
&& !m_portProfileListLookups[BUFFER_INGRESS][port].empty())
2340+
|| (m_portProfileListLookups[BUFFER_EGRESS].find(port) != m_portProfileListLookups[BUFFER_EGRESS].end()
2341+
&& !m_portProfileListLookups[BUFFER_EGRESS][port].empty()))
2342+
{
2343+
SWSS_LOG_INFO("Port %s can't be removed before buffer items have been removed", port.c_str());
2344+
return task_process_status::task_need_retry;
2345+
}
2346+
m_portPgLookup.erase(port);
2347+
m_portQueueLookup.erase(port);
2348+
m_portProfileListLookups[BUFFER_INGRESS].erase(port);
2349+
m_portProfileListLookups[BUFFER_EGRESS].erase(port);
2350+
m_portInfoLookup.erase(port);
2351+
SWSS_LOG_NOTICE("Port %s is removed", port.c_str());
2352+
}
23072353

23082354
return task_status;
23092355
}
@@ -2401,6 +2447,28 @@ task_process_status BufferMgrDynamic::handleBufferPoolTable(KeyOpFieldsValuesTup
24012447
m_applBufferPoolTable.del(pool);
24022448
m_stateBufferPoolTable.del(pool);
24032449
m_bufferPoolLookup.erase(pool);
2450+
if (pool == INGRESS_LOSSLESS_PG_POOL_NAME)
2451+
{
2452+
m_configuredSharedHeadroomPoolSize.clear();
2453+
}
2454+
2455+
if (m_bufferPoolReady && m_bufferPoolLookup.empty())
2456+
{
2457+
for(auto &port : m_adminDownPorts)
2458+
{
2459+
cleanUpItemsForReclaimingBuffer(port);
2460+
}
2461+
2462+
// Zero profiles must be unloaded once all pools have been uploaded
2463+
// This can be resulted from "config qos reload"
2464+
// Any zero profile left can leads to buffer pool not able to be cleared
2465+
unloadZeroPoolAndProfiles();
2466+
2467+
m_bufferPoolReady = false;
2468+
m_bufferCompletelyInitialized = false;
2469+
2470+
m_pendingApplyZeroProfilePorts = m_adminDownPorts;
2471+
}
24042472
}
24052473
else
24062474
{
@@ -2634,6 +2702,12 @@ void BufferMgrDynamic::handleSetSingleBufferObjectOnAdminDownPort(buffer_directi
26342702
{
26352703
if (idsToZero.empty())
26362704
{
2705+
// Happens only after "config qos reload"
2706+
if (!m_zeroProfilesLoaded)
2707+
{
2708+
loadZeroPoolAndProfiles();
2709+
}
2710+
26372711
// If initialization finished, no extra handle required.
26382712
// Check whether the key overlaps with supported but not configured map
26392713
auto const &idsToAdd = parseObjectNameFromKey(key, 1);
@@ -2749,6 +2823,14 @@ void BufferMgrDynamic::handleDelSingleBufferObjectOnAdminDownPort(buffer_directi
27492823

27502824
if (idsToZero.empty())
27512825
{
2826+
if (!m_bufferPoolReady)
2827+
{
2828+
// Reclaiming buffer has not started yet so just remove it.
2829+
// Do not add it to "supported but not configured" set
2830+
updateBufferObjectToDb(key, "", false, direction);
2831+
return;
2832+
}
2833+
27522834
// For admin down ports, if zero profiles have been applied to all configured items
27532835
// do NOT remove it otherwise SDK default value will be set for the items
27542836
// Move the key to supported_but_not_configured_items so that the slice of items
@@ -3125,6 +3207,22 @@ task_process_status BufferMgrDynamic::handleSingleBufferPortProfileListEntry(con
31253207
// For admin-down ports, zero profile list has been applied on the port when it entered admin-down state
31263208
updateBufferObjectListToDb(key, profileListLookup[port], dir);
31273209
}
3210+
else
3211+
{
3212+
const auto &profileList = m_portProfileListLookups[dir][port];
3213+
if (!profileList.empty())
3214+
{
3215+
// Happens only after "config qos reload"
3216+
if (!m_zeroProfilesLoaded)
3217+
{
3218+
loadZeroPoolAndProfiles();
3219+
}
3220+
vector<FieldValueTuple> fvVector;
3221+
const string &zeroProfileNameList = constructZeroProfileListFromNormalProfileList(profileList, port);
3222+
fvVector.emplace_back(buffer_profile_list_field_name, zeroProfileNameList);
3223+
m_applBufferProfileListTables[dir].set(port, fvVector);
3224+
}
3225+
}
31283226
}
31293227
else if (op == DEL_COMMAND)
31303228
{
@@ -3462,9 +3560,25 @@ void BufferMgrDynamic::handlePendingBufferObjects()
34623560
}
34633561
}
34643562

3563+
void BufferMgrDynamic::cleanUpItemsForReclaimingBuffer(const string &port)
3564+
{
3565+
// Clean up zero buffers when the buffer pools or a port has been removed
3566+
if (!m_bufferObjectIdsToZero[BUFFER_PG].empty())
3567+
{
3568+
updateBufferObjectToDb(port + delimiter + m_bufferObjectIdsToZero[BUFFER_PG], "", false, BUFFER_PG);
3569+
}
3570+
if (!m_bufferObjectIdsToZero[BUFFER_QUEUE].empty())
3571+
{
3572+
updateBufferObjectToDb(port + delimiter + m_bufferObjectIdsToZero[BUFFER_QUEUE], "", false, BUFFER_QUEUE);
3573+
}
3574+
removeSupportedButNotConfiguredItemsOnPort(m_portInfoLookup[port], port);
3575+
}
3576+
34653577
void BufferMgrDynamic::doTask(SelectableTimer &timer)
34663578
{
34673579
checkSharedBufferPoolSize(true);
34683580
if (!m_bufferCompletelyInitialized)
3581+
{
34693582
handlePendingBufferObjects();
3583+
}
34703584
}

cfgmgr/buffermgrdyn.h

+2
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ class BufferMgrDynamic : public Orch
196196
// key: port name
197197
// updated only when a port's speed and cable length updated
198198
port_info_lookup_t m_portInfoLookup;
199+
std::map<std::string, std::string> m_cableLengths;
199200
std::set<std::string> m_adminDownPorts;
200201
std::set<std::string> m_pendingApplyZeroProfilePorts;
201202
std::set<std::string> m_pendingSupportedButNotConfiguredPorts[BUFFER_DIR_MAX];
@@ -302,6 +303,7 @@ class BufferMgrDynamic : public Orch
302303
void handleSetSingleBufferObjectOnAdminDownPort(buffer_direction_t direction, const std::string &port, const std::string &key, const std::string &profile);
303304
void handleDelSingleBufferObjectOnAdminDownPort(buffer_direction_t direction, const std::string &port, const std::string &key, port_info_t &portInfo);
304305
bool isReadyToReclaimBufferOnPort(const std::string &port);
306+
void cleanUpItemsForReclaimingBuffer(const std::string &port);
305307

306308
// Main flows
307309
template<class T> task_process_status reclaimReservedBufferForPort(const std::string &port, T &obj, buffer_direction_t dir);

0 commit comments

Comments
 (0)