From 79c2f72532c357cdd945cd9c7feb0423e857604f Mon Sep 17 00:00:00 2001 From: Vineet Mittal Date: Fri, 23 Jun 2023 05:09:56 +0000 Subject: [PATCH 1/2] Support WRED profiles on system ports --- orchagent/portsorch.cpp | 4 +- orchagent/qosorch.cpp | 117 ++++++++++++++++++++++++++++++++-------- 2 files changed, 96 insertions(+), 25 deletions(-) diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 03bc0d74f38..811f3528fd3 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -7971,8 +7971,8 @@ bool PortsOrch::addSystemPorts() } } - //System port for local port. Update the system port info in the existing physical port - if(!getPort(attr.value.oid, port)) + Port local_port; + if(!getPort(attr.value.oid, local_port)) { //This is system port for non-front panel local port (CPU or OLP or RCY (Inband)). Not an error SWSS_LOG_NOTICE("Add port for non-front panel local system port 0x%" PRIx64 "; core: %d, core port: %d", diff --git a/orchagent/qosorch.cpp b/orchagent/qosorch.cpp index c61885992eb..91f1bc1e030 100644 --- a/orchagent/qosorch.cpp +++ b/orchagent/qosorch.cpp @@ -28,6 +28,7 @@ extern PortsOrch *gPortsOrch; extern QosOrch *gQosOrch; extern sai_object_id_t gSwitchId; extern CrmOrch *gCrmOrch; +extern string gMySwitchType; map ecn_map = { {"ecn_none", SAI_ECN_MARK_MODE_NONE}, @@ -1626,22 +1627,58 @@ sai_object_id_t QosOrch::getSchedulerGroup(const Port &port, const sai_object_id bool QosOrch::applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, sai_object_id_t scheduler_profile_id) { SWSS_LOG_ENTER(); + sai_object_id_t queue_id; + Port input_port = port; + sai_object_id_t group_id = 0; - if (port.m_queue_ids.size() <= queue_ind) + if (gMySwitchType == "voq") { - SWSS_LOG_ERROR("Invalid queue index specified:%zd", queue_ind); - return false; - } + if(port.m_system_port_info.type == SAI_SYSTEM_PORT_TYPE_REMOTE) + { + return true; + } + + // Get local port from system port. port is pointing to local port now + if (!gPortsOrch->getPort(port.m_system_port_info.local_port_oid, port)) + { + SWSS_LOG_ERROR("Port with alias:%s not found", port.m_alias.c_str()); + return task_process_status::task_invalid_entry; + } - const sai_object_id_t queue_id = port.m_queue_ids[queue_ind]; + if (port.m_queue_ids.size() <= queue_ind) + { + SWSS_LOG_ERROR("Invalid queue index specified:%zd", queue_ind); + return false; + } + queue_id = port.m_queue_ids[queue_ind]; + + 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: %zu", port.m_alias.c_str(), queue_ind); + return false; + } - const sai_object_id_t group_id = getSchedulerGroup(port, queue_id); - if(group_id == SAI_NULL_OBJECT_ID) + // port is set back to system port + port = input_port; + } + else { - SWSS_LOG_ERROR("Failed to find a scheduler group for port: %s queue: %zu", port.m_alias.c_str(), queue_ind); - return false; + if (port.m_queue_ids.size() <= queue_ind) + { + SWSS_LOG_ERROR("Invalid queue index specified:%zd", queue_ind); + return false; + } + queue_id = port.m_queue_ids[queue_ind]; + + 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: %zu", port.m_alias.c_str(), queue_ind); + return false; + } } - + /* Apply scheduler profile to all port groups */ sai_attribute_t attr; sai_status_t sai_status; @@ -1652,7 +1689,6 @@ bool QosOrch::applySchedulerToQueueSchedulerGroup(Port &port, size_t queue_ind, 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%" PRIx64 " to scheduler group:0x%" PRIx64 ", port:%s", scheduler_profile_id, group_id, port.m_alias.c_str()); task_process_status handle_status = handleSaiSetStatus(SAI_API_SCHEDULER_GROUP, sai_status); if (handle_status != task_success) { @@ -1672,12 +1708,25 @@ bool QosOrch::applyWredProfileToQueue(Port &port, size_t queue_ind, sai_object_i sai_status_t sai_status; sai_object_id_t queue_id; - if (port.m_queue_ids.size() <= queue_ind) + if (gMySwitchType == "voq") { - SWSS_LOG_ERROR("Invalid queue index specified:%zd", queue_ind); - return false; + std :: vector queue_ids = gPortsOrch->getPortVoQIds(port); + if (queue_ids.size() <= queue_ind) + { + SWSS_LOG_ERROR("Invalid voq index specified:%zd", queue_ind); + return task_process_status::task_invalid_entry; + } + queue_id = queue_ids[queue_ind]; + } + else + { + if (port.m_queue_ids.size() <= queue_ind) + { + SWSS_LOG_ERROR("Invalid queue index specified:%zd", queue_ind); + return false; + } + queue_id = port.m_queue_ids[queue_ind]; } - queue_id = port.m_queue_ids[queue_ind]; attr.id = SAI_QUEUE_ATTR_WRED_PROFILE_ID; attr.value.oid = sai_wred_profile; @@ -1708,18 +1757,40 @@ task_process_status QosOrch::handleQueueTable(Consumer& consumer, KeyOpFieldsVal vector port_names; ref_resolve_status resolve_result; - // sample "QUEUE: {Ethernet4|0-1}" + /* + Input sample "QUEUE : {Ethernet4|0-1}" or + "QUEUE : {STG01-0101-0400-01T2-LC6|ASIC0|Ethernet4|0-1}" + */ tokens = tokenize(key, config_db_key_delimiter); - if (tokens.size() != 2) + + if (gMySwitchType == "voq") { - SWSS_LOG_ERROR("malformed key:%s. Must contain 2 tokens", key.c_str()); - return task_process_status::task_invalid_entry; + if (tokens.size() != 4) + { + SWSS_LOG_ERROR("malformed key:%s. Must contain 4 tokens", key.c_str()); + return task_process_status::task_invalid_entry; + } + + port_names = tokenize(tokens[0] + config_db_key_delimiter + tokens[1] + config_db_key_delimiter + tokens[2], list_item_delimiter); + if (!parseIndexRange(tokens[3], range_low, range_high)) + { + SWSS_LOG_ERROR("Failed to parse range:%s", tokens[3].c_str()); + return task_process_status::task_invalid_entry; + } } - port_names = tokenize(tokens[0], list_item_delimiter); - if (!parseIndexRange(tokens[1], range_low, range_high)) + else { - SWSS_LOG_ERROR("Failed to parse range:%s", tokens[1].c_str()); - return task_process_status::task_invalid_entry; + if (tokens.size() != 2) + { + SWSS_LOG_ERROR("malformed key:%s. Must contain 2 tokens", key.c_str()); + return task_process_status::task_invalid_entry; + } + port_names = tokenize(tokens[0], list_item_delimiter); + if (!parseIndexRange(tokens[1], range_low, range_high)) + { + SWSS_LOG_ERROR("Failed to parse range:%s", tokens[1].c_str()); + return task_process_status::task_invalid_entry; + } } bool donotChangeScheduler = false; From bec8d3d12bab6913701c2f2bf6abf1b2732e5bb7 Mon Sep 17 00:00:00 2001 From: Vineet Mittal Date: Fri, 7 Jul 2023 22:27:57 +0000 Subject: [PATCH 2/2] Fix for system port for local ports --- orchagent/bufferorch.cpp | 33 ++++++++++++++++++++++++++++++--- orchagent/portsorch.cpp | 3 +-- orchagent/qosorch.cpp | 17 +++++++++++++++++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/orchagent/bufferorch.cpp b/orchagent/bufferorch.cpp index 42aae302478..c0d6efceff6 100644 --- a/orchagent/bufferorch.cpp +++ b/orchagent/bufferorch.cpp @@ -20,6 +20,8 @@ extern PortsOrch *gPortsOrch; extern Directory gDirectory; extern sai_object_id_t gSwitchId; extern string gMySwitchType; +extern string gMyHostName; +extern string gMyAsicName; #define BUFFER_POOL_WATERMARK_FLEX_STAT_COUNTER_POLL_MSECS "60000" @@ -788,6 +790,8 @@ task_process_status BufferOrch::processQueue(KeyOpFieldsValuesTuple &tuple) vector tokens; sai_uint32_t range_low, range_high; bool need_update_sai = true; + bool local_port = false; + string local_port_name; SWSS_LOG_DEBUG("Processing:%s", key.c_str()); tokens = tokenize(key, delimiter); @@ -806,6 +810,13 @@ task_process_status BufferOrch::processQueue(KeyOpFieldsValuesTuple &tuple) { return task_process_status::task_invalid_entry; } + + if(tokens[0] == gMyHostName) + { + local_port = true; + local_port_name = tokens[2]; + SWSS_LOG_INFO("System port %s is local port %d local port name %s", port_names[0].c_str(), local_port, local_port_name.c_str()); + } } else { @@ -883,7 +894,13 @@ task_process_status BufferOrch::processQueue(KeyOpFieldsValuesTuple &tuple) for (string port_name : port_names) { Port port; - SWSS_LOG_DEBUG("processing port:%s", port_name.c_str()); + SWSS_LOG_ERROR("processing port:%s", port_name.c_str()); + + if(local_port == true) + { + port_name = local_port_name; + } + if (!gPortsOrch->getPort(port_name, port)) { SWSS_LOG_ERROR("Port with alias:%s not found", port_name.c_str()); @@ -1001,9 +1018,19 @@ task_process_status BufferOrch::processQueue(KeyOpFieldsValuesTuple &tuple) // set order is detected. for (const auto &port_name : port_names) { - if (gPortsOrch->isPortAdminUp(port_name)) { - SWSS_LOG_WARN("Queue profile '%s' applied after port %s is up", key.c_str(), port_name.c_str()); + if(local_port == true) + { + if (gPortsOrch->isPortAdminUp(local_port_name)) { + SWSS_LOG_WARN("Queue profile '%s' applied after port %s is up", key.c_str(), port_name.c_str()); + } + } + else + { + if (gPortsOrch->isPortAdminUp(port_name)) { + SWSS_LOG_WARN("Queue profile '%s' applied after port %s is up", key.c_str(), port_name.c_str()); + } } + } } diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 811f3528fd3..6c9957df69e 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -7971,8 +7971,7 @@ bool PortsOrch::addSystemPorts() } } - Port local_port; - if(!getPort(attr.value.oid, local_port)) + if(!getPort(attr.value.oid, port)) { //This is system port for non-front panel local port (CPU or OLP or RCY (Inband)). Not an error SWSS_LOG_NOTICE("Add port for non-front panel local system port 0x%" PRIx64 "; core: %d, core port: %d", diff --git a/orchagent/qosorch.cpp b/orchagent/qosorch.cpp index 91f1bc1e030..4065df65a2c 100644 --- a/orchagent/qosorch.cpp +++ b/orchagent/qosorch.cpp @@ -29,6 +29,8 @@ extern QosOrch *gQosOrch; extern sai_object_id_t gSwitchId; extern CrmOrch *gCrmOrch; extern string gMySwitchType; +extern string gMyHostName; +extern string gMyAsicName; map ecn_map = { {"ecn_none", SAI_ECN_MARK_MODE_NONE}, @@ -1752,6 +1754,8 @@ task_process_status QosOrch::handleQueueTable(Consumer& consumer, KeyOpFieldsVal string op = kfvOp(tuple); size_t queue_ind = 0; vector tokens; + bool local_port = false; + string local_port_name; sai_uint32_t range_low, range_high; vector port_names; @@ -1777,6 +1781,13 @@ task_process_status QosOrch::handleQueueTable(Consumer& consumer, KeyOpFieldsVal SWSS_LOG_ERROR("Failed to parse range:%s", tokens[3].c_str()); return task_process_status::task_invalid_entry; } + + if(tokens[0] == gMyHostName) + { + local_port = true; + local_port_name = tokens[2]; + SWSS_LOG_INFO("System port %s is local port %d local port name %s", port_names[0].c_str(), local_port, local_port_name.c_str()); + } } else { @@ -1884,6 +1895,12 @@ task_process_status QosOrch::handleQueueTable(Consumer& consumer, KeyOpFieldsVal { Port port; SWSS_LOG_DEBUG("processing port:%s", port_name.c_str()); + + if(local_port == true) + { + port_name = local_port_name; + } + if (!gPortsOrch->getPort(port_name, port)) { SWSS_LOG_ERROR("Port with alias:%s not found", port_name.c_str());