Skip to content

Commit f939b95

Browse files
[qosorch]: Optimizations of qosorch (sonic-net#488)
* Get the switch attribute SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_CHILDS_PER_SCHEDULER_GROUP just once * Compress scheduler group creation time in 2.5 times * Inprove style
1 parent edafa34 commit f939b95

File tree

2 files changed

+113
-76
lines changed

2 files changed

+113
-76
lines changed

orchagent/qosorch.cpp

+101-76
Original file line numberDiff line numberDiff line change
@@ -875,106 +875,131 @@ task_process_status QosOrch::handleSchedulerTable(Consumer& consumer)
875875
return task_process_status::task_success;
876876
}
877877

878-
bool QosOrch::applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, sai_object_id_t scheduler_profile_id)
878+
sai_object_id_t QosOrch::getSchedulerGroup(const Port &port, const sai_object_id_t queue_id)
879879
{
880880
SWSS_LOG_ENTER();
881-
sai_attribute_t attr;
882-
sai_status_t sai_status;
883-
sai_object_id_t queue_id;
884-
vector<sai_object_id_t> groups;
885-
vector<sai_object_id_t> child_groups;
886-
uint32_t groups_count = 0;
887-
888-
if (port.m_queue_ids.size() <= queue_ind)
889-
{
890-
SWSS_LOG_ERROR("Invalid queue index specified:%zd", queue_ind);
891-
return false;
892-
}
893-
queue_id = port.m_queue_ids[queue_ind];
894-
895-
/* Get max child groups count */
896-
attr.id = SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_CHILDS_PER_SCHEDULER_GROUP;
897-
sai_status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr);
898-
if (SAI_STATUS_SUCCESS != sai_status)
899-
{
900-
SWSS_LOG_ERROR("Failed to get number of childs per scheduler group for port:%s", port.m_alias.c_str());
901-
return false;
902-
}
903-
child_groups.resize(attr.value.u32);
904-
905-
/* Get max sched groups count */
906-
attr.id = SAI_PORT_ATTR_QOS_NUMBER_OF_SCHEDULER_GROUPS;
907-
sai_status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr);
908-
if (SAI_STATUS_SUCCESS != sai_status)
909-
{
910-
SWSS_LOG_ERROR("Failed to get number of scheduler groups for port:%s", port.m_alias.c_str());
911-
return false;
912-
}
913-
914-
/* Get total groups list on the port */
915-
groups_count = attr.value.u32;
916-
groups.resize(groups_count);
917881

918-
attr.id = SAI_PORT_ATTR_QOS_SCHEDULER_GROUP_LIST;
919-
attr.value.objlist.list = groups.data();
920-
attr.value.objlist.count = groups_count;
921-
sai_status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr);
922-
if (SAI_STATUS_SUCCESS != sai_status)
923-
{
924-
SWSS_LOG_ERROR("Failed to get scheduler group list for port:%s", port.m_alias.c_str());
925-
return false;
926-
}
882+
sai_attribute_t attr;
883+
sai_status_t sai_status;
927884

928-
/* Lookup groups to which queue belongs */
929-
for (uint32_t ii = 0; ii < groups_count ; ii++)
885+
const auto it = m_scheduler_group_port_info.find(port.m_port_id);
886+
if (it == m_scheduler_group_port_info.end())
930887
{
931-
uint32_t child_count = 0;
932-
933-
attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT;//Number of queues/groups childs added to scheduler group
934-
sai_status = sai_scheduler_group_api->get_scheduler_group_attribute(groups[ii], 1, &attr);
935-
child_count = attr.value.u32;
888+
/* Get max sched groups count */
889+
attr.id = SAI_PORT_ATTR_QOS_NUMBER_OF_SCHEDULER_GROUPS;
890+
sai_status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr);
936891
if (SAI_STATUS_SUCCESS != sai_status)
937892
{
938-
SWSS_LOG_ERROR("Failed to get child count for scheduler group:0x%lx of port:%s", groups[ii], port.m_alias.c_str());
939-
return false;
893+
SWSS_LOG_ERROR("Failed to get number of scheduler groups for port:%s", port.m_alias.c_str());
894+
return SAI_NULL_OBJECT_ID;
940895
}
941896

942-
// skip this iteration if there're no children in this group
943-
if (child_count == 0)
944-
{
945-
continue;
946-
}
897+
/* Get total groups list on the port */
898+
uint32_t groups_count = attr.value.u32;
899+
std::vector<sai_object_id_t> groups(groups_count);
947900

948-
attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST;
949-
attr.value.objlist.list = child_groups.data();
950-
attr.value.objlist.count = child_count;
951-
sai_status = sai_scheduler_group_api->get_scheduler_group_attribute(groups[ii], 1, &attr);
901+
attr.id = SAI_PORT_ATTR_QOS_SCHEDULER_GROUP_LIST;
902+
attr.value.objlist.list = groups.data();
903+
attr.value.objlist.count = groups_count;
904+
sai_status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr);
952905
if (SAI_STATUS_SUCCESS != sai_status)
953906
{
954-
SWSS_LOG_ERROR("Failed to get child list for scheduler group:0x%lx of port:%s", groups[ii], port.m_alias.c_str());
955-
return false;
907+
SWSS_LOG_ERROR("Failed to get scheduler group list for port:%s", port.m_alias.c_str());
908+
return SAI_NULL_OBJECT_ID;
956909
}
957910

958-
for (uint32_t jj = 0; jj < child_count; jj++)
911+
m_scheduler_group_port_info[port.m_port_id] = {
912+
.groups = std::move(groups),
913+
.child_groups = std::vector<std::vector<sai_object_id_t>>(groups_count)
914+
};
915+
}
916+
917+
/* Lookup groups to which queue belongs */
918+
const auto& groups = m_scheduler_group_port_info[port.m_port_id].groups;
919+
for (uint32_t ii = 0; ii < groups.size() ; ii++)
920+
{
921+
const auto& group_id = groups[ii];
922+
const auto& child_groups_per_group = m_scheduler_group_port_info[port.m_port_id].child_groups[ii];
923+
if (child_groups_per_group.empty())
959924
{
960-
if (child_groups[jj] != queue_id)
925+
attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT;//Number of queues/groups childs added to scheduler group
926+
sai_status = sai_scheduler_group_api->get_scheduler_group_attribute(group_id, 1, &attr);
927+
if (SAI_STATUS_SUCCESS != sai_status)
928+
{
929+
SWSS_LOG_ERROR("Failed to get child count for scheduler group:0x%lx of port:%s", group_id, port.m_alias.c_str());
930+
return SAI_NULL_OBJECT_ID;
931+
}
932+
933+
uint32_t child_count = attr.value.u32;
934+
vector<sai_object_id_t> child_groups(child_count);
935+
936+
// skip this iteration if there're no children in this group
937+
if (child_count == 0)
961938
{
962939
continue;
963940
}
964941

965-
attr.id = SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID;
966-
attr.value.oid = scheduler_profile_id;
967-
sai_status = sai_scheduler_group_api->set_scheduler_group_attribute(groups[ii], &attr);
942+
attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST;
943+
attr.value.objlist.list = child_groups.data();
944+
attr.value.objlist.count = child_count;
945+
sai_status = sai_scheduler_group_api->get_scheduler_group_attribute(group_id, 1, &attr);
968946
if (SAI_STATUS_SUCCESS != sai_status)
969947
{
970-
SWSS_LOG_ERROR("Failed applying scheduler profile:0x%lx to scheduler group:0x%lx, port:%s", scheduler_profile_id, groups[ii], port.m_alias.c_str());
971-
return false;
948+
SWSS_LOG_ERROR("Failed to get child list for scheduler group:0x%lx of port:%s", group_id, port.m_alias.c_str());
949+
return SAI_NULL_OBJECT_ID;
950+
}
951+
952+
m_scheduler_group_port_info[port.m_port_id].child_groups[ii] = std::move(child_groups);
953+
}
954+
955+
for (const auto& child_group_id: child_groups_per_group)
956+
{
957+
if (child_group_id == queue_id)
958+
{
959+
return group_id;
972960
}
973-
SWSS_LOG_DEBUG("port:%s, scheduler_profile_id:0x%lx applied to scheduler group:0x%lx", port.m_alias.c_str(), scheduler_profile_id, groups[ii]);
974-
return true;
975961
}
976962
}
977-
return false;
963+
964+
return SAI_NULL_OBJECT_ID;
965+
}
966+
967+
bool QosOrch::applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, sai_object_id_t scheduler_profile_id)
968+
{
969+
SWSS_LOG_ENTER();
970+
971+
if (port.m_queue_ids.size() <= queue_ind)
972+
{
973+
SWSS_LOG_ERROR("Invalid queue index specified:%zd", queue_ind);
974+
return false;
975+
}
976+
977+
const sai_object_id_t queue_id = port.m_queue_ids[queue_ind];
978+
979+
const sai_object_id_t group_id = getSchedulerGroup(port, queue_id);
980+
if(group_id == SAI_NULL_OBJECT_ID)
981+
{
982+
SWSS_LOG_ERROR("Failed to find a scheduler group for port: %s queue: %lu", port.m_alias.c_str(), queue_ind);
983+
return false;
984+
}
985+
986+
/* Apply scheduler profile to all port groups */
987+
sai_attribute_t attr;
988+
sai_status_t sai_status;
989+
990+
attr.id = SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID;
991+
attr.value.oid = scheduler_profile_id;
992+
993+
sai_status = sai_scheduler_group_api->set_scheduler_group_attribute(group_id, &attr);
994+
if (SAI_STATUS_SUCCESS != sai_status)
995+
{
996+
SWSS_LOG_ERROR("Failed applying scheduler profile:0x%lx to scheduler group:0x%lx, port:%s", scheduler_profile_id, group_id, port.m_alias.c_str());
997+
return false;
998+
}
999+
1000+
SWSS_LOG_DEBUG("port:%s, scheduler_profile_id:0x%lx applied to scheduler group:0x%lx", port.m_alias.c_str(), scheduler_profile_id, group_id);
1001+
1002+
return true;
9781003
}
9791004

9801005
bool QosOrch::applyWredProfileToQueue(Port &port, size_t queue_ind, sai_object_id_t sai_wred_profile)

orchagent/qosorch.h

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#define SWSS_QOSORCH_H
33

44
#include <map>
5+
#include <unordered_map>
6+
#include <unordered_set>
57
#include "orch.h"
68
#include "portsorch.h"
79

@@ -132,6 +134,8 @@ class QosOrch : public Orch
132134
task_process_status handleQueueTable(Consumer& consumer);
133135
task_process_status handleWredProfileTable(Consumer& consumer);
134136

137+
sai_object_id_t getSchedulerGroup(const Port &port, const sai_object_id_t queue_id);
138+
135139
bool applyMapToPort(Port &port, sai_attr_id_t attr_id, sai_object_id_t sai_dscp_to_tc_map);
136140
bool applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, sai_object_id_t scheduler_profile_id);
137141
bool applyWredProfileToQueue(Port &port, size_t queue_ind, sai_object_id_t sai_wred_profile);
@@ -140,5 +144,13 @@ class QosOrch : public Orch
140144

141145
private:
142146
qos_table_handler_map m_qos_handler_map;
147+
148+
struct SchedulerGroupPortInfo_t
149+
{
150+
std::vector<sai_object_id_t> groups;
151+
std::vector<std::vector<sai_object_id_t>> child_groups;
152+
};
153+
154+
std::unordered_map<sai_object_id_t, SchedulerGroupPortInfo_t> m_scheduler_group_port_info;
143155
};
144156
#endif /* SWSS_QOSORCH_H */

0 commit comments

Comments
 (0)