Skip to content

Commit be0c83d

Browse files
authored
sonic-sairedis : Wred stats feature changes on Sai-redis and Syncd (sonic-net#1234)
Stats capability query API support is added Details : Changes are done to support the stats capability query from Swss to SAI. This was implemented as part of WRED and ECN statistics Statistics capability query is implemented in sairedis/syncd HLD : https://github.com/sonic-net/SONiC/blob/master/doc/qos/ECN_and_WRED_statistics_HLD.md
1 parent 3c1ede9 commit be0c83d

37 files changed

+1494
-71
lines changed

lib/ClientSai.cpp

+103-10
Original file line numberDiff line numberDiff line change
@@ -981,16 +981,6 @@ sai_status_t ClientSai::getStats(
981981
return waitForGetStatsResponse(number_of_counters, counters);
982982
}
983983

984-
sai_status_t ClientSai::queryStatsCapability(
985-
_In_ sai_object_id_t switchId,
986-
_In_ sai_object_type_t objectType,
987-
_Inout_ sai_stat_capability_list_t *stats_capability)
988-
{
989-
SWSS_LOG_ENTER();
990-
991-
return SAI_STATUS_NOT_IMPLEMENTED;
992-
}
993-
994984
sai_status_t ClientSai::waitForGetStatsResponse(
995985
_In_ uint32_t number_of_counters,
996986
_Out_ uint64_t *counters)
@@ -1019,6 +1009,109 @@ sai_status_t ClientSai::waitForGetStatsResponse(
10191009
return status;
10201010
}
10211011

1012+
sai_status_t ClientSai::queryStatsCapability(
1013+
_In_ sai_object_id_t switchId,
1014+
_In_ sai_object_type_t objectType,
1015+
_Inout_ sai_stat_capability_list_t *stats_capability)
1016+
{
1017+
MUTEX();
1018+
SWSS_LOG_ENTER();
1019+
REDIS_CHECK_API_INITIALIZED();
1020+
1021+
auto switchIdStr = sai_serialize_object_id(switchId);
1022+
auto objectTypeStr = sai_serialize_object_type(objectType);
1023+
1024+
if (stats_capability == NULL)
1025+
{
1026+
SWSS_LOG_ERROR("Failed to find stats-capability: switch %s object type %s", switchIdStr.c_str(), objectTypeStr.c_str());
1027+
return SAI_STATUS_INVALID_PARAMETER;
1028+
}
1029+
1030+
if (stats_capability && stats_capability->list && (stats_capability->count))
1031+
{
1032+
// clear input list, since we use serialize to transfer values
1033+
for (uint32_t idx = 0; idx < stats_capability->count; idx++)
1034+
{
1035+
stats_capability->list[idx].stat_enum = 0;
1036+
stats_capability->list[idx].stat_modes = 0;
1037+
}
1038+
}
1039+
1040+
const std::string listSize = std::to_string(stats_capability->count);
1041+
1042+
const std::vector<swss::FieldValueTuple> entry =
1043+
{
1044+
swss::FieldValueTuple("OBJECT_TYPE", objectTypeStr),
1045+
swss::FieldValueTuple("LIST_SIZE", listSize)
1046+
};
1047+
1048+
SWSS_LOG_DEBUG(
1049+
"Query arguments: switch %s, object type: %s, count: %s",
1050+
switchIdStr.c_str(),
1051+
objectTypeStr.c_str(),
1052+
listSize.c_str()
1053+
);
1054+
1055+
// This query will not put any data into the ASIC view, just into the
1056+
// message queue
1057+
1058+
m_communicationChannel->set(switchIdStr, entry, REDIS_ASIC_STATE_COMMAND_STATS_CAPABILITY_QUERY);
1059+
1060+
return waitForQueryStatsCapabilityResponse(stats_capability);
1061+
}
1062+
1063+
sai_status_t ClientSai::waitForQueryStatsCapabilityResponse(
1064+
_Inout_ sai_stat_capability_list_t* stats_capability)
1065+
{
1066+
SWSS_LOG_ENTER();
1067+
1068+
swss::KeyOpFieldsValuesTuple kco;
1069+
1070+
auto status = m_communicationChannel->wait(REDIS_ASIC_STATE_COMMAND_STATS_CAPABILITY_RESPONSE, kco);
1071+
1072+
if (status == SAI_STATUS_SUCCESS)
1073+
{
1074+
const std::vector<swss::FieldValueTuple> &values = kfvFieldsValues(kco);
1075+
1076+
if (values.size() != 3)
1077+
{
1078+
SWSS_LOG_ERROR("Invalid response from syncd: expected 3 value, received %zu", values.size());
1079+
1080+
return SAI_STATUS_FAILURE;
1081+
}
1082+
1083+
const std::string &stat_enum_str = fvValue(values[0]);
1084+
const std::string &stat_modes_str = fvValue(values[1]);
1085+
const uint32_t num_capabilities = std::stoi(fvValue(values[2]));
1086+
1087+
SWSS_LOG_DEBUG("Received payload: stat_enums = '%s', stat_modes = '%s', count = %d",
1088+
stat_enum_str.c_str(), stat_modes_str.c_str(), num_capabilities);
1089+
1090+
stats_capability->count = num_capabilities;
1091+
1092+
sai_deserialize_stats_capability_list(stats_capability, stat_enum_str, stat_modes_str);
1093+
}
1094+
else if (status == SAI_STATUS_BUFFER_OVERFLOW)
1095+
{
1096+
const std::vector<swss::FieldValueTuple> &values = kfvFieldsValues(kco);
1097+
1098+
if (values.size() != 1)
1099+
{
1100+
SWSS_LOG_ERROR("Invalid response from syncd: expected 1 value, received %zu", values.size());
1101+
1102+
return SAI_STATUS_FAILURE;
1103+
}
1104+
1105+
const uint32_t num_capabilities = std::stoi(fvValue(values[0]));
1106+
1107+
SWSS_LOG_DEBUG("Received payload: count = %u", num_capabilities);
1108+
1109+
stats_capability->count = num_capabilities;
1110+
}
1111+
1112+
return status;
1113+
}
1114+
10221115
sai_status_t ClientSai::getStatsExt(
10231116
_In_ sai_object_type_t object_type,
10241117
_In_ sai_object_id_t object_id,

lib/ClientSai.h

+3
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,9 @@ namespace sairedis
297297
sai_status_t waitForObjectTypeGetAvailabilityResponse(
298298
_In_ uint64_t *count);
299299

300+
sai_status_t waitForQueryStatsCapabilityResponse(
301+
_Inout_ sai_stat_capability_list_t* stats_capability);
302+
300303
private:
301304

302305
void handleNotification(

lib/ClientServerSai.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,10 @@ sai_status_t ClientServerSai::queryStatsCapability(
256256
SWSS_LOG_ENTER();
257257
REDIS_CHECK_API_INITIALIZED();
258258

259-
return SAI_STATUS_NOT_IMPLEMENTED;
259+
return m_sai->queryStatsCapability(
260+
switchId,
261+
objectType,
262+
stats_capability);
260263
}
261264

262265
sai_status_t ClientServerSai::getStatsExt(

lib/Recorder.cpp

+79
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,24 @@ void Recorder::recordObjectTypeGetAvailabilityResponse(
370370
recordLine("Q|object_type_get_availability|" + sai_serialize_status(status) + "|" + Globals::joinFieldValues(arguments));
371371
}
372372

373+
void Recorder::recordQueryStatsCapability(
374+
_In_ const std::string& key,
375+
_In_ const std::vector<swss::FieldValueTuple>& arguments)
376+
{
377+
SWSS_LOG_ENTER();
378+
379+
recordLine("q|stats_capability|" + key + "|" + Globals::joinFieldValues(arguments));
380+
}
381+
382+
void Recorder::recordQueryStatsCapabilityResponse(
383+
_In_ sai_status_t status,
384+
_In_ const std::string& arguments)
385+
{
386+
SWSS_LOG_ENTER();
387+
388+
recordLine("Q|stats_capability|" + sai_serialize_status(status) + "|" + arguments);
389+
}
390+
373391
void Recorder::recordNotifySyncd(
374392
_In_ const std::string& key)
375393
{
@@ -1104,6 +1122,67 @@ void Recorder::recordQueryAttributeEnumValuesCapabilityResponse(
11041122
recordQueryAttributeEnumValuesCapabilityResponse(status, values);
11051123
}
11061124

1125+
void Recorder::recordQueryStatsCapability(
1126+
_In_ sai_object_id_t switchId,
1127+
_In_ sai_object_type_t object_type,
1128+
_Inout_ sai_stat_capability_list_t* stats_capability)
1129+
{
1130+
SWSS_LOG_ENTER();
1131+
1132+
auto key = sai_serialize_object_type(SAI_OBJECT_TYPE_SWITCH) + ":" + sai_serialize_object_id(switchId);
1133+
1134+
auto object_type_str = sai_serialize_object_type(object_type);
1135+
const std::string list_size = std::to_string(stats_capability->count);
1136+
const std::vector<swss::FieldValueTuple> values =
1137+
{
1138+
swss::FieldValueTuple("OBJECT_TYPE", object_type_str),
1139+
swss::FieldValueTuple("LIST_SIZE", list_size)
1140+
};
1141+
1142+
SWSS_LOG_DEBUG("Query arguments: switch %s, object_type: %s, count: %s",
1143+
key.c_str(),
1144+
object_type_str.c_str(),
1145+
list_size.c_str());
1146+
1147+
recordQueryStatsCapability(key, values);
1148+
}
1149+
1150+
void Recorder::recordQueryStatsCapabilityResponse(
1151+
_In_ sai_status_t status,
1152+
_In_ sai_object_type_t objectType,
1153+
_In_ const sai_stat_capability_list_t *stats_capability)
1154+
{
1155+
SWSS_LOG_ENTER();
1156+
1157+
std::string str_stats_list;
1158+
1159+
auto meta = sai_metadata_get_object_type_info(objectType);
1160+
1161+
if (meta == NULL)
1162+
{
1163+
SWSS_LOG_ERROR("Failed to find object metadata: object type %s",
1164+
sai_serialize_object_type(objectType).c_str());
1165+
1166+
return;
1167+
}
1168+
1169+
if (meta->statenum == NULL)
1170+
{
1171+
SWSS_LOG_ERROR("%s does not support stats", meta->objecttypename);
1172+
1173+
return;
1174+
}
1175+
1176+
bool countOnly = (status == SAI_STATUS_BUFFER_OVERFLOW);
1177+
1178+
if (status == SAI_STATUS_SUCCESS || status == SAI_STATUS_BUFFER_OVERFLOW)
1179+
{
1180+
str_stats_list = sai_serialize_stats_capability_list(*stats_capability, meta->statenum, countOnly);
1181+
}
1182+
1183+
recordQueryStatsCapabilityResponse(status, str_stats_list);
1184+
}
1185+
11071186
void Recorder::recordNotifySyncd(
11081187
_In_ sai_object_id_t switchId,
11091188
_In_ sai_redis_notify_syncd_t redisNotifySyncd)

lib/Recorder.h

+18
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,16 @@ namespace sairedis
298298
_In_ sai_attr_id_t attrId,
299299
_In_ const sai_s32_list_t* enumValuesCapability);
300300

301+
void recordQueryStatsCapability(
302+
_In_ sai_object_id_t switch_id,
303+
_In_ sai_object_type_t object_type,
304+
_Inout_ sai_stat_capability_list_t* stats_capability);
305+
306+
void recordQueryStatsCapabilityResponse(
307+
_In_ sai_status_t status,
308+
_In_ sai_object_type_t objectType,
309+
_In_ const sai_stat_capability_list_t *stats_capability);
310+
301311
// TODO move to private
302312
void recordQueryAttributeCapability(
303313
_In_ const std::string& key,
@@ -323,6 +333,14 @@ namespace sairedis
323333
_In_ sai_status_t status,
324334
_In_ const std::vector<swss::FieldValueTuple>& arguments);
325335

336+
void recordQueryStatsCapability(
337+
_In_ const std::string& key,
338+
_In_ const std::vector<swss::FieldValueTuple>& arguments);
339+
340+
void recordQueryStatsCapabilityResponse(
341+
_In_ sai_status_t status,
342+
_In_ const std::string& arguments);
343+
326344
public: // SAI notifications
327345

328346
void recordNotification(

0 commit comments

Comments
 (0)