From 145ea447bca16ebfbe28d497e6a224718308fe99 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Sat, 2 Feb 2019 06:02:29 +0200 Subject: [PATCH] [flex counter] handle router interface stats (#410) * [flex counter] handle router interface stats Signed-off-by: Mykola Faryma * allign with new SAI headers Signed-off-by: Mykola Faryma * update aspellcheck dictionary Signed-off-by: Mykola Faryma --- meta/sai_serialize.h | 3 + meta/saiserialize.cpp | 8 ++ syncd/syncd.cpp | 15 ++++ syncd/syncd_flex_counter.cpp | 163 +++++++++++++++++++++++++++++++++++ syncd/syncd_flex_counter.h | 21 +++++ tests/aspell.en.pws | 2 + 6 files changed, 212 insertions(+) diff --git a/meta/sai_serialize.h b/meta/sai_serialize.h index 1f1d8832fd66..daa9079c2ec3 100644 --- a/meta/sai_serialize.h +++ b/meta/sai_serialize.h @@ -90,6 +90,9 @@ std::string sai_serialize_port_pool_stat( std::string sai_serialize_queue_stat( _In_ const sai_queue_stat_t counter); +std::string sai_serialize_router_interface_stat( + _In_ const sai_router_interface_stat_t counter); + std::string sai_serialize_ingress_priority_group_stat( _In_ const sai_ingress_priority_group_stat_t counter); diff --git a/meta/saiserialize.cpp b/meta/saiserialize.cpp index d04371452a46..5310030b1148 100644 --- a/meta/saiserialize.cpp +++ b/meta/saiserialize.cpp @@ -826,6 +826,14 @@ std::string sai_serialize_queue_stat( return sai_serialize_enum(counter, &sai_metadata_enum_sai_queue_stat_t); } +std::string sai_serialize_router_interface_stat( + _In_ const sai_router_interface_stat_t counter) +{ + SWSS_LOG_ENTER(); + + return sai_serialize_enum(counter, &sai_metadata_enum_sai_router_interface_stat_t); +} + std::string sai_serialize_ingress_priority_group_stat( _In_ const sai_ingress_priority_group_stat_t counter) { diff --git a/syncd/syncd.cpp b/syncd/syncd.cpp index 6b15269f567b..ca3160d7c7b4 100644 --- a/syncd/syncd.cpp +++ b/syncd/syncd.cpp @@ -2884,6 +2884,10 @@ void processFlexCounterEvent( { FlexCounter::removePriorityGroup(vid, groupName); } + else if (objectType == SAI_OBJECT_TYPE_ROUTER_INTERFACE) + { + FlexCounter::removeRif(vid, groupName); + } else { SWSS_LOG_ERROR("Object type for removal not supported, %s", objectTypeStr.c_str()); @@ -2957,6 +2961,17 @@ void processFlexCounterEvent( FlexCounter::setPriorityGroupAttrList(vid, rid, groupName, pgAttrIds); } + else if (objectType == SAI_OBJECT_TYPE_ROUTER_INTERFACE && field == RIF_COUNTER_ID_LIST) + { + std::vector rifCounterIds; + for (const auto &str : idStrings) + { + sai_router_interface_stat_t stat; + sai_deserialize_router_interface_stat(str.c_str(), &stat); + rifCounterIds.push_back(stat); + } + FlexCounter::setRifCounterList(vid, rid, groupName, rifCounterIds); + } 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 22fd6393e755..34c803cd8782 100644 --- a/syncd/syncd_flex_counter.cpp +++ b/syncd/syncd_flex_counter.cpp @@ -8,6 +8,7 @@ static std::map> g_flex_counters_map; static std::set supportedPortCounters; static std::set supportedQueueCounters; static std::set supportedPriorityGroupCounters; +static std::set supportedRifCounters; FlexCounter::PortCounterIds::PortCounterIds( _In_ sai_object_id_t port, @@ -49,6 +50,14 @@ FlexCounter::IngressPriorityGroupCounterIds::IngressPriorityGroupCounterIds( SWSS_LOG_ENTER(); } +FlexCounter::RifCounterIds::RifCounterIds( + _In_ sai_object_id_t rif, + _In_ const std::vector &rifIds): + rifId(rif), rifCounterIds(rifIds) +{ + SWSS_LOG_ENTER(); +} + void FlexCounter::setPollInterval( _In_ uint32_t pollInterval, _In_ std::string instanceId) @@ -364,6 +373,62 @@ void FlexCounter::setPriorityGroupAttrList( } } +void FlexCounter::setRifCounterList( + _In_ sai_object_id_t rifVid, + _In_ sai_object_id_t rifId, + _In_ std::string instanceId, + _In_ const std::vector &counterIds) +{ + SWSS_LOG_ENTER(); + + FlexCounter &fc = getInstance(instanceId); + + // Initialize the supported counters list before setting + if (supportedRifCounters.empty()) + { + fc.saiUpdateSupportedRifCounters(rifId); + } + + // Remove unsupported counters + std::vector supportedIds; + for (auto &counter : counterIds) + { + if (fc.isRifCounterSupported(counter)) + { + supportedIds.push_back(counter); + } + } + + if (supportedIds.empty()) + { + SWSS_LOG_ERROR("Router interface %s does not have supported counters", sai_serialize_object_id(rifId).c_str()); + + // Remove flex counter if all counter IDs and plugins are unregistered + if (fc.isEmpty()) + { + removeInstance(instanceId); + } + + return; + } + + auto it = fc.m_rifCounterIdsMap.find(rifVid); + if (it != fc.m_rifCounterIdsMap.end()) + { + (*it).second->rifCounterIds = supportedIds; + return; + } + + auto rifCounterIds = std::make_shared(rifId, supportedIds); + fc.m_rifCounterIdsMap.emplace(rifVid, rifCounterIds); + + // 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, _In_ std::string instanceId) @@ -465,6 +530,35 @@ void FlexCounter::removePriorityGroup( } } +void FlexCounter::removeRif( + _In_ sai_object_id_t rifVid, + _In_ std::string instanceId) +{ + SWSS_LOG_ENTER(); + + FlexCounter &fc = getInstance(instanceId); + + auto it = fc.m_rifCounterIdsMap.find(rifVid); + if (it == fc.m_rifCounterIdsMap.end()) + { + SWSS_LOG_NOTICE("Trying to remove nonexisting router interface counter from Id 0x%lx", rifVid); + // Remove flex counter if all counter IDs and plugins are unregistered + if (fc.isEmpty()) + { + removeInstance(instanceId); + } + return; + } + + fc.m_rifCounterIdsMap.erase(it); + + // 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) @@ -609,6 +703,13 @@ bool FlexCounter::isPriorityGroupCounterSupported(sai_ingress_priority_group_sta return supportedPriorityGroupCounters.count(counter) != 0; } +bool FlexCounter::isRifCounterSupported(sai_router_interface_stat_t counter) const +{ + SWSS_LOG_ENTER(); + + return supportedRifCounters.count(counter) != 0; +} + FlexCounter::FlexCounter(std::string instanceId) : m_instanceId(instanceId) { SWSS_LOG_ENTER(); @@ -644,6 +745,7 @@ void FlexCounter::collectCounters( std::map> queueAttrIdsMap; std::map> priorityGroupCounterIdsMap; std::map> priorityGroupAttrIdsMap; + std::map> rifCounterIdsMap; { std::lock_guard lock(g_mutex); @@ -652,6 +754,7 @@ void FlexCounter::collectCounters( queueAttrIdsMap = m_queueAttrIdsMap; priorityGroupCounterIdsMap = m_priorityGroupCounterIdsMap; priorityGroupAttrIdsMap = m_priorityGroupAttrIdsMap; + rifCounterIdsMap = m_rifCounterIdsMap; } // Collect stats for every registered port @@ -870,6 +973,41 @@ void FlexCounter::collectCounters( countersTable.set(priorityGroupVidStr, values, ""); } + // Collect stats for every registered router interface + for (const auto &kv: rifCounterIdsMap) + { + const auto &rifVid = kv.first; + const auto &rifId = kv.second->rifId; + const auto &rifCounterIds = kv.second->rifCounterIds; + + std::vector rifStats(rifCounterIds.size()); + + // Get rif stats + sai_status_t status = sai_metadata_sai_router_interface_api->get_router_interface_stats( + rifId, + static_cast(rifCounterIds.size()), + (const sai_stat_id_t *)rifCounterIds.data(), + rifStats.data()); + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Failed to get stats of router interface 0x%lx: %d", rifId, status); + continue; + } + + // Push all counter values to a single vector + std::vector values; + + for (size_t i = 0; i != rifCounterIds.size(); i++) + { + const std::string &counterName = sai_serialize_router_interface_stat(rifCounterIds[i]); + values.emplace_back(counterName, std::to_string(rifStats[i])); + } + + // Write counters to DB + std::string rifVidStr = sai_serialize_object_id(rifVid); + + countersTable.set(rifVidStr, values, ""); + } countersTable.flush(); } @@ -1094,3 +1232,28 @@ void FlexCounter::saiUpdateSupportedPriorityGroupCounters( } } } + +void FlexCounter::saiUpdateSupportedRifCounters(sai_object_id_t rifId) +{ + SWSS_LOG_ENTER(); + + uint64_t value; + for (int cntr_id = SAI_ROUTER_INTERFACE_STAT_IN_OCTETS; cntr_id <= SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS; ++cntr_id) + { + sai_router_interface_stat_t counter = static_cast(cntr_id); + + sai_status_t status = sai_metadata_sai_router_interface_api->get_router_interface_stats(rifId, 1, (const sai_stat_id_t *)&counter, &value); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_INFO("Counter %s is not supported on router interface RID %s: %s", + sai_serialize_router_interface_stat(counter).c_str(), + sai_serialize_object_id(rifId).c_str(), + sai_serialize_status(status).c_str()); + + continue; + } + + supportedRifCounters.insert(counter); + } +} diff --git a/syncd/syncd_flex_counter.h b/syncd/syncd_flex_counter.h index fba93e92868f..233d48932ca9 100644 --- a/syncd/syncd_flex_counter.h +++ b/syncd/syncd_flex_counter.h @@ -32,6 +32,11 @@ class FlexCounter _In_ sai_object_id_t priorityGroupId, _In_ std::string instanceId, _In_ const std::vector &counterIds); + static void setRifCounterList( + _In_ sai_object_id_t rifVid, + _In_ sai_object_id_t rifId, + _In_ std::string instanceId, + _In_ const std::vector &counterIds); static void setQueueAttrList( _In_ sai_object_id_t queueVid, _In_ sai_object_id_t queueId, @@ -58,6 +63,9 @@ class FlexCounter static void removePriorityGroup( _In_ sai_object_id_t priorityGroupVid, _In_ std::string instanceId); + static void removeRif( + _In_ sai_object_id_t rifVid, + _In_ std::string instanceId); static void addPortCounterPlugin( _In_ std::string sha, @@ -130,6 +138,16 @@ class FlexCounter std::vector portCounterIds; }; + struct RifCounterIds + { + RifCounterIds( + _In_ sai_object_id_t rif, + _In_ const std::vector &rifIds); + + sai_object_id_t rifId; + std::vector rifCounterIds; + }; + FlexCounter(std::string instanceId); static FlexCounter& getInstance(std::string instanceId); static void removeInstance(std::string instanceId); @@ -143,9 +161,11 @@ 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); + void saiUpdateSupportedRifCounters(sai_object_id_t rifId); 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 isRifCounterSupported(sai_router_interface_stat_t counter) const; bool isEmpty(); // Key is a Virtual ID @@ -154,6 +174,7 @@ class FlexCounter std::map> m_queueAttrIdsMap; std::map> m_priorityGroupCounterIdsMap; std::map> m_priorityGroupAttrIdsMap; + std::map> m_rifCounterIdsMap; // Plugins std::set m_queuePlugins; diff --git a/tests/aspell.en.pws b/tests/aspell.en.pws index 3cd93b5bfea8..4f7206f73161 100644 --- a/tests/aspell.en.pws +++ b/tests/aspell.en.pws @@ -150,6 +150,8 @@ removedVidToRid RID RIDs RIDTOVID +rif +RIF RO RPC runtime