Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[buffer orch] Bugfix: Don't query counter SAI_BUFFER_POOL_STAT_XOFF_ROOM_WATERMARK_BYTES on a pool where it is not supported #1857

Merged
73 changes: 62 additions & 11 deletions orchagent/bufferorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ extern sai_object_id_t gSwitchId;


static const vector<sai_buffer_pool_stat_t> bufferPoolWatermarkStatIds =
{
SAI_BUFFER_POOL_STAT_WATERMARK_BYTES
};

static const vector<sai_buffer_pool_stat_t> bufferSharedHeadroomPoolWatermarkStatIds =
{
SAI_BUFFER_POOL_STAT_XOFF_ROOM_WATERMARK_BYTES
};

static const vector<sai_buffer_pool_stat_t> bufferPoolAllWatermarkStatIds =
{
SAI_BUFFER_POOL_STAT_WATERMARK_BYTES,
SAI_BUFFER_POOL_STAT_XOFF_ROOM_WATERMARK_BYTES
Expand Down Expand Up @@ -218,29 +228,60 @@ void BufferOrch::generateBufferPoolWatermarkCounterIdList(void)
}

// Detokenize the SAI watermark stats to a string, separated by comma
string statList;
string statListPoolOnly;
for (const auto &it : bufferPoolWatermarkStatIds)
{
statList += (sai_serialize_buffer_pool_stat(it) + list_item_delimiter);
statListPoolOnly += (sai_serialize_buffer_pool_stat(it) + list_item_delimiter);
}
if (!statList.empty())
string statListPoolAndShp = statListPoolOnly;
for (const auto &it : bufferSharedHeadroomPoolWatermarkStatIds)
{
statList.pop_back();
statListPoolAndShp += (sai_serialize_buffer_pool_stat(it) + list_item_delimiter);
stephenxs marked this conversation as resolved.
Show resolved Hide resolved
}
if (!statListPoolOnly.empty())
{
statListPoolOnly.pop_back();
}
if (!statListPoolAndShp.empty())
{
statListPoolAndShp.pop_back();
}

// Some platforms do not support buffer pool watermark clear operation on a particular pool
// Invoke the SAI clear_stats API per pool to query the capability from the API call return status
// Some platforms do not support shared headroom pool watermark read operation on a particular pool
// Invoke the SAI get_buffer_pool_stats_ext API per pool to query the capability from the API call return status.
neethajohn marked this conversation as resolved.
Show resolved Hide resolved
// We use bit mask to mark the clear watermark capability of each buffer pool. We use an unsigned int to place hold
// these bits. This assumes the total number of buffer pools to be no greater than 32, which should satisfy all use cases.
unsigned int noWmClrCapability = 0;
unsigned int noShpWmRdCapability = 0;
unsigned int bitMask = 1;
uint32_t size = static_cast<uint32_t>(bufferSharedHeadroomPoolWatermarkStatIds.size());
vector<uint64_t> counterData(size);
for (const auto &it : *(m_buffer_type_maps[APP_BUFFER_POOL_TABLE_NAME]))
{
sai_status_t status = sai_buffer_api->clear_buffer_pool_stats(
sai_status_t status;
// Check whether shared headroom pool water mark is supported
status = sai_buffer_api->get_buffer_pool_stats(
it.second.m_saiObjectId,
static_cast<uint32_t>(bufferPoolWatermarkStatIds.size()),
reinterpret_cast<const sai_stat_id_t *>(bufferPoolWatermarkStatIds.data()));
if (status == SAI_STATUS_NOT_SUPPORTED || status == SAI_STATUS_NOT_IMPLEMENTED)
size,
reinterpret_cast<const sai_stat_id_t *>(bufferSharedHeadroomPoolWatermarkStatIds.data()),
counterData.data());
if (SAI_STATUS_IS_ATTR_NOT_SUPPORTED(status) || SAI_STATUS_IS_ATTR_NOT_IMPLEMENTED(status)
|| status == SAI_STATUS_NOT_SUPPORTED || status == SAI_STATUS_NOT_IMPLEMENTED)
{
SWSS_LOG_NOTICE("Read shared headroom pool watermark failed on %s, rv: %s", it.first.c_str(), sai_serialize_status(status).c_str());
noShpWmRdCapability |= bitMask;
}

const auto &watermarkStatIds = (noShpWmRdCapability & bitMask) ? bufferPoolAllWatermarkStatIds : bufferPoolWatermarkStatIds;
neethajohn marked this conversation as resolved.
Show resolved Hide resolved

status = sai_buffer_api->clear_buffer_pool_stats(
it.second.m_saiObjectId,
static_cast<uint32_t>(watermarkStatIds.size()),
reinterpret_cast<const sai_stat_id_t *>(watermarkStatIds.data()));
if (SAI_STATUS_IS_ATTR_NOT_SUPPORTED(status) || SAI_STATUS_IS_ATTR_NOT_IMPLEMENTED(status)
|| status == SAI_STATUS_NOT_SUPPORTED || status == SAI_STATUS_NOT_IMPLEMENTED)
{
SWSS_LOG_NOTICE("Clear watermark failed on %s, rv: %s", it.first.c_str(), sai_serialize_status(status).c_str());
noWmClrCapability |= bitMask;
Expand All @@ -259,11 +300,21 @@ void BufferOrch::generateBufferPoolWatermarkCounterIdList(void)

// Push buffer pool watermark COUNTER_ID_LIST to FLEX_COUNTER_TABLE on a per buffer pool basis
vector<FieldValueTuple> fvTuples;
fvTuples.emplace_back(BUFFER_POOL_COUNTER_ID_LIST, statList);

bitMask = 1;
for (const auto &it : *(m_buffer_type_maps[APP_BUFFER_POOL_TABLE_NAME]))
{
string key = BUFFER_POOL_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP ":" + sai_serialize_object_id(it.second.m_saiObjectId);
fvTuples.clear();

if (noShpWmRdCapability & bitMask)
{
fvTuples.emplace_back(BUFFER_POOL_COUNTER_ID_LIST, statListPoolOnly);
}
else
{
fvTuples.emplace_back(BUFFER_POOL_COUNTER_ID_LIST, statListPoolAndShp);
}

if (noWmClrCapability)
{
Expand All @@ -275,13 +326,13 @@ void BufferOrch::generateBufferPoolWatermarkCounterIdList(void)
fvTuples.emplace_back(STATS_MODE_FIELD, stats_mode);

m_flexCounterTable->set(key, fvTuples);
fvTuples.pop_back();
bitMask <<= 1;
}
else
{
m_flexCounterTable->set(key, fvTuples);
}
neethajohn marked this conversation as resolved.
Show resolved Hide resolved

bitMask <<= 1;
}

m_isBufferPoolWatermarkCounterIdListGenerated = true;
Expand Down