Skip to content

Commit d8bbe32

Browse files
committed
sonic-sairedis : Wred stats feature changes on Sai-redis and Syncd
* Stats capability query API support is added Signed-off-by: rpmarvell <rperumal@marvell.com>
1 parent dc93d4c commit d8bbe32

18 files changed

+685
-64
lines changed

lib/ClientSai.cpp

Lines changed: 144 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -886,16 +886,6 @@ sai_status_t ClientSai::getStats(
886886
return waitForGetStatsResponse(number_of_counters, counters);
887887
}
888888

889-
sai_status_t ClientSai::queryStatsCapability(
890-
_In_ sai_object_id_t switchId,
891-
_In_ sai_object_type_t objectType,
892-
_Inout_ sai_stat_capability_list_t *stats_capability)
893-
{
894-
SWSS_LOG_ENTER();
895-
896-
return SAI_STATUS_NOT_IMPLEMENTED;
897-
}
898-
899889
sai_status_t ClientSai::waitForGetStatsResponse(
900890
_In_ uint32_t number_of_counters,
901891
_Out_ uint64_t *counters)
@@ -924,6 +914,150 @@ sai_status_t ClientSai::waitForGetStatsResponse(
924914
return status;
925915
}
926916

917+
sai_status_t ClientSai::queryStatsCapability(
918+
_In_ sai_object_id_t switchId,
919+
_In_ sai_object_type_t objectType,
920+
_Inout_ sai_stat_capability_list_t *stats_capability)
921+
{
922+
MUTEX();
923+
SWSS_LOG_ENTER();
924+
REDIS_CHECK_API_INITIALIZED();
925+
926+
if (stats_capability && stats_capability->list)
927+
{
928+
// clear input list, since we use serialize to transfer values
929+
for (uint32_t idx = 0; idx < stats_capability->count; idx++)
930+
{
931+
stats_capability->list[idx].stat_enum = 0;
932+
stats_capability->list[idx].stat_modes = 0;
933+
}
934+
}
935+
936+
auto switchIdStr = sai_serialize_object_id(switchId);
937+
auto objectTypeStr = sai_serialize_object_type(objectType);
938+
const std::string list_size = std::to_string(stats_capability->count);
939+
940+
const std::vector<swss::FieldValueTuple> entry =
941+
{
942+
swss::FieldValueTuple("OBJECT_TYPE", objectTypeStr),
943+
swss::FieldValueTuple("LIST_SIZE", list_size)
944+
};
945+
946+
SWSS_LOG_NOTICE( /* DEBUG */
947+
"Query arguments: switch %s, object type: %s, count: %s",
948+
switchIdStr.c_str(),
949+
objectTypeStr.c_str(),
950+
list_size.c_str()
951+
);
952+
953+
// This query will not put any data into the ASIC view, just into the
954+
// message queue
955+
956+
m_communicationChannel->set(switchIdStr, entry, REDIS_ASIC_STATE_COMMAND_STATS_CAPABILITY_QUERY);
957+
958+
auto status = waitForQueryStatsCapabilityResponse(stats_capability);
959+
960+
return status;
961+
}
962+
963+
sai_status_t ClientSai::waitForQueryStatsCapabilityResponse(
964+
_Inout_ sai_stat_capability_list_t* stats_capability)
965+
{
966+
SWSS_LOG_ENTER();
967+
968+
swss::KeyOpFieldsValuesTuple kco;
969+
970+
auto status = m_communicationChannel->wait(REDIS_ASIC_STATE_COMMAND_STATS_CAPABILITY_RESPONSE, kco);
971+
972+
if (status == SAI_STATUS_SUCCESS)
973+
{
974+
const std::vector<swss::FieldValueTuple> &values = kfvFieldsValues(kco);
975+
976+
if (values.size() != 3)
977+
{
978+
SWSS_LOG_ERROR("Invalid response from syncd: expected 3 value, received %zu", values.size());
979+
980+
return SAI_STATUS_FAILURE;
981+
}
982+
983+
const std::string &stat_enum_str = fvValue(values[0]);
984+
const std::string &stat_modes_str = fvValue(values[1]);
985+
const uint32_t num_capabilities = std::stoi(fvValue(values[2]));
986+
987+
/*DEBUG*/
988+
SWSS_LOG_NOTICE("Received payload: stat_enums = '%s', stat_modes = '%s', count = %d",
989+
stat_enum_str.c_str(), stat_modes_str.c_str(), num_capabilities);
990+
991+
stats_capability->count = num_capabilities;
992+
993+
size_t stat_enum_position = 0;
994+
size_t stat_modes_position = 0;
995+
for (uint32_t i = 0; i < num_capabilities; i++)
996+
{
997+
/* Populate stat_enum */
998+
size_t old_stat_enum_position = stat_enum_position;
999+
stat_enum_position = stat_enum_str.find(",", old_stat_enum_position);
1000+
std::string stat_enum = stat_enum_str.substr(old_stat_enum_position,
1001+
stat_enum_position - old_stat_enum_position);
1002+
stats_capability->list[i].stat_enum = std::stoi(stat_enum);
1003+
1004+
// We have run out of values to add to our list
1005+
if (stat_enum_position == std::string::npos)
1006+
{
1007+
if (num_capabilities != i + 1)
1008+
{
1009+
SWSS_LOG_WARN("Query returned less stat_enums than expected: expected %d, received %d",
1010+
num_capabilities, i+1);
1011+
}
1012+
1013+
break;
1014+
}
1015+
1016+
/* Populate stat_modes */
1017+
size_t old_stat_modes_position = stat_modes_position;
1018+
stat_modes_position = stat_modes_str.find(",", old_stat_modes_position);
1019+
std::string stat_modes = stat_modes_str.substr(old_stat_modes_position,
1020+
stat_modes_position - old_stat_modes_position);
1021+
stats_capability->list[i].stat_modes = std::stoi(stat_modes);
1022+
1023+
// We have run out of values to add to our list
1024+
if (stat_modes_position == std::string::npos)
1025+
{
1026+
if (num_capabilities != i + 1)
1027+
{
1028+
SWSS_LOG_WARN("Query returned less stat_modes than expected: expected %d, received %d",
1029+
num_capabilities, i+1);
1030+
}
1031+
1032+
break;
1033+
}
1034+
1035+
// Skip the commas
1036+
stat_enum_position++;
1037+
stat_modes_position++;
1038+
}
1039+
}
1040+
else if (status == SAI_STATUS_BUFFER_OVERFLOW)
1041+
{
1042+
const std::vector<swss::FieldValueTuple> &values = kfvFieldsValues(kco);
1043+
1044+
if (values.size() != 1)
1045+
{
1046+
SWSS_LOG_ERROR("Invalid response from syncd: expected 1 value, received %zu", values.size());
1047+
1048+
return SAI_STATUS_FAILURE;
1049+
}
1050+
1051+
const uint32_t num_capabilities = std::stoi(fvValue(values[0]));
1052+
1053+
SWSS_LOG_DEBUG("Received payload: count = %u", num_capabilities);
1054+
1055+
stats_capability->count = num_capabilities;
1056+
}
1057+
1058+
return status;
1059+
}
1060+
9271061
sai_status_t ClientSai::getStatsExt(
9281062
_In_ sai_object_type_t object_type,
9291063
_In_ sai_object_id_t object_id,

lib/ClientSai.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,9 @@ namespace sairedis
285285
sai_status_t waitForObjectTypeGetAvailabilityResponse(
286286
_In_ uint64_t *count);
287287

288+
sai_status_t waitForQueryStatsCapabilityResponse(
289+
_Inout_ sai_stat_capability_list_t* stats_capability);
290+
288291
private:
289292

290293
void handleNotification(

lib/ClientServerSai.cpp

Lines changed: 4 additions & 1 deletion
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

Lines changed: 84 additions & 0 deletions
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::vector<swss::FieldValueTuple>& arguments)
385+
{
386+
SWSS_LOG_ENTER();
387+
388+
recordLine("Q|stats_capability|" + sai_serialize_status(status) + "|" + Globals::joinFieldValues(arguments));
389+
}
390+
373391
void Recorder::recordNotifySyncd(
374392
_In_ const std::string& key)
375393
{
@@ -1089,6 +1107,72 @@ void Recorder::recordQueryAattributeEnumValuesCapabilityResponse(
10891107
recordQueryAttributeEnumValuesCapabilityResponse(status, values);
10901108
}
10911109

1110+
void Recorder::recordQueryStatsCapability(
1111+
_In_ sai_object_id_t switchId,
1112+
_In_ sai_object_type_t object_type,
1113+
_Inout_ sai_stat_capability_list_t* stats_capability)
1114+
{
1115+
SWSS_LOG_ENTER();
1116+
1117+
auto key = sai_serialize_object_type(SAI_OBJECT_TYPE_SWITCH) + ":" + sai_serialize_object_id(switchId);
1118+
1119+
auto object_type_str = sai_serialize_object_type(object_type);
1120+
const std::string list_size = std::to_string(stats_capability->count);
1121+
const std::vector<swss::FieldValueTuple> values =
1122+
{
1123+
swss::FieldValueTuple("OBJECT_TYPE", object_type_str),
1124+
swss::FieldValueTuple("LIST_SIZE", list_size)
1125+
};
1126+
1127+
/*DEBUG*/
1128+
SWSS_LOG_NOTICE("Query arguments: switch %s, object_type: %s, count: %s",
1129+
key.c_str(),
1130+
object_type_str.c_str(),
1131+
list_size.c_str());
1132+
1133+
recordQueryStatsCapability (key, values);
1134+
}
1135+
1136+
void Recorder::recordQueryStatsCapabilityResponse(
1137+
_In_ sai_status_t status,
1138+
_In_ sai_object_type_t objectType,
1139+
_In_ const sai_stat_capability_list_t *stats_capability)
1140+
{
1141+
SWSS_LOG_ENTER();
1142+
#if 0
1143+
std::vector<swss::FieldValueTuple> values;
1144+
1145+
auto meta = sai_metadata_get_attr_metadata(objectType, attrId);
1146+
1147+
if (meta == NULL)
1148+
{
1149+
SWSS_LOG_ERROR("Failed to find attribute metadata: object type %s, attr id %d",
1150+
sai_serialize_object_type(objectType).c_str(),
1151+
attrId);
1152+
1153+
return;
1154+
}
1155+
1156+
if (!meta->enummetadata)
1157+
{
1158+
SWSS_LOG_ERROR("Attribute %s is not enum/enumlist!", meta->attridname);
1159+
return;
1160+
}
1161+
1162+
bool countOnly = (status == SAI_STATUS_BUFFER_OVERFLOW);
1163+
1164+
if (status == SAI_STATUS_SUCCESS || status == SAI_STATUS_BUFFER_OVERFLOW)
1165+
{
1166+
auto str_attr_id = sai_serialize_attr_id(*meta);
1167+
auto str_enum_list = sai_serialize_enum_list(*enumValuesCapability, meta->enummetadata, countOnly);
1168+
1169+
values.emplace_back(str_attr_id, str_enum_list);
1170+
}
1171+
1172+
recordQueryAttributeEnumValuesCapabilityResponse(status, values);
1173+
#endif
1174+
}
1175+
10921176
void Recorder::recordNotifySyncd(
10931177
_In_ sai_object_id_t switchId,
10941178
_In_ sai_redis_notify_syncd_t redisNotifySyncd)

lib/Recorder.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,16 @@ namespace sairedis
325325
_In_ sai_attr_id_t attrId,
326326
_In_ const sai_s32_list_t* enumValuesCapability);
327327

328+
void recordQueryStatsCapability(
329+
_In_ sai_object_id_t switch_id,
330+
_In_ sai_object_type_t object_type,
331+
_Inout_ sai_stat_capability_list_t* stats_capability);
332+
333+
void recordQueryStatsCapabilityResponse(
334+
_In_ sai_status_t status,
335+
_In_ sai_object_type_t objectType,
336+
_In_ const sai_stat_capability_list_t *stats_capability);
337+
328338
// TODO move to private
329339
void recordQueryAttributeCapability(
330340
_In_ const std::string& key,
@@ -350,6 +360,14 @@ namespace sairedis
350360
_In_ sai_status_t status,
351361
_In_ const std::vector<swss::FieldValueTuple>& arguments);
352362

363+
void recordQueryStatsCapability(
364+
_In_ const std::string& key,
365+
_In_ const std::vector<swss::FieldValueTuple>& arguments);
366+
367+
void recordQueryStatsCapabilityResponse(
368+
_In_ sai_status_t status,
369+
_In_ const std::vector<swss::FieldValueTuple>& arguments);
370+
353371
public: // SAI notifications
354372

355373
void recordNotification(

0 commit comments

Comments
 (0)