Skip to content

Commit

Permalink
sonic-sairedis : Wred stats feature changes on Sai-redis and Syncd
Browse files Browse the repository at this point in the history
* Stats capability query API support is added
* Marvell VS support for query stats capability added

Signed-off-by: rpmarvell <[email protected]>
  • Loading branch information
rpmarvell committed Dec 11, 2024
1 parent 98bb52e commit f5fd7ef
Show file tree
Hide file tree
Showing 36 changed files with 1,498 additions and 68 deletions.
113 changes: 103 additions & 10 deletions lib/ClientSai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -981,16 +981,6 @@ sai_status_t ClientSai::getStats(
return waitForGetStatsResponse(number_of_counters, counters);
}

sai_status_t ClientSai::queryStatsCapability(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t objectType,
_Inout_ sai_stat_capability_list_t *stats_capability)
{
SWSS_LOG_ENTER();

return SAI_STATUS_NOT_IMPLEMENTED;
}

sai_status_t ClientSai::waitForGetStatsResponse(
_In_ uint32_t number_of_counters,
_Out_ uint64_t *counters)
Expand Down Expand Up @@ -1019,6 +1009,109 @@ sai_status_t ClientSai::waitForGetStatsResponse(
return status;
}

sai_status_t ClientSai::queryStatsCapability(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t objectType,
_Inout_ sai_stat_capability_list_t *stats_capability)
{
MUTEX();
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();

auto switchIdStr = sai_serialize_object_id(switchId);
auto objectTypeStr = sai_serialize_object_type(objectType);

if (stats_capability == NULL)
{
SWSS_LOG_ERROR("Failed to find stats-capability: switch %s object type %s", switchIdStr.c_str(), objectTypeStr.c_str());
return SAI_STATUS_INVALID_PARAMETER;
}

if (stats_capability && stats_capability->list && (stats_capability->count))
{
// clear input list, since we use serialize to transfer values
for (uint32_t idx = 0; idx < stats_capability->count; idx++)
{
stats_capability->list[idx].stat_enum = 0;
stats_capability->list[idx].stat_modes = 0;
}
}

const std::string listSize = std::to_string(stats_capability->count);

const std::vector<swss::FieldValueTuple> entry =
{
swss::FieldValueTuple("OBJECT_TYPE", objectTypeStr),
swss::FieldValueTuple("LIST_SIZE", listSize)
};

SWSS_LOG_DEBUG(
"Query arguments: switch %s, object type: %s, count: %s",
switchIdStr.c_str(),
objectTypeStr.c_str(),
listSize.c_str()
);

// This query will not put any data into the ASIC view, just into the
// message queue

m_communicationChannel->set(switchIdStr, entry, REDIS_ASIC_STATE_COMMAND_STATS_CAPABILITY_QUERY);

return waitForQueryStatsCapabilityResponse(stats_capability);
}

sai_status_t ClientSai::waitForQueryStatsCapabilityResponse(
_Inout_ sai_stat_capability_list_t* stats_capability)
{
SWSS_LOG_ENTER();

swss::KeyOpFieldsValuesTuple kco;

auto status = m_communicationChannel->wait(REDIS_ASIC_STATE_COMMAND_STATS_CAPABILITY_RESPONSE, kco);

if (status == SAI_STATUS_SUCCESS)
{
const std::vector<swss::FieldValueTuple> &values = kfvFieldsValues(kco);

if (values.size() != 3)
{
SWSS_LOG_ERROR("Invalid response from syncd: expected 3 value, received %zu", values.size());

return SAI_STATUS_FAILURE;
}

const std::string &stat_enum_str = fvValue(values[0]);
const std::string &stat_modes_str = fvValue(values[1]);
const uint32_t num_capabilities = std::stoi(fvValue(values[2]));

SWSS_LOG_DEBUG("Received payload: stat_enums = '%s', stat_modes = '%s', count = %d",
stat_enum_str.c_str(), stat_modes_str.c_str(), num_capabilities);

stats_capability->count = num_capabilities;

sai_deserialize_stats_capability_list(stats_capability, stat_enum_str, stat_modes_str);
}
else if (status == SAI_STATUS_BUFFER_OVERFLOW)
{
const std::vector<swss::FieldValueTuple> &values = kfvFieldsValues(kco);

if (values.size() != 1)
{
SWSS_LOG_ERROR("Invalid response from syncd: expected 1 value, received %zu", values.size());

return SAI_STATUS_FAILURE;
}

const uint32_t num_capabilities = std::stoi(fvValue(values[0]));

SWSS_LOG_DEBUG("Received payload: count = %u", num_capabilities);

stats_capability->count = num_capabilities;
}

return status;
}

sai_status_t ClientSai::getStatsExt(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
Expand Down
3 changes: 3 additions & 0 deletions lib/ClientSai.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ namespace sairedis
sai_status_t waitForObjectTypeGetAvailabilityResponse(
_In_ uint64_t *count);

sai_status_t waitForQueryStatsCapabilityResponse(
_Inout_ sai_stat_capability_list_t* stats_capability);

private:

void handleNotification(
Expand Down
5 changes: 4 additions & 1 deletion lib/ClientServerSai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,10 @@ sai_status_t ClientServerSai::queryStatsCapability(
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();

return SAI_STATUS_NOT_IMPLEMENTED;
return m_sai->queryStatsCapability(
switchId,
objectType,
stats_capability);
}

sai_status_t ClientServerSai::getStatsExt(
Expand Down
79 changes: 79 additions & 0 deletions lib/Recorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,24 @@ void Recorder::recordObjectTypeGetAvailabilityResponse(
recordLine("Q|object_type_get_availability|" + sai_serialize_status(status) + "|" + Globals::joinFieldValues(arguments));
}

void Recorder::recordQueryStatsCapability(
_In_ const std::string& key,
_In_ const std::vector<swss::FieldValueTuple>& arguments)
{
SWSS_LOG_ENTER();

recordLine("q|stats_capability|" + key + "|" + Globals::joinFieldValues(arguments));
}

void Recorder::recordQueryStatsCapabilityResponse(
_In_ sai_status_t status,
_In_ const std::string& arguments)
{
SWSS_LOG_ENTER();

recordLine("Q|stats_capability|" + sai_serialize_status(status) + "|" + arguments);
}

void Recorder::recordNotifySyncd(
_In_ const std::string& key)
{
Expand Down Expand Up @@ -1104,6 +1122,67 @@ void Recorder::recordQueryAttributeEnumValuesCapabilityResponse(
recordQueryAttributeEnumValuesCapabilityResponse(status, values);
}

void Recorder::recordQueryStatsCapability(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t object_type,
_Inout_ sai_stat_capability_list_t* stats_capability)
{
SWSS_LOG_ENTER();

auto key = sai_serialize_object_type(SAI_OBJECT_TYPE_SWITCH) + ":" + sai_serialize_object_id(switchId);

auto object_type_str = sai_serialize_object_type(object_type);
const std::string list_size = std::to_string(stats_capability->count);
const std::vector<swss::FieldValueTuple> values =
{
swss::FieldValueTuple("OBJECT_TYPE", object_type_str),
swss::FieldValueTuple("LIST_SIZE", list_size)
};

SWSS_LOG_DEBUG("Query arguments: switch %s, object_type: %s, count: %s",
key.c_str(),
object_type_str.c_str(),
list_size.c_str());

recordQueryStatsCapability(key, values);
}

void Recorder::recordQueryStatsCapabilityResponse(
_In_ sai_status_t status,
_In_ sai_object_type_t objectType,
_In_ const sai_stat_capability_list_t *stats_capability)
{
SWSS_LOG_ENTER();

std::string str_stats_list;

auto meta = sai_metadata_get_object_type_info(objectType);

if (meta == NULL)
{
SWSS_LOG_ERROR("Failed to find object metadata: object type %s",
sai_serialize_object_type(objectType).c_str());

return;
}

if (meta->statenum == NULL)
{
SWSS_LOG_ERROR("%s does not support stats", meta->objecttypename);

return;
}

bool countOnly = (status == SAI_STATUS_BUFFER_OVERFLOW);

if (status == SAI_STATUS_SUCCESS || status == SAI_STATUS_BUFFER_OVERFLOW)
{
str_stats_list = sai_serialize_stats_capability_list(*stats_capability, meta->statenum, countOnly);
}

recordQueryStatsCapabilityResponse(status, str_stats_list);
}

void Recorder::recordNotifySyncd(
_In_ sai_object_id_t switchId,
_In_ sai_redis_notify_syncd_t redisNotifySyncd)
Expand Down
18 changes: 18 additions & 0 deletions lib/Recorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,16 @@ namespace sairedis
_In_ sai_attr_id_t attrId,
_In_ const sai_s32_list_t* enumValuesCapability);

void recordQueryStatsCapability(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_Inout_ sai_stat_capability_list_t* stats_capability);

void recordQueryStatsCapabilityResponse(
_In_ sai_status_t status,
_In_ sai_object_type_t objectType,
_In_ const sai_stat_capability_list_t *stats_capability);

// TODO move to private
void recordQueryAttributeCapability(
_In_ const std::string& key,
Expand All @@ -323,6 +333,14 @@ namespace sairedis
_In_ sai_status_t status,
_In_ const std::vector<swss::FieldValueTuple>& arguments);

void recordQueryStatsCapability(
_In_ const std::string& key,
_In_ const std::vector<swss::FieldValueTuple>& arguments);

void recordQueryStatsCapabilityResponse(
_In_ sai_status_t status,
_In_ const std::string& arguments);

public: // SAI notifications

void recordNotification(
Expand Down
Loading

0 comments on commit f5fd7ef

Please sign in to comment.