From 49f36ce51d5594df131891c522b8c10533e974ca Mon Sep 17 00:00:00 2001 From: Wenda Ni Date: Tue, 16 Jul 2019 07:32:43 -0700 Subject: [PATCH] Per buffer pool watermark polling mode (#485) Add STATS_MODE field parsing when oid in FLEX_COUTER_TABLE key is SAI_OBJECT_TYPE_BUFFER_POOL. Use READ_AND_CLEAR mode when either global stats polling mode or the particular buffer pool stats polling mode is READ_AND_CLEAR. In the opposite, use READ mode (no stats clear) only when both global and per buffer pool stats polling mode are READ. --- syncd/syncd.cpp | 31 +++++++++++++------- syncd/syncd_flex_counter.cpp | 56 ++++++++++++++++++++++++------------ syncd/syncd_flex_counter.h | 13 ++++++--- 3 files changed, 67 insertions(+), 33 deletions(-) diff --git a/syncd/syncd.cpp b/syncd/syncd.cpp index f47f0d45f2..2b9ae2a6a1 100644 --- a/syncd/syncd.cpp +++ b/syncd/syncd.cpp @@ -3022,6 +3022,8 @@ void processFlexCounterEvent( } const auto values = kfvFieldsValues(kco); + std::vector counterIds; + std::string statsMode; for (const auto& valuePair : values) { const auto field = fvField(valuePair); @@ -3029,7 +3031,7 @@ void processFlexCounterEvent( if (op == SET_COMMAND) { - auto idStrings = swss::tokenize(value, ','); + auto idStrings = swss::tokenize(value, ','); if (objectType == SAI_OBJECT_TYPE_PORT && field == PORT_COUNTER_ID_LIST) { @@ -3105,15 +3107,11 @@ void processFlexCounterEvent( } else if (objectType == SAI_OBJECT_TYPE_BUFFER_POOL && field == BUFFER_POOL_COUNTER_ID_LIST) { - std::vector bufferPoolCounterIds; - for (const auto &str : idStrings) - { - sai_buffer_pool_stat_t stat; - sai_deserialize_buffer_pool_stat(str.c_str(), &stat); - bufferPoolCounterIds.push_back(stat); - } - - FlexCounter::setBufferPoolCounterList(vid, rid, groupName, bufferPoolCounterIds); + counterIds = idStrings; + } + else if (objectType == SAI_OBJECT_TYPE_BUFFER_POOL && field == STATS_MODE_FIELD) + { + statsMode = value; } else { @@ -3121,6 +3119,19 @@ void processFlexCounterEvent( } } } + + if (objectType == SAI_OBJECT_TYPE_BUFFER_POOL && counterIds.size()) + { + std::vector bufferPoolCounterIds; + for (const auto &str : counterIds) + { + sai_buffer_pool_stat_t stat; + sai_deserialize_buffer_pool_stat(str.c_str(), &stat); + bufferPoolCounterIds.push_back(stat); + } + + FlexCounter::setBufferPoolCounterList(vid, rid, groupName, bufferPoolCounterIds, statsMode); + } } void printUsage() diff --git a/syncd/syncd_flex_counter.cpp b/syncd/syncd_flex_counter.cpp index c6e154aadb..77548c9343 100644 --- a/syncd/syncd_flex_counter.cpp +++ b/syncd/syncd_flex_counter.cpp @@ -61,8 +61,9 @@ FlexCounter::RifCounterIds::RifCounterIds( FlexCounter::BufferPoolCounterIds::BufferPoolCounterIds( _In_ sai_object_id_t bufferPool, - _In_ const std::vector &bufferPoolIds): - bufferPoolId(bufferPool), bufferPoolCounterIds(bufferPoolIds) + _In_ const std::vector &bufferPoolIds, + _In_ sai_stats_mode_t statsMode): + bufferPoolId(bufferPool), bufferPoolStatsMode(statsMode), bufferPoolCounterIds(bufferPoolIds) { SWSS_LOG_ENTER(); } @@ -463,14 +464,29 @@ void FlexCounter::setRifCounterList( void FlexCounter::setBufferPoolCounterList( _In_ sai_object_id_t bufferPoolVid, _In_ sai_object_id_t bufferPoolId, - _In_ std::string instanceId, - _In_ const std::vector &counterIds) + _In_ const std::string &instanceId, + _In_ const std::vector &counterIds, + _In_ const std::string &statsMode) { SWSS_LOG_ENTER(); FlexCounter &fc = getInstance(instanceId); - fc.saiUpdateSupportedBufferPoolCounters(bufferPoolId, counterIds); + sai_stats_mode_t bufferPoolStatsMode = SAI_STATS_MODE_READ_AND_CLEAR; + if (statsMode == STATS_MODE_READ_AND_CLEAR) + { + bufferPoolStatsMode = SAI_STATS_MODE_READ_AND_CLEAR; + } + else if (statsMode == STATS_MODE_READ) + { + bufferPoolStatsMode = SAI_STATS_MODE_READ; + } + else + { + SWSS_LOG_WARN("Stats mode %s not supported for flex counter. Using STATS_MODE_READ_AND_CLEAR", statsMode.c_str()); + } + + fc.saiUpdateSupportedBufferPoolCounters(bufferPoolId, counterIds, bufferPoolStatsMode); // Filter unsupported counters std::vector supportedIds; @@ -504,7 +520,7 @@ void FlexCounter::setBufferPoolCounterList( return; } - auto bufferPoolCounterIds = std::make_shared(bufferPoolId, supportedIds); + auto bufferPoolCounterIds = std::make_shared(bufferPoolId, supportedIds, bufferPoolStatsMode); fc.m_bufferPoolCounterIdsMap.emplace(bufferPoolVid, bufferPoolCounterIds); // Start flex counter thread in case it was not running due to empty counter IDs map @@ -1194,6 +1210,7 @@ void FlexCounter::collectCounters( const auto &bufferPoolVid = it.first; const auto &bufferPoolId = it.second->bufferPoolId; const auto &bufferPoolCounterIds = it.second->bufferPoolCounterIds; + const auto &bufferPoolStatsMode = it.second->bufferPoolStatsMode; std::vector bufferPoolStats(bufferPoolCounterIds.size()); @@ -1215,22 +1232,22 @@ void FlexCounter::collectCounters( sai_serialize_status(status).c_str()); continue; } - if (m_statsMode == SAI_STATS_MODE_READ_AND_CLEAR) + if (m_statsMode == SAI_STATS_MODE_READ_AND_CLEAR || bufferPoolStatsMode == SAI_STATS_MODE_READ_AND_CLEAR) { status = sai_metadata_sai_buffer_api->clear_buffer_pool_stats( bufferPoolId, static_cast(bufferPoolCounterIds.size()), reinterpret_cast(bufferPoolCounterIds.data())); - } - if (status != SAI_STATUS_SUCCESS) - { - // Because of stat pre-qualification in setting the buffer pool counter list, - // it is less likely that we will get a failure return here in clearing the stats - SWSS_LOG_ERROR("%s: failed to clear stats of buffer pool %s, rv: %s", - m_instanceId.c_str(), - sai_serialize_object_id(bufferPoolId).c_str(), - sai_serialize_status(status).c_str()); - continue; + if (status != SAI_STATUS_SUCCESS) + { + // Because of stat pre-qualification in setting the buffer pool counter list, + // it is less likely that we will get a failure return here in clearing the stats + SWSS_LOG_ERROR("%s: failed to clear stats of buffer pool %s, rv: %s", + m_instanceId.c_str(), + sai_serialize_object_id(bufferPoolId).c_str(), + sai_serialize_status(status).c_str()); + continue; + } } // Write counter values to DB table @@ -1529,7 +1546,8 @@ void FlexCounter::saiUpdateSupportedRifCounters(sai_object_id_t rifId) void FlexCounter::saiUpdateSupportedBufferPoolCounters( _In_ sai_object_id_t bufferPoolId, - _In_ const std::vector &counterIds) + _In_ const std::vector &counterIds, + _In_ sai_stats_mode_t statsMode) { SWSS_LOG_ENTER(); @@ -1550,7 +1568,7 @@ void FlexCounter::saiUpdateSupportedBufferPoolCounters( continue; } - if (m_statsMode == SAI_STATS_MODE_READ_AND_CLEAR) + if (m_statsMode == SAI_STATS_MODE_READ_AND_CLEAR || statsMode == SAI_STATS_MODE_READ_AND_CLEAR) { status = sai_metadata_sai_buffer_api->clear_buffer_pool_stats(bufferPoolId, 1, (const sai_stat_id_t *)&counterId); if (status != SAI_STATUS_SUCCESS) diff --git a/syncd/syncd_flex_counter.h b/syncd/syncd_flex_counter.h index ea98a70bb6..b11176acb0 100644 --- a/syncd/syncd_flex_counter.h +++ b/syncd/syncd_flex_counter.h @@ -40,8 +40,9 @@ class FlexCounter static void setBufferPoolCounterList( _In_ sai_object_id_t bufferPoolVid, _In_ sai_object_id_t bufferPoolId, - _In_ std::string instanceId, - _In_ const std::vector &counterIds); + _In_ const std::string &instanceId, + _In_ const std::vector &counterIds, + _In_ const std::string &statsMode = ""); static void setQueueAttrList( _In_ sai_object_id_t queueVid, _In_ sai_object_id_t queueId, @@ -143,9 +144,11 @@ class FlexCounter { BufferPoolCounterIds( _In_ sai_object_id_t bufferPool, - _In_ const std::vector &bufferPoolIds); + _In_ const std::vector &bufferPoolIds, + _In_ sai_stats_mode_t statsMode); sai_object_id_t bufferPoolId; + sai_stats_mode_t bufferPoolStatsMode; std::vector bufferPoolCounterIds; }; @@ -183,7 +186,9 @@ class FlexCounter 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); - void saiUpdateSupportedBufferPoolCounters(sai_object_id_t bufferPoolId, const std::vector &counterIds); + void saiUpdateSupportedBufferPoolCounters(sai_object_id_t bufferPoolId, + const std::vector &counterIds, + sai_stats_mode_t statsMode = SAI_STATS_MODE_READ_AND_CLEAR); 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;