Skip to content

Commit

Permalink
Added Flex Counters support for tunnel counters (sonic-net#886)
Browse files Browse the repository at this point in the history
Added Flex counter support for tunnel counters and rates implementation
  • Loading branch information
dgsudharsan committed Nov 2, 2021
1 parent a718226 commit 88b62ce
Show file tree
Hide file tree
Showing 2 changed files with 245 additions and 3 deletions.
217 changes: 214 additions & 3 deletions syncd/FlexCounter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ FlexCounter::MACsecSAAttrIds::MACsecSAAttrIds(
// empty intentionally
}

FlexCounter::TunnelCounterIds::TunnelCounterIds(
_In_ sai_object_id_t tunnelRid,
_In_ const std::vector<sai_tunnel_stat_t> &tunnelIds):
m_tunnelId(tunnelRid),
m_tunnelCounterIds(tunnelIds)
{
SWSS_LOG_ENTER();
// empty intentionally
}

void FlexCounter::setPollInterval(
_In_ uint32_t pollInterval)
{
Expand Down Expand Up @@ -567,6 +577,47 @@ void FlexCounter::setBufferPoolCounterList(
addCollectCountersHandler(BUFFER_POOL_COUNTER_ID_LIST, &FlexCounter::collectBufferPoolCounters);
}

void FlexCounter::setTunnelCounterList(
_In_ sai_object_id_t tunnelVid,
_In_ sai_object_id_t tunnelRid,
_In_ const std::vector<sai_tunnel_stat_t> &counterIds)
{
SWSS_LOG_ENTER();

updateSupportedTunnelCounters(tunnelRid, counterIds);

// Remove unsupported counters
std::vector<sai_tunnel_stat_t> supportedIds;

for (auto &counter : counterIds)
{
if (isTunnelCounterSupported(counter))
{
supportedIds.push_back(counter);
}
}

if (supportedIds.empty())
{
SWSS_LOG_NOTICE("Tunnel %s does not have supported counters", sai_serialize_object_id(tunnelRid).c_str());
return;
}

auto it = m_tunnelCounterIdsMap.find(tunnelVid);

if (it != m_tunnelCounterIdsMap.end())
{
it->second->m_tunnelCounterIds = supportedIds;
return;
}

auto tunnelCounterIds = std::make_shared<TunnelCounterIds>(tunnelRid, supportedIds);

m_tunnelCounterIdsMap.emplace(tunnelVid, tunnelCounterIds);

addCollectCountersHandler(TUNNEL_COUNTER_ID_LIST, &FlexCounter::collectTunnelCounters);
}

void FlexCounter::removePort(
_In_ sai_object_id_t portVid)
{
Expand Down Expand Up @@ -787,6 +838,27 @@ void FlexCounter::removeSwitchDebugCounters(
}
}

void FlexCounter::removeTunnel(
_In_ sai_object_id_t tunnelVid)
{
SWSS_LOG_ENTER();

auto it = m_tunnelCounterIdsMap.find(tunnelVid);

if (it == m_tunnelCounterIdsMap.end())
{
SWSS_LOG_NOTICE("Trying to remove nonexisting tunnel counter from Id 0x%" PRIx64, tunnelVid);
return;
}

m_tunnelCounterIdsMap.erase(it);

if (m_tunnelCounterIdsMap.empty())
{
removeCollectCountersHandler(TUNNEL_COUNTER_ID_LIST);
}
}

void FlexCounter::checkPluginRegistered(
_In_ const std::string& sha) const
{
Expand All @@ -797,7 +869,8 @@ void FlexCounter::checkPluginRegistered(
m_rifPlugins.find(sha) != m_rifPlugins.end() ||
m_queuePlugins.find(sha) != m_queuePlugins.end() ||
m_priorityGroupPlugins.find(sha) != m_priorityGroupPlugins.end() ||
m_bufferPoolPlugins.find(sha) != m_bufferPoolPlugins.end()
m_bufferPoolPlugins.find(sha) != m_bufferPoolPlugins.end() ||
m_tunnelPlugins.find(sha) != m_tunnelPlugins.end()
)
{
SWSS_LOG_ERROR("Plugin %s already registered", sha.c_str());
Expand Down Expand Up @@ -864,6 +937,18 @@ void FlexCounter::addBufferPoolCounterPlugin(
SWSS_LOG_NOTICE("Buffer pool counters plugin %s registered", sha.c_str());
}

void FlexCounter::addTunnelCounterPlugin(
_In_ const std::string& sha)
{
SWSS_LOG_ENTER();

checkPluginRegistered(sha);

m_tunnelPlugins.insert(sha);

SWSS_LOG_NOTICE("Tunnel counters plugin %s registered", sha.c_str());
}

void FlexCounter::removeCounterPlugins()
{
MUTEX;
Expand All @@ -875,6 +960,7 @@ void FlexCounter::removeCounterPlugins()
m_rifPlugins.clear();
m_priorityGroupPlugins.clear();
m_bufferPoolPlugins.clear();
m_tunnelPlugins.clear();

m_isDiscarded = true;
}
Expand Down Expand Up @@ -942,6 +1028,13 @@ void FlexCounter::addCounterPlugin(
addBufferPoolCounterPlugin(sha);
}
}
else if (field == TUNNEL_PLUGIN_FIELD)
{
for (auto& sha: shaStrings)
{
addTunnelCounterPlugin(sha);
}
}
else
{
SWSS_LOG_ERROR("Field is not supported %s", field.c_str());
Expand Down Expand Up @@ -981,7 +1074,8 @@ bool FlexCounter::allIdsEmpty() const
m_rifCounterIdsMap.empty() &&
m_bufferPoolCounterIdsMap.empty() &&
m_switchDebugCounterIdsMap.empty() &&
m_macsecSAAttrIdsMap.empty();
m_macsecSAAttrIdsMap.empty() &&
m_tunnelCounterIdsMap.empty();
}

bool FlexCounter::allPluginsEmpty() const
Expand All @@ -992,7 +1086,8 @@ bool FlexCounter::allPluginsEmpty() const
m_queuePlugins.empty() &&
m_portPlugins.empty() &&
m_rifPlugins.empty() &&
m_bufferPoolPlugins.empty();
m_bufferPoolPlugins.empty() &&
m_tunnelPlugins.empty();
}

bool FlexCounter::isPortCounterSupported(sai_port_stat_t counter) const
Expand Down Expand Up @@ -1034,6 +1129,14 @@ bool FlexCounter::isBufferPoolCounterSupported(
return m_supportedBufferPoolCounters.count(counter) != 0;
}

bool FlexCounter::isTunnelCounterSupported(
_In_ sai_tunnel_stat_t counter) const
{
SWSS_LOG_ENTER();

return m_supportedTunnelCounters.count(counter) != 0;
}

bool FlexCounter::isStatsModeSupported(
_In_ uint32_t statsMode,
_In_ sai_stats_mode_t statCapability)
Expand Down Expand Up @@ -1597,6 +1700,51 @@ void FlexCounter::collectBufferPoolCounters(
}
}

void FlexCounter::collectTunnelCounters(
_In_ swss::Table &countersTable)
{
SWSS_LOG_ENTER();

// Collect stats for every registered tunnel
for (const auto &kv: m_tunnelCounterIdsMap)
{
const auto &tunnelVid = kv.first;
const auto &tunnelId = kv.second->m_tunnelId;
const auto &tunnelCounterIds = kv.second->m_tunnelCounterIds;

std::vector<uint64_t> tunnelStats(tunnelCounterIds.size());

// Get tunnel stats
sai_status_t status = m_vendorSai->getStats(
SAI_OBJECT_TYPE_TUNNEL,
tunnelId,
static_cast<uint32_t>(tunnelCounterIds.size()),
(const sai_stat_id_t *)tunnelCounterIds.data(),
tunnelStats.data());

if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to get stats of tunnel 0x%" PRIx64 ": %d", tunnelId, status);
continue;
}

// Push all counter values to a single vector
std::vector<swss::FieldValueTuple> values;

for (size_t i = 0; i != tunnelCounterIds.size(); i++)
{
const std::string &counterName = sai_serialize_tunnel_stat(tunnelCounterIds[i]);

values.emplace_back(counterName, std::to_string(tunnelStats[i]));
}

// Write counters to DB
std::string tunnelVidStr = sai_serialize_object_id(tunnelVid);

countersTable.set(tunnelVidStr, values, "");
}
}

void FlexCounter::runPlugins(
_In_ swss::DBConnector& counters_db)
{
Expand Down Expand Up @@ -1675,6 +1823,17 @@ void FlexCounter::runPlugins(
{
runRedisScript(counters_db, sha, bufferPoolVids, argv);
}

std::vector<std::string> tunnelList;
tunnelList.reserve(m_tunnelCounterIdsMap.size());
for (const auto& kv : m_tunnelCounterIdsMap)
{
tunnelList.push_back(sai_serialize_object_id(kv.first));
}
for (const auto& sha : m_tunnelPlugins)
{
runRedisScript(counters_db, sha, tunnelList, argv);
}
}

void FlexCounter::flexCounterThreadRunFunction()
Expand Down Expand Up @@ -2318,6 +2477,41 @@ void FlexCounter::getSupportedBufferPoolCounters(
}
}

void FlexCounter::updateSupportedTunnelCounters(
_In_ sai_object_id_t tunnelRid,
_In_ const std::vector<sai_tunnel_stat_t> &counterIds)
{
SWSS_LOG_ENTER();

if (m_supportedTunnelCounters.size())
{
return;
}

uint64_t value;
for (auto &counter: counterIds)
{
sai_status_t status = m_vendorSai->getStats(
SAI_OBJECT_TYPE_TUNNEL,
tunnelRid,
1,
(const sai_stat_id_t *)&counter,
&value);

if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_INFO("Counter %s is not supported on tunnel RID %s: %s",
sai_serialize_tunnel_stat(counter).c_str(),
sai_serialize_object_id(tunnelRid).c_str(),
sai_serialize_status(status).c_str());

continue;
}

m_supportedTunnelCounters.insert(counter);
}
}

void FlexCounter::updateSupportedBufferPoolCounters(
_In_ sai_object_id_t bufferPoolId,
_In_ const std::vector<sai_buffer_pool_stat_t> &counterIds,
Expand Down Expand Up @@ -2413,6 +2607,10 @@ void FlexCounter::removeCounter(
{
removeMACsecSA(vid);
}
else if (objectType == SAI_OBJECT_TYPE_TUNNEL)
{
removeTunnel(vid);
}
else
{
SWSS_LOG_ERROR("Object type for removal not supported, %s",
Expand Down Expand Up @@ -2568,6 +2766,19 @@ void FlexCounter::addCounter(
{
statsMode = value;
}
else if (objectType == SAI_OBJECT_TYPE_TUNNEL && field == TUNNEL_COUNTER_ID_LIST)
{
std::vector<sai_tunnel_stat_t> tunnelCounterIds;

for (const auto &str : idStrings)
{
sai_tunnel_stat_t stat;
sai_deserialize_tunnel_stat(str.c_str(), &stat);
tunnelCounterIds.push_back(stat);
}

setTunnelCounterList(vid, rid, tunnelCounterIds);
}
else
{
SWSS_LOG_ERROR("Object type and field combination is not supported, object type %s, field %s",
Expand Down
Loading

0 comments on commit 88b62ce

Please sign in to comment.