Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize counter initialization by reducing the number of bulk counter poll calls and communication between swss/sairedis #1527

Merged
merged 32 commits into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a75a5ed
Support bulk step 1: deserialize bulk but handle it in single mode
stephenxs May 27, 2024
4098581
Support bulk add flex counter
Junchao-Mellanox May 27, 2024
56d2977
Fix compiling errors
stephenxs May 27, 2024
09483f8
Compiling pass
stephenxs May 27, 2024
55999b7
bulk counter: syncd
stephenxs May 28, 2024
0451b9d
Working solution
stephenxs May 28, 2024
4ea9f74
Fix compiling errors
stephenxs Dec 13, 2024
c092ac2
Bulk counter init + bulk chunk size
stephenxs Dec 20, 2024
4751d59
Support addBulkStatsContext using vector
stephenxs Dec 22, 2024
254eff2
Support test for bulk counter init
stephenxs Dec 23, 2024
22737a9
Optimize addBulkStatsContext
stephenxs Dec 24, 2024
1f4796f
Insert entry with single OID as key into FLEX_COUNTER_DB
stephenxs Dec 24, 2024
df95629
Cover bulk counter initialization
stephenxs Dec 24, 2024
d6ac21d
Remove non-used function queryObjectSupportedCounters
stephenxs Dec 24, 2024
2206451
Remove unused code
stephenxs Dec 24, 2024
c124814
Minor changes
stephenxs Dec 31, 2024
c7bc1b6
Simplify the logic
stephenxs Jan 6, 2025
6832104
Fix issue: fail to parse virtual ID vector which causes error message
stephenxs Jan 6, 2025
e247996
Fix alignment
stephenxs Jan 6, 2025
9ca5b17
Fix issue: check bulk with empty OID list and add unit test case
stephenxs Jan 8, 2025
9b76188
Update log severity before and after bulk counter polling to info
stephenxs Jan 9, 2025
8ddf7e5
Enhance unit test
stephenxs Jan 12, 2025
ffb93e3
Handle corner case that partial counters are not supported to be poll…
stephenxs Jan 13, 2025
7424742
Enhance the unit test
stephenxs Jan 13, 2025
66e2e61
Add comments
stephenxs Dec 30, 2024
135200d
Move the syslog to avoid confusion
stephenxs Dec 31, 2024
6ba9c47
Do not check bulk capability if it is configured for counter groups w…
stephenxs Jan 25, 2025
139202d
Fix spelling check error and tail white spaces
stephenxs Feb 9, 2025
9a4bb03
Fix issue and simplify code
stephenxs Feb 10, 2025
fe9a9be
Fix review comments
stephenxs Feb 14, 2025
55881cb
Fix an error in the test
stephenxs Feb 17, 2025
213310a
Update test case to cover bulk create more than single create counters
stephenxs Feb 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
441 changes: 307 additions & 134 deletions syncd/FlexCounter.cpp

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions syncd/FlexCounter.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ namespace syncd
_In_ const std::vector<std::string> &idStrings,
_In_ const std::string &per_object_stats_mode) = 0;

virtual void bulkAddObject(
_In_ const std::vector<sai_object_id_t>& vids,
_In_ const std::vector<sai_object_id_t>& rids,
_In_ const std::vector<std::string>& idStrings,
_In_ const std::string &per_object_stats_mode) = 0;

virtual void removeObject(
_In_ sai_object_id_t vid) = 0;

Expand Down Expand Up @@ -95,6 +101,12 @@ namespace syncd
_In_ sai_object_id_t rid,
_In_ const std::vector<swss::FieldValueTuple>& values);

void bulkAddCounter(
_In_ sai_object_type_t objectType,
_In_ const std::vector<sai_object_id_t>& vids,
_In_ const std::vector<sai_object_id_t>& rids,
_In_ const std::vector<swss::FieldValueTuple>& values);

void removeCounter(
_In_ sai_object_id_t vid);

Expand Down Expand Up @@ -188,5 +200,7 @@ namespace syncd
bool m_noDoubleCheckBulkCapability;

static const std::map<std::string, std::string> m_plugIn2CounterType;

static const std::map<std::tuple<sai_object_type_t, std::string>, std::string> m_objectTypeField2CounterType;
};
}
21 changes: 21 additions & 0 deletions syncd/FlexCounterManager.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "FlexCounterManager.h"
#include "VidManager.h"

#include "swss/logger.h"

Expand Down Expand Up @@ -100,6 +101,26 @@ void FlexCounterManager::addCounter(
}
}

void FlexCounterManager::bulkAddCounter(
_In_ const std::vector<sai_object_id_t> &vids,
_In_ const std::vector<sai_object_id_t> &rids,
_In_ const std::string& instanceId,
_In_ const std::vector<swss::FieldValueTuple>& values)
{
SWSS_LOG_ENTER();

auto fc = getInstance(instanceId);

sai_object_type_t objectType = VidManager::objectTypeQuery(vids.at(0)); // VID and RID will have the same object type

fc->bulkAddCounter(objectType, vids, rids, values);

if (fc->isDiscarded())
{
removeInstance(instanceId);
}
}

void FlexCounterManager::removeCounter(
_In_ sai_object_id_t vid,
_In_ const std::string& instanceId)
Expand Down
6 changes: 6 additions & 0 deletions syncd/FlexCounterManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ namespace syncd
_In_ const std::string& instanceId,
_In_ const std::vector<swss::FieldValueTuple>& values);

void bulkAddCounter(
_In_ const std::vector<sai_object_id_t> &vids,
_In_ const std::vector<sai_object_id_t> &rids,
_In_ const std::string& instanceId,
_In_ const std::vector<swss::FieldValueTuple>& values);

void removeCounter(
_In_ sai_object_id_t vid,
_In_ const std::string& instanceId);
Expand Down
102 changes: 74 additions & 28 deletions syncd/Syncd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2791,49 +2791,95 @@ sai_status_t Syncd::processFlexCounterEvent(
}

auto groupName = key.substr(0, delimiter);
auto strVid = key.substr(delimiter + 1);
auto strVids = key.substr(delimiter + 1);
auto vidStringVector = swss::tokenize(strVids, ',');
stephenxs marked this conversation as resolved.
Show resolved Hide resolved

auto effective_op = op;

sai_object_id_t vid;
sai_deserialize_object_id(strVid, vid);
if (fromAsicChannel && op == SET_COMMAND && (!vidStringVector.empty()))
{
std::vector<sai_object_id_t> vids;
std::vector<sai_object_id_t> rids;
std::vector<std::string> keys;

sai_object_id_t rid;
vids.reserve(vidStringVector.size());
rids.reserve(vidStringVector.size());
keys.reserve(vidStringVector.size());

if (!m_translator->tryTranslateVidToRid(vid, rid))
{
if (fromAsicChannel)
for (auto &strVid: vidStringVector)
{
SWSS_LOG_ERROR("port VID %s, was not found (probably port was removed/splitted) and will remove from counters now",
sai_serialize_object_id(vid).c_str());
sai_object_id_t vid, rid;
sai_deserialize_object_id(strVid, vid);
vids.emplace_back(vid);

if (!m_translator->tryTranslateVidToRid(vid, rid))
{
SWSS_LOG_ERROR("port VID %s, was not found (probably port was removed/splitted) and will remove from counters now",
sai_serialize_object_id(vid).c_str());
}

rids.emplace_back(rid);
keys.emplace_back(groupName + ":" + strVid);
}
else

m_manager->bulkAddCounter(vids, rids, groupName, values);

for (auto &singleKey: keys)
{
SWSS_LOG_WARN("port VID %s, was not found (probably port was removed/splitted) and will remove from counters now",
sai_serialize_object_id(vid).c_str());
m_flexCounterTable->set(singleKey, values);
}
effective_op = DEL_COMMAND;
}

if (effective_op == SET_COMMAND)
{
m_manager->addCounter(vid, rid, groupName, values);
if (fromAsicChannel)
{
m_flexCounterTable->set(key, values);
sendApiResponse(SAI_COMMON_API_SET, SAI_STATUS_SUCCESS);
}

return SAI_STATUS_SUCCESS;
}
else if (effective_op == DEL_COMMAND)

for(auto &strVid : vidStringVector)
{
if (fromAsicChannel)
auto effective_op = op;
auto singleKey = groupName + ":" + strVid;

sai_object_id_t vid;
sai_deserialize_object_id(strVid, vid);

sai_object_id_t rid;

if (!m_translator->tryTranslateVidToRid(vid, rid))
{
m_flexCounterTable->del(key);
if (fromAsicChannel)
{
SWSS_LOG_ERROR("port VID %s, was not found (probably port was removed/splitted) and will remove from counters now",
sai_serialize_object_id(vid).c_str());
}
else
{
SWSS_LOG_WARN("port VID %s, was not found (probably port was removed/splitted) and will remove from counters now",
sai_serialize_object_id(vid).c_str());
}
effective_op = DEL_COMMAND;
}

if (effective_op == SET_COMMAND)
{
m_manager->addCounter(vid, rid, groupName, values);
if (fromAsicChannel)
{
m_flexCounterTable->set(singleKey, values);
}
}
else if (effective_op == DEL_COMMAND)
{
if (fromAsicChannel)
{
m_flexCounterTable->del(singleKey);
}
m_manager->removeCounter(vid, groupName);
}
else
{
SWSS_LOG_ERROR("unknown command: %s", op.c_str());
}
m_manager->removeCounter(vid, groupName);
}
else
{
SWSS_LOG_ERROR("unknown command: %s", op.c_str());
}

if (fromAsicChannel)
Expand Down
77 changes: 57 additions & 20 deletions syncd/tests/TestSyncdMlnx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,29 +222,40 @@ TEST_F(SyncdMlnxTest, queryAttrEnumValuesCapability)

TEST_F(SyncdMlnxTest, portBulkAddRemove)
{
const std::uint32_t portCount = 1;
const std::uint32_t portCount = 4;
const std::uint32_t laneCount = 4;

// Generate port config
std::array<std::uint32_t, laneCount> laneList = { 1000, 1001, 1002, 1003 };

sai_attribute_t attr;
std::vector<sai_attribute_t> attrList;

attr.id = SAI_PORT_ATTR_HW_LANE_LIST;
attr.value.u32list.count = static_cast<std::uint32_t>(laneList.size());
attr.value.u32list.list = laneList.data();
attrList.push_back(attr);

attr.id = SAI_PORT_ATTR_SPEED;
attr.value.u32 = 1000;
attrList.push_back(attr);
std::array<std::vector<std::uint32_t>, portCount> laneLists;
std::array<std::vector<sai_attribute_t>, portCount> attrLists;
std::array<std::uint32_t, portCount> attrCountList;
std::array<const sai_attribute_t*, portCount> attrPtrList;

std::array<std::uint32_t, portCount> attrCountList = { static_cast<std::uint32_t>(attrList.size()) };
std::array<const sai_attribute_t*, portCount> attrPtrList = { attrList.data() };
uint32_t lane = 1000;
for (auto i = 0u; i < portCount; i++)
{
auto &laneList = laneLists[i];
auto &attrList = attrLists[i];
for (auto j = 0u; j < laneCount; j++)
{
laneList.push_back(lane++);
}
attr.id = SAI_PORT_ATTR_HW_LANE_LIST;
attr.value.u32list.count = static_cast<std::uint32_t>(laneList.size());
attr.value.u32list.list = laneList.data();
attrList.push_back(attr);

attr.id = SAI_PORT_ATTR_SPEED;
attr.value.u32 = 1000;
attrList.push_back(attr);

attrPtrList[i] = attrList.data();
attrCountList[i] = static_cast<std::uint32_t>(attrList.size());
}

std::array<sai_object_id_t, portCount> oidList = { SAI_NULL_OBJECT_ID };
std::array<sai_status_t, portCount> statusList = { SAI_STATUS_SUCCESS };
std::vector<sai_object_id_t> oidList(portCount, SAI_NULL_OBJECT_ID);
std::vector<sai_status_t> statusList(portCount, SAI_STATUS_SUCCESS);

// Validate port bulk add
auto status = m_sairedis->bulkCreate(
Expand Down Expand Up @@ -334,15 +345,41 @@ TEST_F(SyncdMlnxTest, portBulkAddRemove)
fvVectorExpected.emplace_back(counter_field_name, counters);
ASSERT_EQ(fvVectorExpected, fvVector);

// Try with bulk initialization
key = "PORT_STAT_COUNTER:";
for (auto i = 1u; i < portCount; i++)
{
key += sai_serialize_object_id(oidList[i]) + ",";
}
key.pop_back();

flexCounterParam.counter_key.list = (int8_t*)const_cast<char *>(key.c_str());
flexCounterParam.counter_key.count = (uint32_t)key.length();
status = m_sairedis->set(SAI_OBJECT_TYPE_SWITCH, m_switchId, &attr);
ASSERT_EQ(status, SAI_STATUS_SUCCESS);

for (auto i = 1u; i < portCount; i++)
{
key = "PORT_STAT_COUNTER:" + sai_serialize_object_id(oidList[i]);
ASSERT_TRUE(m_flexCounterTable->get(key, fvVector));
ASSERT_EQ(fvVectorExpected, fvVector);
}

flexCounterParam.counter_ids.list = nullptr;
flexCounterParam.counter_ids.count = 0;
flexCounterParam.counter_field_name.list = nullptr;
flexCounterParam.counter_field_name.count = 0;

// 3. Stop counter polling for the port
status = m_sairedis->set(SAI_OBJECT_TYPE_SWITCH, m_switchId, &attr);
ASSERT_EQ(status, SAI_STATUS_SUCCESS);
ASSERT_FALSE(m_flexCounterTable->get(key, fvVector));
for (auto i = 0u; i < portCount; i++)
{
key = "PORT_STAT_COUNTER:" + sai_serialize_object_id(oidList[i]);
flexCounterParam.counter_key.list = (int8_t*)const_cast<char *>(key.c_str());
flexCounterParam.counter_key.count = (uint32_t)key.length();
status = m_sairedis->set(SAI_OBJECT_TYPE_SWITCH, m_switchId, &attr);
ASSERT_EQ(status, SAI_STATUS_SUCCESS);
ASSERT_FALSE(m_flexCounterTable->get(key, fvVector));
}

// 4. Disable counter polling for the group
flexCounterGroupParam.poll_interval.list = nullptr;
Expand Down
Loading
Loading