Skip to content

Commit

Permalink
[pfcwdactionhandler]: Add PG setting (sonic-net#326)
Browse files Browse the repository at this point in the history
PFC storm drop handler that applies zero size buffer profile to a queue, also
has to apply zero size profile to ingress PG to drop RX traffic too.
Code that creates profiles and pools was refactored to always create
only one mode of pools/profiles (because it actually doesn't matter which mode
is configured - traffic is dropped anyway).

Signed-off-by: marian-pritsak <marianp@mellanox.com>
  • Loading branch information
marian-pritsak authored and lguohan committed Oct 6, 2017
1 parent 455fd5e commit 9339d9c
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 146 deletions.
210 changes: 76 additions & 134 deletions orchagent/pfcactionhandler.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "pfcactionhandler.h"
#include "logger.h"
#include "saiserialize.h"
#include "portsorch.h"

#include <vector>

Expand All @@ -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;
Expand Down Expand Up @@ -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<sai_buffer_profile_threshold_mode_t>(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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -288,111 +315,40 @@ 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<sai_attribute_t> 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<uint32_t>(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<uint32_t>(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<sai_attribute_t> 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;
attr.value.u32 = SAI_BUFFER_POOL_THRESHOLD_MODE_DYNAMIC;
attribs.push_back(attr);

sai_status_t status = sai_buffer_api->create_buffer_pool(
&m_zeroDynamicBufferPool,
&getPool(ingress),
gSwitchId,
static_cast<uint32_t>(attribs.size()),
attribs.data());
Expand All @@ -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;
Expand All @@ -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<uint32_t>(attribs.size()),
attribs.data());
Expand All @@ -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);
}
}
32 changes: 20 additions & 12 deletions orchagent/pfcactionhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 9339d9c

Please sign in to comment.