From 31c749b5cf498dfe0f14d2f1e746e9c93b387154 Mon Sep 17 00:00:00 2001 From: Pavel Shirshov Date: Tue, 24 Apr 2018 12:17:41 -0700 Subject: [PATCH 1/3] Get the switch attribute SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_CHILDS_PER_SCHEDULER_GROUP just once --- orchagent/qosorch.cpp | 22 +++++++++++----------- orchagent/qosorch.h | 1 + 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/orchagent/qosorch.cpp b/orchagent/qosorch.cpp index b85a6655c6..9e0d223b44 100644 --- a/orchagent/qosorch.cpp +++ b/orchagent/qosorch.cpp @@ -621,6 +621,16 @@ QosOrch::QosOrch(DBConnector *db, vector &tableNames) : Orch(db, tableNa } initTableHandlers(); + + /* Get max child groups count */ + sai_attribute_t attr; + attr.id = SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_CHILDS_PER_SCHEDULER_GROUP; + sai_status_t status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr); + if (SAI_STATUS_SUCCESS != status) + { + throw runtime_error("Failed to get number of childs per scheduler group"); + } + m_max_number_of_childs_per_scheduler_group = attr.value.u32; }; type_map& QosOrch::getTypeMap() @@ -882,7 +892,7 @@ bool QosOrch::applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, sai_status_t sai_status; sai_object_id_t queue_id; vector groups; - vector child_groups; + vector child_groups(m_max_number_of_childs_per_scheduler_group); uint32_t groups_count = 0; if (port.m_queue_ids.size() <= queue_ind) @@ -892,16 +902,6 @@ bool QosOrch::applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, } queue_id = port.m_queue_ids[queue_ind]; - /* Get max child groups count */ - attr.id = SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_CHILDS_PER_SCHEDULER_GROUP; - sai_status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr); - if (SAI_STATUS_SUCCESS != sai_status) - { - SWSS_LOG_ERROR("Failed to get number of childs per scheduler group for port:%s", port.m_alias.c_str()); - return false; - } - child_groups.resize(attr.value.u32); - /* Get max sched groups count */ attr.id = SAI_PORT_ATTR_QOS_NUMBER_OF_SCHEDULER_GROUPS; sai_status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr); diff --git a/orchagent/qosorch.h b/orchagent/qosorch.h index 3c39d37012..4c98934ef9 100644 --- a/orchagent/qosorch.h +++ b/orchagent/qosorch.h @@ -140,5 +140,6 @@ class QosOrch : public Orch private: qos_table_handler_map m_qos_handler_map; + sai_uint32_t m_max_number_of_childs_per_scheduler_group; }; #endif /* SWSS_QOSORCH_H */ From 1dc9cccbedb93e52bb41827dda790f56c3b695dd Mon Sep 17 00:00:00 2001 From: Pavel Shirshov Date: Wed, 25 Apr 2018 12:46:44 -0700 Subject: [PATCH 2/3] Compress scheduler group creation time in 2.5 times --- orchagent/qosorch.cpp | 172 ++++++++++++++++++++++++------------------ orchagent/qosorch.h | 13 +++- 2 files changed, 109 insertions(+), 76 deletions(-) diff --git a/orchagent/qosorch.cpp b/orchagent/qosorch.cpp index 9e0d223b44..2570dfe4b9 100644 --- a/orchagent/qosorch.cpp +++ b/orchagent/qosorch.cpp @@ -621,16 +621,6 @@ QosOrch::QosOrch(DBConnector *db, vector &tableNames) : Orch(db, tableNa } initTableHandlers(); - - /* Get max child groups count */ - sai_attribute_t attr; - attr.id = SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_CHILDS_PER_SCHEDULER_GROUP; - sai_status_t status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr); - if (SAI_STATUS_SUCCESS != status) - { - throw runtime_error("Failed to get number of childs per scheduler group"); - } - m_max_number_of_childs_per_scheduler_group = attr.value.u32; }; type_map& QosOrch::getTypeMap() @@ -885,96 +875,128 @@ task_process_status QosOrch::handleSchedulerTable(Consumer& consumer) return task_process_status::task_success; } -bool QosOrch::applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, sai_object_id_t scheduler_profile_id) +sai_object_id_t QosOrch::getSchedulerGroup(const Port &port, const sai_object_id_t queue_id) { SWSS_LOG_ENTER(); + sai_attribute_t attr; sai_status_t sai_status; - sai_object_id_t queue_id; - vector groups; - vector child_groups(m_max_number_of_childs_per_scheduler_group); - uint32_t groups_count = 0; - if (port.m_queue_ids.size() <= queue_ind) + const auto it = m_scheduler_group_port_info.find(port.m_port_id); + if (it == m_scheduler_group_port_info.end()) { - SWSS_LOG_ERROR("Invalid queue index specified:%zd", queue_ind); - return false; - } - queue_id = port.m_queue_ids[queue_ind]; - - /* Get max sched groups count */ - attr.id = SAI_PORT_ATTR_QOS_NUMBER_OF_SCHEDULER_GROUPS; - sai_status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr); - if (SAI_STATUS_SUCCESS != sai_status) - { - SWSS_LOG_ERROR("Failed to get number of scheduler groups for port:%s", port.m_alias.c_str()); - return false; - } - - /* Get total groups list on the port */ - groups_count = attr.value.u32; - groups.resize(groups_count); - - attr.id = SAI_PORT_ATTR_QOS_SCHEDULER_GROUP_LIST; - attr.value.objlist.list = groups.data(); - attr.value.objlist.count = groups_count; - sai_status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr); - if (SAI_STATUS_SUCCESS != sai_status) - { - SWSS_LOG_ERROR("Failed to get scheduler group list for port:%s", port.m_alias.c_str()); - return false; - } - - /* Lookup groups to which queue belongs */ - for (uint32_t ii = 0; ii < groups_count ; ii++) - { - uint32_t child_count = 0; - - attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT;//Number of queues/groups childs added to scheduler group - sai_status = sai_scheduler_group_api->get_scheduler_group_attribute(groups[ii], 1, &attr); - child_count = attr.value.u32; + /* Get max sched groups count */ + attr.id = SAI_PORT_ATTR_QOS_NUMBER_OF_SCHEDULER_GROUPS; + sai_status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr); if (SAI_STATUS_SUCCESS != sai_status) { - SWSS_LOG_ERROR("Failed to get child count for scheduler group:0x%lx of port:%s", groups[ii], port.m_alias.c_str()); - return false; + SWSS_LOG_ERROR("Failed to get number of scheduler groups for port:%s", port.m_alias.c_str()); + return SAI_NULL_OBJECT_ID; } - // skip this iteration if there're no children in this group - if (child_count == 0) - { - continue; - } + /* Get total groups list on the port */ + uint32_t groups_count = attr.value.u32; + std::vector groups(groups_count); - attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST; - attr.value.objlist.list = child_groups.data(); - attr.value.objlist.count = child_count; - sai_status = sai_scheduler_group_api->get_scheduler_group_attribute(groups[ii], 1, &attr); + attr.id = SAI_PORT_ATTR_QOS_SCHEDULER_GROUP_LIST; + attr.value.objlist.list = groups.data(); + attr.value.objlist.count = groups_count; + sai_status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr); if (SAI_STATUS_SUCCESS != sai_status) { - SWSS_LOG_ERROR("Failed to get child list for scheduler group:0x%lx of port:%s", groups[ii], port.m_alias.c_str()); - return false; + SWSS_LOG_ERROR("Failed to get scheduler group list for port:%s", port.m_alias.c_str()); + return SAI_NULL_OBJECT_ID; } - for (uint32_t jj = 0; jj < child_count; jj++) + m_scheduler_group_port_info[port.m_port_id] = { + .groups = std::move(groups), + .child_groups = std::vector>(groups_count) + }; + } + + /* Lookup groups to which queue belongs */ + for (uint32_t ii = 0; ii < m_scheduler_group_port_info[port.m_port_id].groups.size() ; ii++) + { + const auto& group_id = m_scheduler_group_port_info[port.m_port_id].groups[ii]; + const auto& child_groups = m_scheduler_group_port_info[port.m_port_id].child_groups[ii]; + if (child_groups.empty()) { - if (child_groups[jj] != queue_id) + attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT;//Number of queues/groups childs added to scheduler group + sai_status = sai_scheduler_group_api->get_scheduler_group_attribute(group_id, 1, &attr); + if (SAI_STATUS_SUCCESS != sai_status) + { + SWSS_LOG_ERROR("Failed to get child count for scheduler group:0x%lx of port:%s", group_id, port.m_alias.c_str()); + return SAI_NULL_OBJECT_ID; + } + + uint32_t child_count = attr.value.u32; + vector child_groups(child_count); + + // skip this iteration if there're no children in this group + if (child_count == 0) { continue; } - attr.id = SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID; - attr.value.oid = scheduler_profile_id; - sai_status = sai_scheduler_group_api->set_scheduler_group_attribute(groups[ii], &attr); + attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST; + attr.value.objlist.list = child_groups.data(); + attr.value.objlist.count = child_count; + sai_status = sai_scheduler_group_api->get_scheduler_group_attribute(group_id, 1, &attr); if (SAI_STATUS_SUCCESS != sai_status) { - 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()); - return false; + SWSS_LOG_ERROR("Failed to get child list for scheduler group:0x%lx of port:%s", group_id, port.m_alias.c_str()); + return SAI_NULL_OBJECT_ID; + } + m_scheduler_group_port_info[port.m_port_id].child_groups[ii] = std::move(child_groups); + } + + for (uint32_t jj = 0; jj < m_scheduler_group_port_info[port.m_port_id].child_groups[ii].size(); jj++) + { + if (m_scheduler_group_port_info[port.m_port_id].child_groups[ii][jj] == queue_id) + { + return group_id; } - 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]); - return true; } } - return false; + + return SAI_NULL_OBJECT_ID; +} + +bool QosOrch::applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, sai_object_id_t scheduler_profile_id) +{ + SWSS_LOG_ENTER(); + + if (port.m_queue_ids.size() <= queue_ind) + { + SWSS_LOG_ERROR("Invalid queue index specified:%zd", queue_ind); + return false; + } + + const sai_object_id_t queue_id = port.m_queue_ids[queue_ind]; + + const sai_object_id_t group_id = getSchedulerGroup(port, queue_id); + if(group_id == SAI_NULL_OBJECT_ID) + { + return false; + } + + /* Apply scheduler profile to all port groups */ + sai_attribute_t attr; + sai_status_t sai_status; + + attr.id = SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID; + attr.value.oid = scheduler_profile_id; + + sai_status = sai_scheduler_group_api->set_scheduler_group_attribute(group_id, &attr); + if (SAI_STATUS_SUCCESS != sai_status) + { + 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()); + return false; + } + + 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); + + return true; } bool QosOrch::applyWredProfileToQueue(Port &port, size_t queue_ind, sai_object_id_t sai_wred_profile) diff --git a/orchagent/qosorch.h b/orchagent/qosorch.h index 4c98934ef9..03b70a7dbc 100644 --- a/orchagent/qosorch.h +++ b/orchagent/qosorch.h @@ -2,6 +2,8 @@ #define SWSS_QOSORCH_H #include +#include +#include #include "orch.h" #include "portsorch.h" @@ -132,6 +134,8 @@ class QosOrch : public Orch task_process_status handleQueueTable(Consumer& consumer); task_process_status handleWredProfileTable(Consumer& consumer); + sai_object_id_t getSchedulerGroup(const Port &port, const sai_object_id_t queue_id); + bool applyMapToPort(Port &port, sai_attr_id_t attr_id, sai_object_id_t sai_dscp_to_tc_map); bool applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, sai_object_id_t scheduler_profile_id); bool applyWredProfileToQueue(Port &port, size_t queue_ind, sai_object_id_t sai_wred_profile); @@ -140,6 +144,13 @@ class QosOrch : public Orch private: qos_table_handler_map m_qos_handler_map; - sai_uint32_t m_max_number_of_childs_per_scheduler_group; + + struct SchedulerGroupPortInfo_t + { + std::vector groups; + std::vector> child_groups; + }; + + std::unordered_map m_scheduler_group_port_info; }; #endif /* SWSS_QOSORCH_H */ From 4f8aadc610430a953d86ce2f1504b82321619c1c Mon Sep 17 00:00:00 2001 From: Pavel Shirshov Date: Wed, 25 Apr 2018 13:21:01 -0700 Subject: [PATCH 3/3] Inprove style --- orchagent/qosorch.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/orchagent/qosorch.cpp b/orchagent/qosorch.cpp index 2570dfe4b9..23f0e9f0c9 100644 --- a/orchagent/qosorch.cpp +++ b/orchagent/qosorch.cpp @@ -879,8 +879,8 @@ sai_object_id_t QosOrch::getSchedulerGroup(const Port &port, const sai_object_id { SWSS_LOG_ENTER(); - sai_attribute_t attr; - sai_status_t sai_status; + sai_attribute_t attr; + sai_status_t sai_status; const auto it = m_scheduler_group_port_info.find(port.m_port_id); if (it == m_scheduler_group_port_info.end()) @@ -915,11 +915,12 @@ sai_object_id_t QosOrch::getSchedulerGroup(const Port &port, const sai_object_id } /* Lookup groups to which queue belongs */ - for (uint32_t ii = 0; ii < m_scheduler_group_port_info[port.m_port_id].groups.size() ; ii++) + const auto& groups = m_scheduler_group_port_info[port.m_port_id].groups; + for (uint32_t ii = 0; ii < groups.size() ; ii++) { - const auto& group_id = m_scheduler_group_port_info[port.m_port_id].groups[ii]; - const auto& child_groups = m_scheduler_group_port_info[port.m_port_id].child_groups[ii]; - if (child_groups.empty()) + const auto& group_id = groups[ii]; + const auto& child_groups_per_group = m_scheduler_group_port_info[port.m_port_id].child_groups[ii]; + if (child_groups_per_group.empty()) { attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT;//Number of queues/groups childs added to scheduler group sai_status = sai_scheduler_group_api->get_scheduler_group_attribute(group_id, 1, &attr); @@ -947,12 +948,13 @@ sai_object_id_t QosOrch::getSchedulerGroup(const Port &port, const sai_object_id SWSS_LOG_ERROR("Failed to get child list for scheduler group:0x%lx of port:%s", group_id, port.m_alias.c_str()); return SAI_NULL_OBJECT_ID; } + m_scheduler_group_port_info[port.m_port_id].child_groups[ii] = std::move(child_groups); } - for (uint32_t jj = 0; jj < m_scheduler_group_port_info[port.m_port_id].child_groups[ii].size(); jj++) + for (const auto& child_group_id: child_groups_per_group) { - if (m_scheduler_group_port_info[port.m_port_id].child_groups[ii][jj] == queue_id) + if (child_group_id == queue_id) { return group_id; } @@ -977,6 +979,7 @@ bool QosOrch::applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, const sai_object_id_t group_id = getSchedulerGroup(port, queue_id); if(group_id == SAI_NULL_OBJECT_ID) { + SWSS_LOG_ERROR("Failed to find a scheduler group for port: %s queue: %lu", port.m_alias.c_str(), queue_ind); return false; }