From 94086867a93b21881387df1f2ba2d3763dc8796f Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Wed, 10 Oct 2018 23:34:54 +0300 Subject: [PATCH] [watarmark] add watermark support (#349) Signed-off-by: Mykola Faryma --- meta/sai_serialize.h | 7 + meta/saiserialize.cpp | 17 ++ syncd/syncd.cpp | 39 ++++ syncd/syncd_flex_counter.cpp | 393 ++++++++++++++++++++++++++++++++++- syncd/syncd_flex_counter.h | 46 +++- 5 files changed, 490 insertions(+), 12 deletions(-) diff --git a/meta/sai_serialize.h b/meta/sai_serialize.h index bef3691ab61b..4a0ddb81ffd9 100644 --- a/meta/sai_serialize.h +++ b/meta/sai_serialize.h @@ -81,6 +81,9 @@ std::string sai_serialize_queue_stat( std::string sai_serialize_ingress_priority_group_stat( _In_ const sai_ingress_priority_group_stat_t counter); +std::string sai_serialize_ingress_priority_group_attr( + _In_ const sai_ingress_priority_group_attr_t attr); + std::string sai_serialize_tunnel_stat( _In_ const sai_tunnel_stat_t counter); @@ -239,6 +242,10 @@ void sai_deserialize_ingress_priority_group_stat( _In_ const std::string& s, _Out_ sai_ingress_priority_group_stat_t& stat); +void sai_deserialize_ingress_priority_group_attr( + _In_ const std::string& s, + _Out_ sai_ingress_priority_group_attr_t& attr); + void sai_deserialize_queue_attr( _In_ const std::string& s, _Out_ sai_queue_attr_t& attr); diff --git a/meta/saiserialize.cpp b/meta/saiserialize.cpp index 155d693cd209..17ea33712dca 100644 --- a/meta/saiserialize.cpp +++ b/meta/saiserialize.cpp @@ -755,6 +755,14 @@ std::string sai_serialize_ingress_priority_group_stat( return sai_serialize_enum(counter, &sai_metadata_enum_sai_ingress_priority_group_stat_t); } +std::string sai_serialize_ingress_priority_group_attr( + _In_ const sai_ingress_priority_group_attr_t attr) +{ + SWSS_LOG_ENTER(); + + return sai_serialize_enum(attr, &sai_metadata_enum_sai_ingress_priority_group_attr_t); +} + std::string sai_serialize_tunnel_stat( _In_ const sai_tunnel_stat_t counter) { @@ -2863,6 +2871,15 @@ void sai_deserialize_ingress_priority_group_stat( sai_deserialize_enum(s, &sai_metadata_enum_sai_ingress_priority_group_stat_t, (int32_t&)stat); } +void sai_deserialize_ingress_priority_group_attr( + _In_ const std::string& s, + _Out_ sai_ingress_priority_group_attr_t& attr) +{ + SWSS_LOG_ENTER(); + + sai_deserialize_enum(s, &sai_metadata_enum_sai_ingress_priority_group_attr_t, (int32_t&)attr); +} + void sai_deserialize_queue_attr( _In_ const std::string& s, _Out_ sai_queue_attr_t& attr) diff --git a/syncd/syncd.cpp b/syncd/syncd.cpp index 31a5a829ce45..41137d3344e3 100644 --- a/syncd/syncd.cpp +++ b/syncd/syncd.cpp @@ -2748,6 +2748,14 @@ void processFlexCounterGroupEvent( FlexCounter::addQueueCounterPlugin(sha, groupName); } } + else if (field == PG_PLUGIN_FIELD) + { + auto shaStrings = swss::tokenize(value, ','); + for (const auto &sha : shaStrings) + { + FlexCounter::addPriorityGroupCounterPlugin(sha, groupName); + } + } else if (field == PORT_PLUGIN_FIELD) { auto shaStrings = swss::tokenize(value, ','); @@ -2760,6 +2768,10 @@ void processFlexCounterGroupEvent( { FlexCounter::updateFlexCounterStatus(value, groupName); } + else if (field == STATS_MODE_FIELD) + { + FlexCounter::updateFlexCounterStatsMode(value, groupName); + } else { SWSS_LOG_ERROR("Field is not supported %s", field.c_str()); @@ -2807,6 +2819,10 @@ void processFlexCounterEvent( { FlexCounter::removeQueue(vid, groupName); } + else if (objectType == SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP) + { + FlexCounter::removePriorityGroup(vid, groupName); + } else { SWSS_LOG_ERROR("Object type for removal not supported, %s", objectTypeStr.c_str()); @@ -2857,6 +2873,29 @@ void processFlexCounterEvent( FlexCounter::setQueueAttrList(vid, rid, groupName, queueAttrIds); } + else if (objectType == SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP && field == PG_COUNTER_ID_LIST) + { + std::vector pgCounterIds; + for (const auto &str : idStrings) + { + sai_ingress_priority_group_stat_t stat; + sai_deserialize_ingress_priority_group_stat(str, stat); + pgCounterIds.push_back(stat); + } + FlexCounter::setPriorityGroupCounterList(vid, rid, groupName, pgCounterIds); + } + else if (objectType == SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP && field == PG_ATTR_ID_LIST) + { + std::vector pgAttrIds; + for (const auto &str : idStrings) + { + sai_ingress_priority_group_attr_t attr; + sai_deserialize_ingress_priority_group_attr(str, attr); + pgAttrIds.push_back(attr); + } + + FlexCounter::setPriorityGroupAttrList(vid, rid, groupName, pgAttrIds); + } else { SWSS_LOG_ERROR("Object type and field combination is not supported, object type %s, field %s", objectTypeStr.c_str(), field.c_str()); diff --git a/syncd/syncd_flex_counter.cpp b/syncd/syncd_flex_counter.cpp index f3a4537dc465..4db13103c8d8 100644 --- a/syncd/syncd_flex_counter.cpp +++ b/syncd/syncd_flex_counter.cpp @@ -7,6 +7,7 @@ static std::map> g_flex_counters_map; // List with supported counters static std::set supportedPortCounters; static std::set supportedQueueCounters; +static std::set supportedPriorityGroupCounters; FlexCounter::PortCounterIds::PortCounterIds( _In_ sai_object_id_t port, @@ -32,6 +33,22 @@ FlexCounter::QueueAttrIds::QueueAttrIds( SWSS_LOG_ENTER(); } +FlexCounter::IngressPriorityGroupAttrIds::IngressPriorityGroupAttrIds( + _In_ sai_object_id_t priorityGroup, + _In_ const std::vector &priorityGroupIds): + priorityGroupId(priorityGroup), priorityGroupAttrIds(priorityGroupIds) +{ + SWSS_LOG_ENTER(); +} + +FlexCounter::IngressPriorityGroupCounterIds::IngressPriorityGroupCounterIds( + _In_ sai_object_id_t priorityGroup, + _In_ const std::vector &priorityGroupIds): + priorityGroupId(priorityGroup), priorityGroupCounterIds(priorityGroupIds) +{ + SWSS_LOG_ENTER(); +} + void FlexCounter::setPollInterval( _In_ uint32_t pollInterval, _In_ std::string instanceId) @@ -64,6 +81,28 @@ void FlexCounter::updateFlexCounterStatus( } +void FlexCounter::updateFlexCounterStatsMode( + _In_ std::string mode, + _In_ std::string instanceId) +{ + SWSS_LOG_ENTER(); + FlexCounter &fc = getInstance(instanceId); + if (mode == STATS_MODE_READ) + { + fc.m_statsMode = SAI_STATS_MODE_READ; + SWSS_LOG_DEBUG("Set STATS MODE %s for FC %s", mode.c_str(), fc.m_instanceId.c_str()); + } + else if (mode == STATS_MODE_READ_AND_CLEAR) + { + fc.m_statsMode = SAI_STATS_MODE_READ_AND_CLEAR; + SWSS_LOG_DEBUG("Set STATS MODE %s for FC %s", mode.c_str(), fc.m_instanceId.c_str()); + } + else + { + SWSS_LOG_WARN("Input value %s is not supported for Flex counter stats mode, enter STATS_MODE_READ or STATS_MODE_READ_AND_CLEAR", mode.c_str()); + } + } + /* The current implementation of 'setPortCounterList' and 'setQueueCounterList' are * not the same. Need to refactor these two functions to have the similar logic. * Either the full SAI attributes are queried once, or each of the needed counters @@ -87,7 +126,7 @@ void FlexCounter::setPortCounterList( // Remove unsupported counters std::vector supportedIds; - for(auto &counter : counterIds) + for (auto &counter : counterIds) { if (fc.isPortCounterSupported(counter)) { @@ -119,7 +158,10 @@ void FlexCounter::setPortCounterList( fc.m_portCounterIdsMap.emplace(portVid, portCounterIds); // Start flex counter thread in case it was not running due to empty counter IDs map - if (fc.m_pollInterval > 0) fc.startFlexCounterThread(); + if (fc.m_pollInterval > 0) + { + fc.startFlexCounterThread(); + } } void FlexCounter::setQueueCounterList( @@ -136,7 +178,7 @@ void FlexCounter::setQueueCounterList( // Remove unsupported counters std::vector supportedIds; - for(auto &counter : counterIds) + for (auto &counter : counterIds) { if (fc.isQueueCounterSupported(counter)) { @@ -189,7 +231,10 @@ void FlexCounter::setQueueCounterList( fc.m_queueCounterIdsMap.emplace(queueVid, queueCounterIds); // Start flex counter thread in case it was not running due to empty counter IDs map - if (fc.m_pollInterval > 0) fc.startFlexCounterThread(); + if (fc.m_pollInterval > 0) + { + fc.startFlexCounterThread(); + } } void FlexCounter::setQueueAttrList( @@ -213,9 +258,111 @@ void FlexCounter::setQueueAttrList( fc.m_queueAttrIdsMap.emplace(queueVid, queueAttrIds); // Start flex counter thread in case it was not running due to empty counter IDs map - if (fc.m_pollInterval > 0) fc.startFlexCounterThread(); + if (fc.m_pollInterval > 0) + { + fc.startFlexCounterThread(); + } } +void FlexCounter::setPriorityGroupCounterList( + _In_ sai_object_id_t priorityGroupVid, + _In_ sai_object_id_t priorityGroupId, + _In_ std::string instanceId, + _In_ const std::vector &counterIds) +{ + SWSS_LOG_ENTER(); + + FlexCounter &fc = getInstance(instanceId); + + fc.saiUpdateSupportedPriorityGroupCounters(priorityGroupId, counterIds); + + // Remove unsupported counters + std::vector supportedIds; + for (auto &counter : counterIds) + { + if (fc.isPriorityGroupCounterSupported(counter)) + { + supportedIds.push_back(counter); + } + } + + if (supportedIds.size() == 0) + { + SWSS_LOG_ERROR("Priority group %s does not have supported counters", sai_serialize_object_id(priorityGroupId).c_str()); + + // Remove flex counter if all counter IDs and plugins are unregistered + if (fc.isEmpty()) + { + removeInstance(instanceId); + } + + return; + } + + // Check if PG is able to provide the statistic + std::vector priorityGroupStats(supportedIds.size()); + sai_status_t status = sai_metadata_sai_buffer_api->get_ingress_priority_group_stats( + priorityGroupId, + static_cast(supportedIds.size()), + supportedIds.data(), + priorityGroupStats.data()); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Priority group %s can't provide the statistic", sai_serialize_object_id(priorityGroupId).c_str()); + + // Remove flex counter if all counter IDs and plugins are unregistered + if (fc.isEmpty()) + { + removeInstance(instanceId); + } + + return; + } + + auto it = fc.m_priorityGroupCounterIdsMap.find(priorityGroupVid); + if (it != fc.m_priorityGroupCounterIdsMap.end()) + { + (*it).second->priorityGroupCounterIds = supportedIds; + return; + } + + auto priorityGroupCounterIds = std::make_shared(priorityGroupId, supportedIds); + fc.m_priorityGroupCounterIdsMap.emplace(priorityGroupVid, priorityGroupCounterIds); + + // Start flex counter thread in case it was not running due to empty counter IDs map + if (fc.m_pollInterval > 0) + { + fc.startFlexCounterThread(); + } +} + +void FlexCounter::setPriorityGroupAttrList( + _In_ sai_object_id_t priorityGroupVid, + _In_ sai_object_id_t priorityGroupId, + _In_ std::string instanceId, + _In_ const std::vector &attrIds) +{ + SWSS_LOG_ENTER(); + + FlexCounter &fc = getInstance(instanceId); + + auto it = fc.m_priorityGroupAttrIdsMap.find(priorityGroupVid); + if (it != fc.m_priorityGroupAttrIdsMap.end()) + { + (*it).second->priorityGroupAttrIds = attrIds; + return; + } + + auto priorityGroupAttrIds = std::make_shared(priorityGroupId, attrIds); + fc.m_priorityGroupAttrIdsMap.emplace(priorityGroupVid, priorityGroupAttrIds); + + // Start flex counter thread in case it was not running due to empty counter IDs map + if (fc.m_pollInterval > 0) + { + fc.startFlexCounterThread(); + } +} void FlexCounter::removePort( _In_ sai_object_id_t portVid, @@ -282,6 +429,42 @@ void FlexCounter::removeQueue( } } +void FlexCounter::removePriorityGroup( + _In_ sai_object_id_t priorityGroupVid, + _In_ std::string instanceId) +{ + SWSS_LOG_ENTER(); + + bool found = false; + FlexCounter &fc = getInstance(instanceId); + + auto counterIter = fc.m_priorityGroupCounterIdsMap.find(priorityGroupVid); + if (counterIter != fc.m_priorityGroupCounterIdsMap.end()) + { + fc.m_priorityGroupCounterIdsMap.erase(counterIter); + found = true; + } + + auto attrIter = fc.m_priorityGroupAttrIdsMap.find(priorityGroupVid); + if (attrIter != fc.m_priorityGroupAttrIdsMap.end()) + { + fc.m_priorityGroupAttrIdsMap.erase(attrIter); + found = true; + } + + if (!found) + { + SWSS_LOG_NOTICE("Trying to remove nonexisting PG from flex counter 0x%lx", priorityGroupVid); + return; + } + + // Remove flex counter if all counter IDs and plugins are unregistered + if (fc.isEmpty()) + { + removeInstance(instanceId); + } +} + void FlexCounter::addPortCounterPlugin( _In_ std::string sha, _In_ std::string instanceId) @@ -291,7 +474,8 @@ void FlexCounter::addPortCounterPlugin( FlexCounter &fc = getInstance(instanceId); if (fc.m_portPlugins.find(sha) != fc.m_portPlugins.end() || - fc.m_queuePlugins.find(sha) != fc.m_queuePlugins.end()) + fc.m_queuePlugins.find(sha) != fc.m_queuePlugins.end() || + fc.m_priorityGroupPlugins.find(sha) != fc.m_priorityGroupPlugins.end()) { SWSS_LOG_ERROR("Plugin %s already registered", sha.c_str()); } @@ -309,7 +493,8 @@ void FlexCounter::addQueueCounterPlugin( FlexCounter &fc = getInstance(instanceId); if (fc.m_portPlugins.find(sha) != fc.m_portPlugins.end() || - fc.m_queuePlugins.find(sha) != fc.m_queuePlugins.end()) + fc.m_queuePlugins.find(sha) != fc.m_queuePlugins.end() || + fc.m_priorityGroupPlugins.find(sha) != fc.m_priorityGroupPlugins.end()) { SWSS_LOG_ERROR("Plugin %s already registered", sha.c_str()); } @@ -318,6 +503,25 @@ void FlexCounter::addQueueCounterPlugin( SWSS_LOG_NOTICE("Queue counters plugin %s registered", sha.c_str()); } +void FlexCounter::addPriorityGroupCounterPlugin( + _In_ std::string sha, + _In_ std::string instanceId) +{ + SWSS_LOG_ENTER(); + + FlexCounter &fc = getInstance(instanceId); + + if (fc.m_portPlugins.find(sha) != fc.m_portPlugins.end() || + fc.m_queuePlugins.find(sha) != fc.m_queuePlugins.end() || + fc.m_priorityGroupPlugins.find(sha) != fc.m_priorityGroupPlugins.end()) + { + SWSS_LOG_ERROR("Plugin %s already registered", sha.c_str()); + } + + fc.m_priorityGroupPlugins.insert(sha); + SWSS_LOG_NOTICE("Priority group counters plugin %s registered", sha.c_str()); +} + void FlexCounter::removeCounterPlugin( _In_ std::string sha, _In_ std::string instanceId) @@ -328,6 +532,7 @@ void FlexCounter::removeCounterPlugin( fc.m_queuePlugins.erase(sha); fc.m_portPlugins.erase(sha); + fc.m_priorityGroupPlugins.erase(sha); // Remove flex counter if all counter IDs and plugins are unregistered if (fc.isEmpty()) @@ -345,6 +550,7 @@ void FlexCounter::removeCounterPlugin( fc.m_queuePlugins.clear(); fc.m_portPlugins.clear(); + fc.m_priorityGroupPlugins.clear(); // Remove flex counter if all counter IDs and plugins are unregistered if (fc.isEmpty()) @@ -372,7 +578,10 @@ bool FlexCounter::isEmpty() { SWSS_LOG_ENTER(); - return m_queueCounterIdsMap.empty() && + return m_priorityGroupCounterIdsMap.empty() && + m_priorityGroupAttrIdsMap.empty() && + m_priorityGroupPlugins.empty() && + m_queueCounterIdsMap.empty() && m_portCounterIdsMap.empty() && m_queueAttrIdsMap.empty() && m_queuePlugins.empty() && @@ -393,6 +602,13 @@ bool FlexCounter::isQueueCounterSupported(sai_queue_stat_t counter) const return supportedQueueCounters.count(counter) != 0; } +bool FlexCounter::isPriorityGroupCounterSupported(sai_ingress_priority_group_stat_t counter) const +{ + SWSS_LOG_ENTER(); + + return supportedPriorityGroupCounters.count(counter) != 0; +} + FlexCounter::FlexCounter(std::string instanceId) : m_instanceId(instanceId) { SWSS_LOG_ENTER(); @@ -426,12 +642,16 @@ void FlexCounter::collectCounters( std::map> portCounterIdsMap; std::map> queueCounterIdsMap; std::map> queueAttrIdsMap; + std::map> priorityGroupCounterIdsMap; + std::map> priorityGroupAttrIdsMap; { std::lock_guard lock(g_mutex); portCounterIdsMap = m_portCounterIdsMap; queueCounterIdsMap = m_queueCounterIdsMap; queueAttrIdsMap = m_queueAttrIdsMap; + priorityGroupCounterIdsMap = m_priorityGroupCounterIdsMap; + priorityGroupAttrIdsMap = m_priorityGroupAttrIdsMap; } // Collect stats for every registered port @@ -443,7 +663,7 @@ void FlexCounter::collectCounters( std::vector portStats(portCounterIds.size()); - // Get port stats for queue + // Get port stats sai_status_t status = sai_metadata_sai_port_api->get_port_stats( portId, static_cast(portCounterIds.size()), @@ -480,11 +700,27 @@ void FlexCounter::collectCounters( std::vector queueStats(queueCounterIds.size()); // Get queue stats - sai_status_t status = sai_metadata_sai_queue_api->get_queue_stats( + sai_status_t status = -1; +// TODO: replace if with get_queue_stats_ext() call when it's fully supported +// Example: +// sai_status_t status = sai_metadata_sai_queue_api->get_queue_stats_ext( +// queueId, +// static_cast(queueCounterIds.size()), +// queueCounterIds.data(), +// m_statsMode, +// queueStats.data()); + status = sai_metadata_sai_queue_api->get_queue_stats( queueId, static_cast(queueCounterIds.size()), queueCounterIds.data(), queueStats.data()); + if (m_statsMode == SAI_STATS_MODE_READ_AND_CLEAR){ + status = sai_metadata_sai_queue_api->clear_queue_stats( + queueId, + static_cast(queueCounterIds.size()), + queueCounterIds.data()); + } + if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("Failed to get stats of queue 0x%lx: %d", queueVid, status); @@ -515,7 +751,7 @@ void FlexCounter::collectCounters( std::vector queueAttr(queueAttrIds.size()); - for (uint64_t i =0; i< queueAttrIds.size(); i++) + for (size_t i = 0; i < queueAttrIds.size(); i++) { queueAttr[i].id = queueAttrIds[i]; } @@ -548,6 +784,93 @@ void FlexCounter::collectCounters( countersTable.set(queueVidStr, values, ""); } + // Collect stats for every registered ingress priority group + for (const auto &kv: priorityGroupCounterIdsMap) + { + const auto &priorityGroupVid = kv.first; + const auto &priorityGroupId = kv.second->priorityGroupId; + const auto &priorityGroupCounterIds = kv.second->priorityGroupCounterIds; + + std::vector priorityGroupStats(priorityGroupCounterIds.size()); + + // Get PG stats + sai_status_t status = -1; +// TODO: replace if with get_ingress_priority_group_stats_ext() call when it's fully supported + status = sai_metadata_sai_buffer_api->get_ingress_priority_group_stats( + priorityGroupId, + static_cast(priorityGroupCounterIds.size()), + priorityGroupCounterIds.data(), + priorityGroupStats.data()); + if (m_statsMode == SAI_STATS_MODE_READ_AND_CLEAR){ + status = sai_metadata_sai_buffer_api->clear_ingress_priority_group_stats( + priorityGroupId, + static_cast(priorityGroupCounterIds.size()), + priorityGroupCounterIds.data()); + } + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Failed to get %ld/%ld stats of PG 0x%lx: %d", priorityGroupCounterIds.size(), priorityGroupStats.size(), priorityGroupVid, status); + continue; + } + + // Push all counter values to a single vector + std::vector values; + + for (size_t i = 0; i != priorityGroupCounterIds.size(); i++) + { + const std::string &counterName = sai_serialize_ingress_priority_group_stat(priorityGroupCounterIds[i]); + values.emplace_back(counterName, std::to_string(priorityGroupStats[i])); + } + + // Write counters to DB + std::string priorityGroupVidStr = sai_serialize_object_id(priorityGroupVid); + + countersTable.set(priorityGroupVidStr, values, ""); + } + + // Collect attrs for every registered priority group + for (const auto &kv: priorityGroupAttrIdsMap) + { + const auto &priorityGroupVid = kv.first; + const auto &priorityGroupId = kv.second->priorityGroupId; + const auto &priorityGroupAttrIds = kv.second->priorityGroupAttrIds; + + std::vector priorityGroupAttr(priorityGroupAttrIds.size()); + + for (size_t i = 0; i < priorityGroupAttrIds.size(); i++) + { + priorityGroupAttr[i].id = priorityGroupAttrIds[i]; + } + + // Get PG attr + sai_status_t status = sai_metadata_sai_buffer_api->get_ingress_priority_group_attribute( + priorityGroupId, + static_cast(priorityGroupAttrIds.size()), + priorityGroupAttr.data()); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Failed to get attr of PG 0x%lx: %d", priorityGroupVid, status); + continue; + } + + // Push all counter values to a single vector + std::vector values; + + for (size_t i = 0; i != priorityGroupAttrIds.size(); i++) + { + const std::string &counterName = sai_serialize_ingress_priority_group_attr(priorityGroupAttrIds[i]); + auto meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, priorityGroupAttr[i].id); + + values.emplace_back(counterName, sai_serialize_attr_value(*meta, priorityGroupAttr[i])); + } + // Write counters to DB + std::string priorityGroupVidStr = sai_serialize_object_id(priorityGroupVid); + + countersTable.set(priorityGroupVidStr, values, ""); + } + countersTable.flush(); } @@ -559,8 +882,11 @@ void FlexCounter::runPlugins( std::map> portCounterIdsMap; std::map> queueCounterIdsMap; std::map> queueAttrIdsMap; + std::map> priorityGroupCounterIdsMap; + std::map> priorityGroupAttrIdsMap; std::set queuePlugins; std::set portPlugins; + std::set priorityGroupPlugins; { std::lock_guard lock(g_mutex); @@ -569,6 +895,9 @@ void FlexCounter::runPlugins( queueAttrIdsMap = m_queueAttrIdsMap; queuePlugins = m_queuePlugins; portPlugins = m_portPlugins; + priorityGroupCounterIdsMap = m_priorityGroupCounterIdsMap; + priorityGroupAttrIdsMap = m_priorityGroupAttrIdsMap; + priorityGroupPlugins = m_priorityGroupPlugins; } const std::vector argv = @@ -601,6 +930,18 @@ void FlexCounter::runPlugins( { runRedisScript(db, sha, queueList, argv); } + + std::vector priorityGroupList; + priorityGroupList.reserve(priorityGroupCounterIdsMap.size()); + for (const auto& kv : priorityGroupCounterIdsMap) + { + priorityGroupList.push_back(sai_serialize_object_id(kv.first)); + } + + for (const auto& sha : priorityGroupPlugins) + { + runRedisScript(db, sha, priorityGroupList, argv); + } } void FlexCounter::flexCounterThread(void) @@ -626,6 +967,7 @@ void FlexCounter::flexCounterThread(void) std::chrono::duration_cast(finish - start).count()); uint32_t correction = delay % m_pollInterval; + SWSS_LOG_DEBUG("End of flex counter thread FC %s, took %d ms", m_instanceId.c_str(), delay); std::unique_lock lk(m_mtxSleep); m_cvSleep.wait_for(lk, std::chrono::milliseconds(m_pollInterval - correction)); } @@ -723,3 +1065,32 @@ void FlexCounter::saiUpdateSupportedQueueCounters( } } } + +void FlexCounter::saiUpdateSupportedPriorityGroupCounters( + _In_ sai_object_id_t priorityGroupId, + _In_ const std::vector &counterIds) +{ + SWSS_LOG_ENTER(); + + uint64_t value; + supportedPriorityGroupCounters.clear(); + + for (auto &counter : counterIds) + { + sai_status_t status = sai_metadata_sai_buffer_api->get_ingress_priority_group_stats(priorityGroupId, 1, &counter, &value); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_INFO("Counter %s is not supported on PG %s, rv: %s", + sai_serialize_ingress_priority_group_stat(counter).c_str(), + sai_serialize_object_id(priorityGroupId).c_str(), + sai_serialize_status(status).c_str()); + + continue; + } + else + { + supportedPriorityGroupCounters.insert(counter); + } + } +} diff --git a/syncd/syncd_flex_counter.h b/syncd/syncd_flex_counter.h index 51499be86629..fba93e92868f 100644 --- a/syncd/syncd_flex_counter.h +++ b/syncd/syncd_flex_counter.h @@ -27,15 +27,27 @@ class FlexCounter _In_ sai_object_id_t queueId, _In_ std::string instanceId, _In_ const std::vector &counterIds); + static void setPriorityGroupCounterList( + _In_ sai_object_id_t priorityGroupVid, + _In_ sai_object_id_t priorityGroupId, + _In_ std::string instanceId, + _In_ const std::vector &counterIds); static void setQueueAttrList( _In_ sai_object_id_t queueVid, _In_ sai_object_id_t queueId, _In_ std::string instanceId, _In_ const std::vector &attrIds); + static void setPriorityGroupAttrList( + _In_ sai_object_id_t priorityGroupVid, + _In_ sai_object_id_t priorityGroupId, + _In_ std::string instanceId, + _In_ const std::vector &attrIds); static void updateFlexCounterStatus( _In_ std::string status, _In_ std::string instanceId); - + static void updateFlexCounterStatsMode( + _In_ std::string mode, + _In_ std::string instanceId); static void removePort( _In_ sai_object_id_t portVid, @@ -43,6 +55,9 @@ class FlexCounter static void removeQueue( _In_ sai_object_id_t queueVid, _In_ std::string instanceId); + static void removePriorityGroup( + _In_ sai_object_id_t priorityGroupVid, + _In_ std::string instanceId); static void addPortCounterPlugin( _In_ std::string sha, @@ -50,6 +65,9 @@ class FlexCounter static void addQueueCounterPlugin( _In_ std::string sha, _In_ std::string instanceId); + static void addPriorityGroupCounterPlugin( + _In_ std::string sha, + _In_ std::string instanceId); static void removeCounterPlugin( _In_ std::string sha, _In_ std::string instanceId); @@ -82,6 +100,26 @@ class FlexCounter std::vector queueAttrIds; }; + struct IngressPriorityGroupCounterIds + { + IngressPriorityGroupCounterIds( + _In_ sai_object_id_t priorityGroup, + _In_ const std::vector &priorityGroupIds); + + sai_object_id_t priorityGroupId; + std::vector priorityGroupCounterIds; + }; + + struct IngressPriorityGroupAttrIds + { + IngressPriorityGroupAttrIds( + _In_ sai_object_id_t priorityGroup, + _In_ const std::vector &priorityGroupIds); + + sai_object_id_t priorityGroupId; + std::vector priorityGroupAttrIds; + }; + struct PortCounterIds { PortCounterIds( @@ -104,18 +142,23 @@ class FlexCounter void saiUpdateSupportedPortCounters(sai_object_id_t portId); void saiUpdateSupportedQueueCounters(sai_object_id_t queueId, const std::vector &counterIds); + void saiUpdateSupportedPriorityGroupCounters(sai_object_id_t priorityGroupId, const std::vector &counterIds); bool isPortCounterSupported(sai_port_stat_t counter) const; bool isQueueCounterSupported(sai_queue_stat_t counter) const; + bool isPriorityGroupCounterSupported(sai_ingress_priority_group_stat_t counter) const; bool isEmpty(); // Key is a Virtual ID std::map> m_portCounterIdsMap; std::map> m_queueCounterIdsMap; std::map> m_queueAttrIdsMap; + std::map> m_priorityGroupCounterIdsMap; + std::map> m_priorityGroupAttrIdsMap; // Plugins std::set m_queuePlugins; std::set m_portPlugins; + std::set m_priorityGroupPlugins; std::atomic_bool m_runFlexCounterThread = { false }; std::shared_ptr m_flexCounterThread = nullptr; @@ -124,6 +167,7 @@ class FlexCounter uint32_t m_pollInterval = 0; std::string m_instanceId; + sai_stats_mode_t m_statsMode; bool m_enable = false; };