@@ -22,6 +22,16 @@ extern sai_object_id_t gSwitchId;
2222
2323
2424static const vector<sai_buffer_pool_stat_t > bufferPoolWatermarkStatIds =
25+ {
26+ SAI_BUFFER_POOL_STAT_WATERMARK_BYTES
27+ };
28+
29+ static const vector<sai_buffer_pool_stat_t > bufferSharedHeadroomPoolWatermarkStatIds =
30+ {
31+ SAI_BUFFER_POOL_STAT_XOFF_ROOM_WATERMARK_BYTES
32+ };
33+
34+ static const vector<sai_buffer_pool_stat_t > bufferPoolAllWatermarkStatIds =
2535{
2636 SAI_BUFFER_POOL_STAT_WATERMARK_BYTES,
2737 SAI_BUFFER_POOL_STAT_XOFF_ROOM_WATERMARK_BYTES
@@ -218,29 +228,60 @@ void BufferOrch::generateBufferPoolWatermarkCounterIdList(void)
218228 }
219229
220230 // Detokenize the SAI watermark stats to a string, separated by comma
221- string statList ;
231+ string statListBufferPoolOnly ;
222232 for (const auto &it : bufferPoolWatermarkStatIds)
223233 {
224- statList += (sai_serialize_buffer_pool_stat (it) + list_item_delimiter);
234+ statListBufferPoolOnly += (sai_serialize_buffer_pool_stat (it) + list_item_delimiter);
225235 }
226- if (!statList.empty ())
236+ string statListBufferPoolAndSharedHeadroomPool = statListBufferPoolOnly;
237+ for (const auto &it : bufferSharedHeadroomPoolWatermarkStatIds)
227238 {
228- statList.pop_back ();
239+ statListBufferPoolAndSharedHeadroomPool += (sai_serialize_buffer_pool_stat (it) + list_item_delimiter);
240+ }
241+ if (!statListBufferPoolOnly.empty ())
242+ {
243+ statListBufferPoolOnly.pop_back ();
244+ }
245+ if (!statListBufferPoolAndSharedHeadroomPool.empty ())
246+ {
247+ statListBufferPoolAndSharedHeadroomPool.pop_back ();
229248 }
230249
231250 // Some platforms do not support buffer pool watermark clear operation on a particular pool
232251 // Invoke the SAI clear_stats API per pool to query the capability from the API call return status
252+ // Some platforms do not support shared headroom pool watermark read operation on a particular pool
253+ // Invoke the SAI get_buffer_pool_stats API per pool to query the capability from the API call return status.
233254 // We use bit mask to mark the clear watermark capability of each buffer pool. We use an unsigned int to place hold
234255 // these bits. This assumes the total number of buffer pools to be no greater than 32, which should satisfy all use cases.
235256 unsigned int noWmClrCapability = 0 ;
257+ unsigned int noSharedHeadroomPoolWmRdCapability = 0 ;
236258 unsigned int bitMask = 1 ;
259+ uint32_t size = static_cast <uint32_t >(bufferSharedHeadroomPoolWatermarkStatIds.size ());
260+ vector<uint64_t > counterData (size);
237261 for (const auto &it : *(m_buffer_type_maps[APP_BUFFER_POOL_TABLE_NAME]))
238262 {
239- sai_status_t status = sai_buffer_api->clear_buffer_pool_stats (
263+ sai_status_t status;
264+ // Check whether shared headroom pool water mark is supported
265+ status = sai_buffer_api->get_buffer_pool_stats (
266+ it.second .m_saiObjectId ,
267+ size,
268+ reinterpret_cast <const sai_stat_id_t *>(bufferSharedHeadroomPoolWatermarkStatIds.data ()),
269+ counterData.data ());
270+ if (SAI_STATUS_IS_ATTR_NOT_SUPPORTED (status) || SAI_STATUS_IS_ATTR_NOT_IMPLEMENTED (status)
271+ || status == SAI_STATUS_NOT_SUPPORTED || status == SAI_STATUS_NOT_IMPLEMENTED)
272+ {
273+ SWSS_LOG_NOTICE (" Read shared headroom pool watermark failed on %s, rv: %s" , it.first .c_str (), sai_serialize_status (status).c_str ());
274+ noSharedHeadroomPoolWmRdCapability |= bitMask;
275+ }
276+
277+ const auto &watermarkStatIds = (noSharedHeadroomPoolWmRdCapability & bitMask) ? bufferPoolWatermarkStatIds : bufferPoolAllWatermarkStatIds;
278+
279+ status = sai_buffer_api->clear_buffer_pool_stats (
240280 it.second .m_saiObjectId ,
241- static_cast <uint32_t >(bufferPoolWatermarkStatIds.size ()),
242- reinterpret_cast <const sai_stat_id_t *>(bufferPoolWatermarkStatIds.data ()));
243- if (status == SAI_STATUS_NOT_SUPPORTED || status == SAI_STATUS_NOT_IMPLEMENTED)
281+ static_cast <uint32_t >(watermarkStatIds.size ()),
282+ reinterpret_cast <const sai_stat_id_t *>(watermarkStatIds.data ()));
283+ if (SAI_STATUS_IS_ATTR_NOT_SUPPORTED (status) || SAI_STATUS_IS_ATTR_NOT_IMPLEMENTED (status)
284+ || status == SAI_STATUS_NOT_SUPPORTED || status == SAI_STATUS_NOT_IMPLEMENTED)
244285 {
245286 SWSS_LOG_NOTICE (" Clear watermark failed on %s, rv: %s" , it.first .c_str (), sai_serialize_status (status).c_str ());
246287 noWmClrCapability |= bitMask;
@@ -259,11 +300,21 @@ void BufferOrch::generateBufferPoolWatermarkCounterIdList(void)
259300
260301 // Push buffer pool watermark COUNTER_ID_LIST to FLEX_COUNTER_TABLE on a per buffer pool basis
261302 vector<FieldValueTuple> fvTuples;
262- fvTuples. emplace_back (BUFFER_POOL_COUNTER_ID_LIST, statList);
303+
263304 bitMask = 1 ;
264305 for (const auto &it : *(m_buffer_type_maps[APP_BUFFER_POOL_TABLE_NAME]))
265306 {
266307 string key = BUFFER_POOL_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP " :" + sai_serialize_object_id (it.second .m_saiObjectId );
308+ fvTuples.clear ();
309+
310+ if (noSharedHeadroomPoolWmRdCapability & bitMask)
311+ {
312+ fvTuples.emplace_back (BUFFER_POOL_COUNTER_ID_LIST, statListBufferPoolOnly);
313+ }
314+ else
315+ {
316+ fvTuples.emplace_back (BUFFER_POOL_COUNTER_ID_LIST, statListBufferPoolAndSharedHeadroomPool);
317+ }
267318
268319 if (noWmClrCapability)
269320 {
@@ -273,15 +324,11 @@ void BufferOrch::generateBufferPoolWatermarkCounterIdList(void)
273324 stats_mode = STATS_MODE_READ;
274325 }
275326 fvTuples.emplace_back (STATS_MODE_FIELD, stats_mode);
276-
277- m_flexCounterTable->set (key, fvTuples);
278- fvTuples.pop_back ();
279- bitMask <<= 1 ;
280- }
281- else
282- {
283- m_flexCounterTable->set (key, fvTuples);
284327 }
328+
329+ m_flexCounterTable->set (key, fvTuples);
330+
331+ bitMask <<= 1 ;
285332 }
286333
287334 m_isBufferPoolWatermarkCounterIdListGenerated = true ;
0 commit comments