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

Draft
wants to merge 29 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9e6688b
Support bulk step 1: deserialize bulk but handle it in single mode
stephenxs May 27, 2024
5500c57
Support bulk add flex counter
Junchao-Mellanox May 27, 2024
cad8d0b
Fix compiling errors
stephenxs May 27, 2024
dbbe4fe
Compiling pass
stephenxs May 27, 2024
2cbfde9
bulk counter: syncd
stephenxs May 28, 2024
6b57401
Working solution
stephenxs May 28, 2024
5cc1fbe
Fix compiling errors
stephenxs Dec 13, 2024
a7aa9c1
Bulk counter init + bulk chunk size
stephenxs Dec 20, 2024
9d9a03c
Support addBulkStatsContext using vector
stephenxs Dec 22, 2024
57c420e
Support test for bulk counter init
stephenxs Dec 23, 2024
82e4db0
Optimize addBulkStatsContext
stephenxs Dec 24, 2024
3cf66a5
Insert entry with single OID as key into FLEX_COUNTER_DB
stephenxs Dec 24, 2024
19c0918
Cover bulk counter initialization
stephenxs Dec 24, 2024
ed6ea79
Remove non-used function queryObjectSupportedCounters
stephenxs Dec 24, 2024
0d5cc61
Remove unused code
stephenxs Dec 24, 2024
5c31a68
Minor changes
stephenxs Dec 31, 2024
1f0ffe2
Simplify the logic
stephenxs Jan 6, 2025
b58df83
Fix issue: fail to parse virtual ID vector which causes error message
stephenxs Jan 6, 2025
ef22684
Fix alignment
stephenxs Jan 6, 2025
78bce8e
Fix issue: check bulk with empty OID list and add unit test case
stephenxs Jan 8, 2025
ca061be
Update log severity before and after bulk counter polling to info
stephenxs Jan 9, 2025
373991b
Enhance unit test
stephenxs Jan 12, 2025
7f0a8fc
Handle corner case that partial counters are not supported to be poll…
stephenxs Jan 13, 2025
2d90bda
Enhance the unit test
stephenxs Jan 13, 2025
597d256
Add comments
stephenxs Dec 30, 2024
8583436
Move the syslog to avoid confusion
stephenxs Dec 31, 2024
67e41df
Do not check bulk capability if it is configured for counter groups w…
stephenxs Jan 25, 2025
11069a2
Fix spelling check error and tail white spaces
stephenxs Feb 9, 2025
d2a613b
Fix issue and simplify code
stephenxs Feb 10, 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
437 changes: 299 additions & 138 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;
};
}
20 changes: 20 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,25 @@ 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[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, ',');

auto effective_op = op;

sai_object_id_t vid;
sai_deserialize_object_id(strVid, vid);
if (fromAsicChannel && op == SET_COMMAND && vidStringVector.size() > 1)
{
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