Skip to content

Commit 8d810be

Browse files
[portsorch]: Rewrite validatePortSpeed() method. Use true lazy approach (sonic-net#506)
* We have enough logging inside of the method. Remove the excessive one * Rewrite portsorch::validatespeed. Use true lazy approach to minimize SAI get operations on each port * Restore the missed attr.id * Rename validatePortSpeed to isSpeedSupported. Change logic to return true for erross also. Even we receive an error, we could move further. It's not critical
1 parent 8314a94 commit 8d810be

2 files changed

Lines changed: 55 additions & 30 deletions

File tree

orchagent/portsorch.cpp

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -757,54 +757,80 @@ bool PortsOrch::setHostIntfsStripTag(Port &port, sai_hostif_vlan_tag_t strip)
757757
return true;
758758
}
759759

760-
bool PortsOrch::validatePortSpeed(sai_object_id_t port_id, sai_uint32_t speed)
760+
bool PortsOrch::isSpeedSupported(const std::string& alias, sai_object_id_t port_id, sai_uint32_t speed)
761761
{
762+
// This method will return false iff we get a list of supported speeds and the requested speed
763+
// is not supported
764+
// Otherwise the method will return true (even if we received errors)
765+
762766
sai_attribute_t attr;
763767
sai_status_t status;
764768

765769
// "Lazy" query of supported speeds for given port
766770
// Once received the list will be stored in m_portSupportedSpeeds
767771
if (!m_portSupportedSpeeds.count(port_id))
768772
{
769-
attr.id = SAI_PORT_ATTR_SUPPORTED_SPEED;
770-
attr.value.u32list.count = 0;
771-
attr.value.u32list.list = NULL;
773+
const auto size_guess = 25; // Guess the size which could be enough
772774

773-
status = sai_port_api->get_port_attribute(port_id, 1, &attr);
774-
if (status == SAI_STATUS_BUFFER_OVERFLOW)
775-
{
776-
std::vector<sai_uint32_t> speeds(attr.value.u32list.count);
775+
std::vector<sai_uint32_t> speeds(size_guess);
776+
777+
for (int attempt = 0; attempt < 2; ++attempt) // two attempts to get our value
778+
{ // first with the guess,
779+
// other with the returned value
780+
attr.id = SAI_PORT_ATTR_SUPPORTED_SPEED;
781+
attr.value.u32list.count = static_cast<uint32_t>(speeds.size());
777782
attr.value.u32list.list = speeds.data();
783+
778784
status = sai_port_api->get_port_attribute(port_id, 1, &attr);
779-
if (status == SAI_STATUS_SUCCESS)
785+
if (status != SAI_STATUS_BUFFER_OVERFLOW)
780786
{
781-
m_portSupportedSpeeds[port_id] = speeds;
782-
}
783-
else
784-
{
785-
SWSS_LOG_ERROR("Failed to get supported speed list for port %lx", port_id);
786-
return false;
787+
break;
787788
}
789+
790+
speeds.resize(attr.value.u32list.count); // if our guess was wrong
791+
// retry with the correct value
788792
}
789-
// TODO: change to macro SAI_STATUS_IS_ATTR_NOT_SUPPORTED once it is fixed in SAI
790-
// https://github.com/opencomputeproject/SAI/pull/710
791-
else if ((((status) & (~0xFFFF)) == SAI_STATUS_ATTR_NOT_SUPPORTED_0) ||
792-
(((status) & (~0xFFFF)) == SAI_STATUS_ATTR_NOT_IMPLEMENTED_0) ||
793-
(status == SAI_STATUS_NOT_IMPLEMENTED))
793+
794+
if (status == SAI_STATUS_SUCCESS)
794795
{
795-
// unable to validate speed if attribute is not supported on platform
796-
// assuming input value is correct
797-
SWSS_LOG_WARN("Unable to validate speed for port %lx. Not supported by platform", port_id);
798-
return true;
796+
speeds.resize(attr.value.u32list.count);
797+
m_portSupportedSpeeds[port_id] = speeds;
799798
}
800799
else
801800
{
802-
SWSS_LOG_ERROR("Failed to get number of supported speeds for port %lx", port_id);
803-
return false;
801+
if (status == SAI_STATUS_BUFFER_OVERFLOW)
802+
{
803+
// something went wrong in SAI implementation
804+
SWSS_LOG_ERROR("Failed to get supported speed list for port %s id=%lx. Not enough container size",
805+
alias.c_str(), port_id);
806+
}
807+
else if (SAI_STATUS_IS_ATTR_NOT_SUPPORTED(status) ||
808+
SAI_STATUS_IS_ATTR_NOT_IMPLEMENTED(status) ||
809+
status == SAI_STATUS_NOT_IMPLEMENTED)
810+
{
811+
// unable to validate speed if attribute is not supported on platform
812+
// assuming input value is correct
813+
SWSS_LOG_WARN("Unable to validate speed for port %s id=%lx. Not supported by platform",
814+
alias.c_str(), port_id);
815+
}
816+
else
817+
{
818+
SWSS_LOG_ERROR("Failed to get a list of supported speeds for port %s id=%lx. Error=%d",
819+
alias.c_str(), port_id, status);
820+
}
821+
m_portSupportedSpeeds[port_id] = {}; // use an empty list,
822+
// we don't want to get the port speed for this port again
823+
return true; // we can't check if the speed is valid, so return true to change the speed
804824
}
825+
805826
}
806827

807-
PortSupportedSpeeds &supp_speeds = m_portSupportedSpeeds[port_id];
828+
const PortSupportedSpeeds &supp_speeds = m_portSupportedSpeeds[port_id];
829+
if (supp_speeds.size() == 0)
830+
{
831+
// we don't have the list for this port, so return true to change speed anyway
832+
return true;
833+
}
808834

809835
return std::find(supp_speeds.begin(), supp_speeds.end(), speed) != supp_speeds.end();
810836
}
@@ -1236,9 +1262,8 @@ void PortsOrch::doPortTask(Consumer &consumer)
12361262
{
12371263
sai_uint32_t current_speed;
12381264

1239-
if (!validatePortSpeed(p.m_port_id, speed))
1265+
if (!isSpeedSupported(alias, p.m_port_id, speed))
12401266
{
1241-
SWSS_LOG_ERROR("Failed to set speed %u for port %s. The value is not supported", speed, alias.c_str());
12421267
it++;
12431268
continue;
12441269
}

orchagent/portsorch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ class PortsOrch : public Orch, public Subject
134134

135135
bool setBridgePortAdminStatus(sai_object_id_t id, bool up);
136136

137-
bool validatePortSpeed(sai_object_id_t port_id, sai_uint32_t speed);
137+
bool isSpeedSupported(const std::string& alias, sai_object_id_t port_id, sai_uint32_t speed);
138138
bool setPortSpeed(sai_object_id_t port_id, sai_uint32_t speed);
139139
bool getPortSpeed(sai_object_id_t port_id, sai_uint32_t &speed);
140140

0 commit comments

Comments
 (0)