-
Notifications
You must be signed in to change notification settings - Fork 276
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
ASIC temperature sensors support #383
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -138,6 +138,9 @@ std::string sai_serialize_ipmc_entry_type( | |
std::string sai_serialize_qos_map_item( | ||
_In_ const sai_qos_map_t& qosmap); | ||
|
||
std::string sai_serialize_switch_attr( | ||
_In_ const sai_switch_attr_t switch_attr); | ||
|
||
// serialize notifications | ||
|
||
std::string sai_serialize_fdb_event_ntf( | ||
|
@@ -287,4 +290,8 @@ void sai_deserialize_queue_attr( | |
_In_ const std::string& s, | ||
_Out_ sai_queue_attr_t& attr); | ||
|
||
void sai_deserialize_switch_attr( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please remove we already have generic function to deserialize attributes for all objects |
||
_In_ const std::string& s, | ||
_Out_ sai_switch_attr_t& attr); | ||
|
||
#endif // __SAI_SERIALIZE__ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1636,6 +1636,14 @@ std::string sai_serialize_object_meta_key( | |
return key; | ||
} | ||
|
||
std::string sai_serialize_switch_attr( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please remove we already have generic function to serialize attributes for all objects |
||
_In_ const sai_switch_attr_t switch_attr) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
return sai_serialize_enum(switch_attr, &sai_metadata_enum_sai_switch_attr_t); | ||
} | ||
|
||
// deserialize | ||
|
||
void sai_deserialize_bool( | ||
|
@@ -2976,3 +2984,12 @@ void sai_deserialize_queue_attr( | |
|
||
sai_deserialize_enum(s, &sai_metadata_enum_sai_queue_attr_t, (int32_t&)attr); | ||
} | ||
|
||
void sai_deserialize_switch_attr( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please remove we already have generic function to deserialize attributes for all objects |
||
_In_ const std::string& s, | ||
_Out_ sai_switch_attr_t& attr) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
sai_deserialize_enum(s, &sai_metadata_enum_sai_switch_attr_t, (int32_t&)attr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2907,6 +2907,17 @@ void processFlexCounterEvent( | |
|
||
FlexCounter::setPriorityGroupAttrList(vid, rid, groupName, pgAttrIds); | ||
} | ||
else if (objectType == SAI_OBJECT_TYPE_SWITCH && field == SWITCH_SENSOR_ID_LIST) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why we need this here as special case ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wasn't sure if there could be other (non thermal) attributes that may be of interest in the future.. Agree that there should be a generic approach to handle flex group events (a single table) instead of having to extend event/attribute handling multiple locations... |
||
{ | ||
std::vector<sai_switch_attr_t> SwitchSensorIds; | ||
for (const auto &str : idStrings) | ||
{ | ||
sai_switch_attr_t attr; | ||
sai_deserialize_switch_attr(str, attr); | ||
SwitchSensorIds.push_back(attr); | ||
} | ||
FlexCounter::setSwitchSensorsList(vid, rid, groupName, SwitchSensorIds); | ||
} | ||
else | ||
{ | ||
SWSS_LOG_ERROR("Object type and field combination is not supported, object type %s, field %s", objectTypeStr.c_str(), field.c_str()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ static std::map<std::string, std::shared_ptr<FlexCounter>> g_flex_counters_map; | |
static std::set<sai_port_stat_t> supportedPortCounters; | ||
static std::set<sai_queue_stat_t> supportedQueueCounters; | ||
static std::set<sai_ingress_priority_group_stat_t> supportedPriorityGroupCounters; | ||
static std::set<sai_switch_attr_t> supportedSwitchSensors; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why temperature sensors are in counters ? i think we dont need this implementation here at all, seems like sensors are just another attribute and we can definitely query them There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ASIC sensor readings are not counters per-se - yes.. This is one of the few environmental variables that need to be retrieved thru' SAI : the list may grow but may not bloat. We wanted to leverage the existing flex counter infra (instead of creating a private poller). Since thermal algorithms may typically need this every few seconds, having a script based daemon may be possible. Can you point me to how a script may query attributes directly (rather than query the DB) ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as script i dont know, i had in mind orchagent which would query those sensors using sai apis There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since the load is low, ~8 values in maybe one minute. Moving to orchagent is better. agree with @kcudnik |
||
|
||
FlexCounter::PortCounterIds::PortCounterIds( | ||
_In_ sai_object_id_t port, | ||
|
@@ -49,6 +50,14 @@ FlexCounter::IngressPriorityGroupCounterIds::IngressPriorityGroupCounterIds( | |
SWSS_LOG_ENTER(); | ||
} | ||
|
||
FlexCounter::SwitchSensorIds::SwitchSensorIds( | ||
_In_ sai_object_id_t switch_id, | ||
_In_ const std::vector<sai_switch_attr_t> &SensorIds): | ||
switchId(switch_id), switchSensorIds(SensorIds) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
} | ||
|
||
void FlexCounter::setPollInterval( | ||
_In_ uint32_t pollInterval, | ||
_In_ std::string instanceId) | ||
|
@@ -364,6 +373,59 @@ void FlexCounter::setPriorityGroupAttrList( | |
} | ||
} | ||
|
||
void FlexCounter::setSwitchSensorsList( | ||
_In_ sai_object_id_t switchVid, | ||
_In_ sai_object_id_t switchId, | ||
_In_ std::string instanceId, | ||
_In_ const std::vector<sai_switch_attr_t> &sensorIds) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
FlexCounter &fc = getInstance(instanceId); | ||
|
||
fc.saiUpdateSupportedSwitchSensors(switchId, sensorIds); | ||
|
||
// Remove unsupported sensors | ||
std::vector<sai_switch_attr_t> supportedIds; | ||
for (auto &sensor : sensorIds) | ||
{ | ||
if (fc.isSwitchSensorSupported(sensor)) | ||
{ | ||
supportedIds.push_back(sensor); | ||
} | ||
} | ||
|
||
if (supportedIds.size() == 0) | ||
{ | ||
SWSS_LOG_ERROR("SWITCH %s does not has supported sensors", sai_serialize_object_id(switchId).c_str()); | ||
|
||
// Remove flex counter if all sensor IDs are unregistered | ||
if (fc.isEmpty()) | ||
{ | ||
removeInstance(instanceId); | ||
} | ||
|
||
return; | ||
} | ||
|
||
auto it = fc.m_switchSensorIdsMap.find(switchVid); | ||
if (it != fc.m_switchSensorIdsMap.end()) | ||
{ | ||
(*it).second->switchSensorIds = supportedIds; | ||
return; | ||
} | ||
|
||
auto switchSensorIds = std::make_shared<SwitchSensorIds>(switchId, supportedIds); | ||
fc.m_switchSensorIdsMap.emplace(switchVid, switchSensorIds); | ||
|
||
// Start flex counter thread in case it was not running due to empty sensor IDs map | ||
if (fc.m_pollInterval > 0) | ||
{ | ||
fc.startFlexCounterThread(); | ||
SWSS_LOG_ERROR("setSwitchSensorsList startFlexCounterThread started"); | ||
} | ||
} | ||
|
||
void FlexCounter::removePort( | ||
_In_ sai_object_id_t portVid, | ||
_In_ std::string instanceId) | ||
|
@@ -465,6 +527,35 @@ void FlexCounter::removePriorityGroup( | |
} | ||
} | ||
|
||
void FlexCounter::removeSwitch( | ||
_In_ sai_object_id_t switchVid, | ||
_In_ std::string instanceId) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
FlexCounter &fc = getInstance(instanceId); | ||
|
||
auto it = fc.m_switchSensorIdsMap.find(switchVid); | ||
if (it == fc.m_switchSensorIdsMap.end()) | ||
{ | ||
SWSS_LOG_NOTICE("Trying to remove nonexisting switch sensor Ids 0x%lx", switchVid); | ||
// Remove flex counter if all counter IDs and plugins are unregistered | ||
if (fc.isEmpty()) | ||
{ | ||
removeInstance(instanceId); | ||
} | ||
return; | ||
} | ||
|
||
fc.m_switchSensorIdsMap.erase(it); | ||
|
||
// Remove flex counter if all switch sensor IDs are unregistered | ||
if (fc.isEmpty()) | ||
{ | ||
removeInstance(instanceId); | ||
} | ||
} | ||
|
||
void FlexCounter::addPortCounterPlugin( | ||
_In_ std::string sha, | ||
_In_ std::string instanceId) | ||
|
@@ -609,6 +700,13 @@ bool FlexCounter::isPriorityGroupCounterSupported(sai_ingress_priority_group_sta | |
return supportedPriorityGroupCounters.count(counter) != 0; | ||
} | ||
|
||
bool FlexCounter::isSwitchSensorSupported(sai_switch_attr_t sensor) const | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
return supportedSwitchSensors.count(sensor) != 0; | ||
} | ||
|
||
FlexCounter::FlexCounter(std::string instanceId) : m_instanceId(instanceId) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
@@ -644,6 +742,7 @@ void FlexCounter::collectCounters( | |
std::map<sai_object_id_t, std::shared_ptr<QueueAttrIds>> queueAttrIdsMap; | ||
std::map<sai_object_id_t, std::shared_ptr<IngressPriorityGroupCounterIds>> priorityGroupCounterIdsMap; | ||
std::map<sai_object_id_t, std::shared_ptr<IngressPriorityGroupAttrIds>> priorityGroupAttrIdsMap; | ||
std::map<sai_object_id_t, std::shared_ptr<SwitchSensorIds>> SwitchSensorIdsMap; | ||
|
||
{ | ||
std::lock_guard<std::mutex> lock(g_mutex); | ||
|
@@ -652,6 +751,7 @@ void FlexCounter::collectCounters( | |
queueAttrIdsMap = m_queueAttrIdsMap; | ||
priorityGroupCounterIdsMap = m_priorityGroupCounterIdsMap; | ||
priorityGroupAttrIdsMap = m_priorityGroupAttrIdsMap; | ||
SwitchSensorIdsMap = m_switchSensorIdsMap; | ||
} | ||
|
||
// Collect stats for every registered port | ||
|
@@ -871,6 +971,60 @@ void FlexCounter::collectCounters( | |
countersTable.set(priorityGroupVidStr, values, ""); | ||
} | ||
|
||
// Collect stats for every registered Switch Sensor | ||
for (const auto &kv: SwitchSensorIdsMap) | ||
{ | ||
const auto &switchVid = kv.first; | ||
const auto &switchId = kv.second->switchId; | ||
const auto &switchSensorIds = kv.second->switchSensorIds; | ||
|
||
std::vector<uint32_t> switchSensorValue(switchSensorIds.size()); | ||
|
||
// Push all counter values to a single vector | ||
std::vector<swss::FieldValueTuple> values; | ||
|
||
for (auto &sensor : switchSensorIds) | ||
{ | ||
sai_attribute_t attr; | ||
|
||
if(SAI_SWITCH_ATTR_TEMP_LIST == sensor) { | ||
std::vector<int32_t> temp_list(max_temp_sensors); | ||
|
||
attr.id = SAI_SWITCH_ATTR_TEMP_LIST; | ||
attr.value.s32list.count = max_temp_sensors; | ||
attr.value.s32list.list = temp_list.data(); | ||
|
||
sai_status_t status = sai_metadata_sai_switch_api->get_switch_attribute(switchId , 1, &attr); | ||
if (status != SAI_STATUS_SUCCESS) | ||
{ | ||
SWSS_LOG_ERROR("Failed to get value of sensor 0x%lx: %d", sensor, status); | ||
continue; | ||
} | ||
|
||
for (size_t i = 0; i < attr.value.s32list.count ; i++) { | ||
const std::string &counterName = sai_serialize_switch_attr(sensor) + "_ITEM_" + std::to_string(i); | ||
values.emplace_back(counterName, std::to_string(temp_list[i])); | ||
} | ||
} else { | ||
attr.id = sensor; | ||
sai_status_t status = sai_metadata_sai_switch_api->get_switch_attribute(switchId , 1, &attr); | ||
if (status != SAI_STATUS_SUCCESS) | ||
{ | ||
SWSS_LOG_ERROR("Failed to get value of sensor 0x%lx: %d", sensor, status); | ||
continue; | ||
} | ||
|
||
const std::string &counterName = sai_serialize_switch_attr(sensor); | ||
values.emplace_back(counterName, std::to_string(attr.value.s32)); | ||
} | ||
} | ||
|
||
// Write counters to DB | ||
std::string switchVidStr = sai_serialize_object_id(switchVid); | ||
|
||
countersTable.set(switchVidStr, values, ""); | ||
} | ||
|
||
countersTable.flush(); | ||
} | ||
|
||
|
@@ -1094,3 +1248,51 @@ void FlexCounter::saiUpdateSupportedPriorityGroupCounters( | |
} | ||
} | ||
} | ||
|
||
void FlexCounter::saiUpdateSupportedSwitchSensors( | ||
_In_ sai_object_id_t switchId, | ||
_In_ const std::vector<sai_switch_attr_t> &sensorIds) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
sai_attribute_t attr; | ||
|
||
supportedSwitchSensors.clear(); | ||
|
||
for (auto &sensor : sensorIds) | ||
{ | ||
if(SAI_SWITCH_ATTR_TEMP_LIST == sensor) { | ||
attr.id = SAI_SWITCH_ATTR_MAX_NUMBER_OF_TEMP_SENSORS; | ||
sai_status_t status = sai_metadata_sai_switch_api->get_switch_attribute(switchId , 1, &attr); | ||
if ((status != SAI_STATUS_SUCCESS) || (0 == attr.value.u8)) | ||
{ | ||
SWSS_LOG_INFO("Temperature sensor list is not supported"); | ||
continue; | ||
} else { | ||
max_temp_sensors = attr.value.u8; | ||
} | ||
} | ||
|
||
attr.id = sensor; | ||
|
||
sai_status_t status = sai_metadata_sai_switch_api->get_switch_attribute(switchId , 1, &attr); | ||
|
||
if (status != SAI_STATUS_SUCCESS) | ||
{ | ||
SWSS_LOG_INFO("Sensor %s is not supported on switch %s, rv: %s", | ||
sai_serialize_switch_attr(sensor).c_str(), | ||
sai_serialize_object_id(switchId).c_str(), | ||
sai_serialize_status(status).c_str()); | ||
|
||
continue; | ||
} | ||
else | ||
{ | ||
SWSS_LOG_ERROR("Sensor %s is supported on switch %s, rv: %s", | ||
sai_serialize_switch_attr(sensor).c_str(), | ||
sai_serialize_object_id(switchId).c_str(), | ||
sai_serialize_status(status).c_str()); | ||
supportedSwitchSensors.insert(sensor); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove we already have generic function to serialize attributes for all objects