diff --git a/orchagent/pfcactionhandler.cpp b/orchagent/pfcactionhandler.cpp index 6ba149d757b2..b42598ebbcc0 100644 --- a/orchagent/pfcactionhandler.cpp +++ b/orchagent/pfcactionhandler.cpp @@ -1,6 +1,7 @@ #include "pfcactionhandler.h" #include "logger.h" #include "saiserialize.h" +#include "portsorch.h" #include @@ -15,6 +16,7 @@ #define SAI_QUEUE_STAT_DROPPED_PACKETS_STR "SAI_QUEUE_STAT_DROPPED_PACKETS" extern sai_object_id_t gSwitchId; +extern PortsOrch *gPortsOrch; extern sai_port_api_t *sai_port_api; extern sai_queue_api_t *sai_queue_api; extern sai_buffer_api_t *sai_buffer_api; @@ -200,53 +202,57 @@ PfcWdZeroBufferHandler::PfcWdZeroBufferHandler(sai_object_id_t port, return; } - sai_object_id_t oldProfileId = attr.value.oid; -#if 0 - attr.id = SAI_BUFFER_PROFILE_ATTR_THRESHOLD_MODE; - attr.value.u32 = 0; + sai_object_id_t oldQueueProfileId = attr.value.oid; + + attr.id = SAI_QUEUE_ATTR_BUFFER_PROFILE_ID; + attr.value.oid = ZeroBufferProfile::getZeroBufferProfile(false); - // Get threshold mode of buffer profile - status = sai_buffer_api->get_buffer_profile_attribute(oldProfileId, 1, &attr); + // Set our zero buffer profile + status = sai_queue_api->set_queue_attribute(queue, &attr); if (status != SAI_STATUS_SUCCESS) { - SWSS_LOG_ERROR("Failed to get buffer profile threshold mode for 0x%lx: %d", queue, status); + SWSS_LOG_ERROR("Failed to set buffer profile ID on queue 0x%lx: %d", queue, status); return; } - sai_buffer_profile_threshold_mode_t threshold_mode = static_cast(attr.value.u32); -#endif - - // XXX: Remove when above is fixed - sai_buffer_profile_threshold_mode_t threshold_mode = SAI_BUFFER_PROFILE_THRESHOLD_MODE_DYNAMIC; + // Save original buffer profile + m_originalQueueBufferProfile = oldQueueProfileId; - sai_object_id_t zeroBufferProfileId = SAI_NULL_OBJECT_ID; - if (threshold_mode == SAI_BUFFER_PROFILE_THRESHOLD_MODE_STATIC) - { - zeroBufferProfileId = ZeroBufferProfile::getStaticProfile(); - } - else if (threshold_mode == SAI_BUFFER_PROFILE_THRESHOLD_MODE_DYNAMIC) + // Get PG + Port portInstance; + if (!gPortsOrch->getPort(port, portInstance)) { - zeroBufferProfileId = ZeroBufferProfile::getDynamicProfile(); + SWSS_LOG_ERROR("Cannot get port by ID 0x%lx", port); + return; } - else + + sai_object_id_t pg = portInstance.m_priority_group_ids[queueId]; + + attr.id = SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE; + + // Get PG's buffer profile + status = sai_buffer_api->get_ingress_priority_group_attribute(pg, 1, &attr); + if (status != SAI_STATUS_SUCCESS) { - SWSS_LOG_ERROR("Buffer mode in buffer 0x%lx is not supported", queue); + SWSS_LOG_ERROR("Failed to get buffer profile ID on PG 0x%lx: %d", pg, status); return; } - attr.id = SAI_QUEUE_ATTR_BUFFER_PROFILE_ID; - attr.value.oid = zeroBufferProfileId; + // Set zero profile to PG + sai_object_id_t oldPgProfileId = attr.value.oid; - // Set our zero buffer profile - status = sai_queue_api->set_queue_attribute(queue, &attr); + attr.id = SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE; + attr.value.oid = ZeroBufferProfile::getZeroBufferProfile(true); + + status = sai_buffer_api->set_ingress_priority_group_attribute(pg, &attr); if (status != SAI_STATUS_SUCCESS) { - SWSS_LOG_ERROR("Failed to set buffer profile ID on queue 0x%lx: %d", queue, status); + SWSS_LOG_ERROR("Failed to set buffer profile ID on pg 0x%lx: %d", pg, status); return; } // Save original buffer profile - m_originalBufferProfile = oldProfileId; + m_originalPgBufferProfile = oldPgProfileId; } PfcWdZeroBufferHandler::~PfcWdZeroBufferHandler(void) @@ -255,15 +261,35 @@ PfcWdZeroBufferHandler::~PfcWdZeroBufferHandler(void) sai_attribute_t attr; attr.id = SAI_QUEUE_ATTR_BUFFER_PROFILE_ID; - attr.value.oid = m_originalBufferProfile; + attr.value.oid = m_originalQueueBufferProfile; - // Set our zero buffer profile + // Set our zero buffer profile on a queue sai_status_t status = sai_queue_api->set_queue_attribute(getQueue(), &attr); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("Failed to set buffer profile ID on queue 0x%lx: %d", getQueue(), status); return; } + + Port portInstance; + if (!gPortsOrch->getPort(getPort(), portInstance)) + { + SWSS_LOG_ERROR("Cannot get port by ID 0x%lx", getPort()); + return; + } + + sai_object_id_t pg = portInstance.m_priority_group_ids[getQueueId()]; + + attr.id = SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE; + attr.value.oid = m_originalPgBufferProfile; + + // Set our zero buffer profile + status = sai_buffer_api->set_ingress_priority_group_attribute(pg, &attr); + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Failed to set buffer profile ID on queue 0x%lx: %d", getQueue(), status); + return; + } } PfcWdZeroBufferHandler::ZeroBufferProfile::ZeroBufferProfile(void) @@ -275,8 +301,9 @@ PfcWdZeroBufferHandler::ZeroBufferProfile::~ZeroBufferProfile(void) { SWSS_LOG_ENTER(); - destroyStaticProfile(); - destroyDynamicProfile(); + // Destory ingress and egress prifiles and pools + destroyZeroBufferProfile(true); + destroyZeroBufferProfile(false); } PfcWdZeroBufferHandler::ZeroBufferProfile &PfcWdZeroBufferHandler::ZeroBufferProfile::getInstance(void) @@ -288,103 +315,32 @@ PfcWdZeroBufferHandler::ZeroBufferProfile &PfcWdZeroBufferHandler::ZeroBufferPro return instance; } -sai_object_id_t PfcWdZeroBufferHandler::ZeroBufferProfile::getStaticProfile(void) +sai_object_id_t PfcWdZeroBufferHandler::ZeroBufferProfile::getZeroBufferProfile(bool ingress) { SWSS_LOG_ENTER(); - if (getInstance().m_zeroStaticBufferProfile == SAI_NULL_OBJECT_ID) + if (getInstance().getProfile(ingress) == SAI_NULL_OBJECT_ID) { - getInstance().createStaticProfile(); + getInstance().createZeroBufferProfile(ingress); } - return getInstance().m_zeroStaticBufferProfile; + return getInstance().getProfile(ingress); } -sai_object_id_t PfcWdZeroBufferHandler::ZeroBufferProfile::getDynamicProfile(void) -{ - SWSS_LOG_ENTER(); - - if (getInstance().m_zeroDynamicBufferProfile == SAI_NULL_OBJECT_ID) - { - getInstance().createDynamicProfile(); - } - - return getInstance().m_zeroDynamicBufferProfile; -} - -void PfcWdZeroBufferHandler::ZeroBufferProfile::createStaticProfile(void) +void PfcWdZeroBufferHandler::ZeroBufferProfile::createZeroBufferProfile(bool ingress) { SWSS_LOG_ENTER(); sai_attribute_t attr; vector attribs; - // Create static zero pool + // Create zero pool attr.id = SAI_BUFFER_POOL_ATTR_SIZE; attr.value.u32 = 0; attribs.push_back(attr); attr.id = SAI_BUFFER_POOL_ATTR_TYPE; - attr.value.u32 = SAI_BUFFER_POOL_TYPE_EGRESS; - attribs.push_back(attr); - - attr.id = SAI_BUFFER_POOL_ATTR_THRESHOLD_MODE; - attr.value.u32 = SAI_BUFFER_POOL_THRESHOLD_MODE_STATIC; - attribs.push_back(attr); - - sai_status_t status = sai_buffer_api->create_buffer_pool( - &m_zeroStaticBufferPool, - gSwitchId, - static_cast(attribs.size()), - attribs.data()); - if (status != SAI_STATUS_SUCCESS) - { - SWSS_LOG_ERROR("Failed to create static zero buffer pool for PFC WD: %d", status); - return; - } - - // Create static zero profile - attribs.clear(); - - attr.id = SAI_BUFFER_PROFILE_ATTR_POOL_ID; - attr.value.oid = m_zeroStaticBufferPool; - attribs.push_back(attr); - - attr.id = SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE; - attr.value.u32 = 0; - attribs.push_back(attr); - - attr.id = SAI_BUFFER_PROFILE_ATTR_SHARED_STATIC_TH; - attr.value.u32 = 0; - attribs.push_back(attr); - - status = sai_buffer_api->create_buffer_profile( - &m_zeroStaticBufferProfile, - gSwitchId, - static_cast(attribs.size()), - attribs.data()); - if (status != SAI_STATUS_SUCCESS) - { - SWSS_LOG_ERROR("Failed to create static zero buffer profile for PFC WD: %d", status); - return; - } -} - - -void PfcWdZeroBufferHandler::ZeroBufferProfile::createDynamicProfile(void) -{ - SWSS_LOG_ENTER(); - - sai_attribute_t attr; - vector attribs; - - // Create dynamic zero pool - attr.id = SAI_BUFFER_POOL_ATTR_SIZE; - attr.value.u32 = 0; - attribs.push_back(attr); - - attr.id = SAI_BUFFER_POOL_ATTR_TYPE; - attr.value.u32 = SAI_BUFFER_POOL_TYPE_EGRESS; + attr.value.u32 = ingress ? SAI_BUFFER_POOL_TYPE_INGRESS : SAI_BUFFER_POOL_TYPE_EGRESS; attribs.push_back(attr); attr.id = SAI_BUFFER_POOL_ATTR_THRESHOLD_MODE; @@ -392,7 +348,7 @@ void PfcWdZeroBufferHandler::ZeroBufferProfile::createDynamicProfile(void) attribs.push_back(attr); sai_status_t status = sai_buffer_api->create_buffer_pool( - &m_zeroDynamicBufferPool, + &getPool(ingress), gSwitchId, static_cast(attribs.size()), attribs.data()); @@ -402,11 +358,15 @@ void PfcWdZeroBufferHandler::ZeroBufferProfile::createDynamicProfile(void) return; } - // Create dynamic zero profile + // Create zero profile attribs.clear(); attr.id = SAI_BUFFER_PROFILE_ATTR_POOL_ID; - attr.value.oid = m_zeroDynamicBufferPool; + attr.value.oid = getPool(ingress); + attribs.push_back(attr); + + attr.id = SAI_BUFFER_PROFILE_ATTR_THRESHOLD_MODE; + attr.value.u32 = SAI_BUFFER_PROFILE_THRESHOLD_MODE_DYNAMIC; attribs.push_back(attr); attr.id = SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE; @@ -418,7 +378,7 @@ void PfcWdZeroBufferHandler::ZeroBufferProfile::createDynamicProfile(void) attribs.push_back(attr); status = sai_buffer_api->create_buffer_profile( - &m_zeroDynamicBufferProfile, + &getProfile(ingress), gSwitchId, static_cast(attribs.size()), attribs.data()); @@ -429,38 +389,20 @@ void PfcWdZeroBufferHandler::ZeroBufferProfile::createDynamicProfile(void) } } -void PfcWdZeroBufferHandler::ZeroBufferProfile::destroyStaticProfile(void) +void PfcWdZeroBufferHandler::ZeroBufferProfile::destroyZeroBufferProfile(bool ingress) { SWSS_LOG_ENTER(); - sai_status_t status = sai_buffer_api->remove_buffer_profile(m_zeroStaticBufferProfile); + sai_status_t status = sai_buffer_api->remove_buffer_profile(getProfile(ingress)); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("Failed to remove static zero buffer profile for PFC WD: %d", status); return; } - status = sai_buffer_api->remove_buffer_pool(m_zeroStaticBufferPool); + status = sai_buffer_api->remove_buffer_pool(getPool(ingress)); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("Failed to remove static zero buffer pool for PFC WD: %d", status); } } - -void PfcWdZeroBufferHandler::ZeroBufferProfile::destroyDynamicProfile(void) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = sai_buffer_api->remove_buffer_profile(m_zeroDynamicBufferProfile); - if (status != SAI_STATUS_SUCCESS) - { - SWSS_LOG_ERROR("Failed to remove dynamic zero buffer profile for PFC WD: %d", status); - return; - } - - status = sai_buffer_api->remove_buffer_pool(m_zeroDynamicBufferPool); - if (status != SAI_STATUS_SUCCESS) - { - SWSS_LOG_ERROR("Failed to remove dynamic zero buffer pool for PFC WD: %d", status); - } -} diff --git a/orchagent/pfcactionhandler.h b/orchagent/pfcactionhandler.h index a1aa06868b66..400751a72ebf 100644 --- a/orchagent/pfcactionhandler.h +++ b/orchagent/pfcactionhandler.h @@ -83,24 +83,32 @@ class PfcWdZeroBufferHandler: public PfcWdLossyHandler { public: ~ZeroBufferProfile(void); - static sai_object_id_t getStaticProfile(void); - static sai_object_id_t getDynamicProfile(void); + static sai_object_id_t getZeroBufferProfile(bool ingress); private: ZeroBufferProfile(void); static ZeroBufferProfile &getInstance(void); - void createStaticProfile(void); - void createDynamicProfile(void); - void destroyStaticProfile(void); - void destroyDynamicProfile(void); - - sai_object_id_t m_zeroStaticBufferPool = SAI_NULL_OBJECT_ID; - sai_object_id_t m_zeroDynamicBufferPool = SAI_NULL_OBJECT_ID; - sai_object_id_t m_zeroStaticBufferProfile = SAI_NULL_OBJECT_ID; - sai_object_id_t m_zeroDynamicBufferProfile = SAI_NULL_OBJECT_ID; + void createZeroBufferProfile(bool ingress); + void destroyZeroBufferProfile(bool ingress); + + sai_object_id_t& getProfile(bool ingress) + { + return ingress ? m_zeroIngressBufferProfile : m_zeroEgressBufferProfile; + } + + sai_object_id_t& getPool(bool ingress) + { + return ingress ? m_zeroIngressBufferPool : m_zeroEgressBufferPool; + } + + sai_object_id_t m_zeroIngressBufferPool = SAI_NULL_OBJECT_ID; + sai_object_id_t m_zeroEgressBufferPool = SAI_NULL_OBJECT_ID; + sai_object_id_t m_zeroIngressBufferProfile = SAI_NULL_OBJECT_ID; + sai_object_id_t m_zeroEgressBufferProfile = SAI_NULL_OBJECT_ID; }; - sai_object_id_t m_originalBufferProfile; + sai_object_id_t m_originalQueueBufferProfile = SAI_NULL_OBJECT_ID; + sai_object_id_t m_originalPgBufferProfile = SAI_NULL_OBJECT_ID; }; #endif