Skip to content

Commit

Permalink
Merge branch 'github-201803'
Browse files Browse the repository at this point in the history
Conflicts:
	cfgmgr/buffermgr.cpp

    RB=1312100
    G=lnos-reviewers
    R=pchaudha,pmao,rmolina,zxu
    A=
  • Loading branch information
zhenggen-xu committed May 18, 2018
2 parents 9955bf3 + c374357 commit 0591513
Show file tree
Hide file tree
Showing 15 changed files with 377 additions and 73 deletions.
42 changes: 32 additions & 10 deletions cfgmgr/buffermgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ void BufferMgr::readPgProfileLookupFile(string file)
infile.close();
}

void BufferMgr::doCableTask(string port, string cable_length)
task_process_status BufferMgr::doCableTask(string port, string cable_length)
{
m_cableLenLookup[port] = cable_length;
return task_process_status::task_success;
}

string BufferMgr::getPgPoolMode()
Expand Down Expand Up @@ -108,7 +109,7 @@ Create/update two tables: profile (in m_cfgBufferProfileTable) and port buffer (
}
}
*/
void BufferMgr::doSpeedUpdateTask(string port, string speed)
task_process_status BufferMgr::doSpeedUpdateTask(string port, string speed)
{
vector<FieldValueTuple> fvVector;
string cable;
Expand All @@ -117,7 +118,7 @@ void BufferMgr::doSpeedUpdateTask(string port, string speed)
{
/* Set to NOTICE since cable length could be left empty */
SWSS_LOG_NOTICE("Unable to create/update PG profile for port %s. Cable length is not set", port.c_str());
return;
return task_process_status::task_need_retry;
}

cable = m_cableLenLookup[port];
Expand All @@ -126,7 +127,7 @@ void BufferMgr::doSpeedUpdateTask(string port, string speed)
{
SWSS_LOG_ERROR("Unable to create/update PG profile for port %s. No PG profile configured for speed %s and cable length %s",
port.c_str(), speed.c_str(), cable.c_str());
return;
return task_process_status::task_invalid_entry;
}

// Crete record in BUFFER_PROFILE table
Expand All @@ -144,8 +145,8 @@ void BufferMgr::doSpeedUpdateTask(string port, string speed)
if (mode.empty())
{
// this should never happen if switch initialized properly
SWSS_LOG_ERROR("PG lossless pool is not yet created");
return;
SWSS_LOG_WARN("PG lossless pool is not yet created");
return task_process_status::task_need_retry;
}

// profile threshold field name
Expand All @@ -171,6 +172,7 @@ void BufferMgr::doSpeedUpdateTask(string port, string speed)
string profile_ref = string("[") + CFG_BUFFER_PROFILE_TABLE_NAME + CONFIGDB_TABLE_NAME_SEPARATOR + buffer_profile_key + "]";
fvVector.push_back(make_pair("profile", profile_ref));
m_cfgBufferPgTable.set(buffer_pg_key, fvVector);
return task_process_status::task_success;
}

void BufferMgr::doTask(Consumer &consumer)
Expand All @@ -189,25 +191,45 @@ void BufferMgr::doTask(Consumer &consumer)
string port(keys[0]);

string op = kfvOp(t);
task_process_status task_status = task_process_status::task_success;
if (op == SET_COMMAND)
{
for (auto i : kfvFieldsValues(t))
{
if (table_name == CFG_PORT_CABLE_LEN_TABLE_NAME)
{
// receive and cache cable length table
doCableTask(fvField(i), fvValue(i));
task_status = doCableTask(fvField(i), fvValue(i));
}
// In case of PORT table update, Buffer Manager is interested in speed update only
if (table_name == CFG_PORT_TABLE_NAME && fvField(i) == "speed")
{
// create/update profile for port
doSpeedUpdateTask(port, fvValue(i));
task_status = doSpeedUpdateTask(port, fvValue(i));
}
if (task_status != task_process_status::task_success)
{
break;
}
}
}

it = consumer.m_toSync.erase(it);
continue;
switch (task_status)
{
case task_process_status::task_failed:
SWSS_LOG_ERROR("Failed to process table update");
return;
case task_process_status::task_need_retry:
SWSS_LOG_INFO("Unable to process table update. Will retry...");
++it;
break;
case task_process_status::task_invalid_entry:
SWSS_LOG_ERROR("Failed to process invalid entry, drop it");
it = consumer.m_toSync.erase(it);
break;
default:
it = consumer.m_toSync.erase(it);
break;
}
}
}
4 changes: 2 additions & 2 deletions cfgmgr/buffermgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class BufferMgr : public Orch
port_cable_length_t m_cableLenLookup;
std::string getPgPoolMode();
void readPgProfileLookupFile(std::string);
void doCableTask(string port, string cable_length);
void doSpeedUpdateTask(string port, string speed);
task_process_status doCableTask(string port, string cable_length);
task_process_status doSpeedUpdateTask(string port, string speed);

void doTask(Consumer &consumer);
};
Expand Down
43 changes: 43 additions & 0 deletions orchagent/aclorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,11 @@ shared_ptr<AclRule> AclRule::makeShared(acl_table_type_t type, AclOrch *acl, Mir
{
return make_shared<AclRuleL3V6>(acl, rule, table, type);
}
/* Pfcwd rules can exist only in PFCWD table */
else if (type == ACL_TABLE_PFCWD)
{
return make_shared<AclRulePfcwd>(acl, rule, table, type);
}

throw runtime_error("Wrong combination of table type and action in rule " + rule);
}
Expand Down Expand Up @@ -739,6 +744,23 @@ void AclRuleL3::update(SubjectType, void *)
// Do nothing
}


AclRulePfcwd::AclRulePfcwd(AclOrch *aclOrch, string rule, string table, acl_table_type_t type) :
AclRuleL3(aclOrch, rule, table, type)
{
}

bool AclRulePfcwd::validateAddMatch(string attr_name, string attr_value)
{
if (attr_name != MATCH_TC)
{
SWSS_LOG_ERROR("%s is not supported for the tables of type Pfcwd", attr_name.c_str());
return false;
}

return AclRule::validateAddMatch(attr_name, attr_value);
}

AclRuleL3V6::AclRuleL3V6(AclOrch *aclOrch, string rule, string table, acl_table_type_t type) :
AclRuleL3(aclOrch, rule, table, type)
{
Expand All @@ -761,6 +783,7 @@ bool AclRuleL3V6::validateAddMatch(string attr_name, string attr_value)
return AclRule::validateAddMatch(attr_name, attr_value);
}


AclRuleMirror::AclRuleMirror(AclOrch *aclOrch, MirrorOrch *mirror, string rule, string table, acl_table_type_t type) :
AclRule(aclOrch, rule, table, type),
m_state(false),
Expand Down Expand Up @@ -971,6 +994,26 @@ bool AclTable::create()
attr.value.s32list.list = bpoint_list.data();
table_attrs.push_back(attr);

if (type == ACL_TABLE_PFCWD)
{
attr.id = SAI_ACL_TABLE_ATTR_FIELD_TC;
attr.value.booldata = true;
table_attrs.push_back(attr);

attr.id = SAI_ACL_TABLE_ATTR_ACL_STAGE;
attr.value.s32 = stage == ACL_STAGE_INGRESS ? SAI_ACL_STAGE_INGRESS : SAI_ACL_STAGE_EGRESS;
table_attrs.push_back(attr);

sai_status_t status = sai_acl_api->create_acl_table(&m_oid, gSwitchId, (uint32_t)table_attrs.size(), table_attrs.data());

if (status == SAI_STATUS_SUCCESS)
{
gCrmOrch->incCrmAclUsedCounter(CrmResourceType::CRM_ACL_TABLE, (sai_acl_stage_t) attr.value.s32, SAI_ACL_BIND_POINT_TYPE_PORT);
}

return status == SAI_STATUS_SUCCESS;
}

attr.id = SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE;
attr.value.booldata = true;
table_attrs.push_back(attr);
Expand Down
10 changes: 10 additions & 0 deletions orchagent/aclorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define TABLE_TYPE_L3 "L3"
#define TABLE_TYPE_L3V6 "L3V6"
#define TABLE_TYPE_MIRROR "MIRROR"
#define TABLE_TYPE_PFCWD "PFCWD"
#define TABLE_TYPE_CTRLPLANE "CTRLPLANE"

#define RULE_PRIORITY "PRIORITY"
Expand Down Expand Up @@ -73,6 +74,7 @@ typedef enum
ACL_TABLE_L3,
ACL_TABLE_L3V6,
ACL_TABLE_MIRROR,
ACL_TABLE_PFCWD,
ACL_TABLE_CTRLPLANE
} acl_table_type_t;

Expand Down Expand Up @@ -211,6 +213,14 @@ class AclRuleL3V6: public AclRuleL3
bool validateAddMatch(string attr_name, string attr_value);
};

class AclRulePfcwd: public AclRuleL3
{
public:
AclRulePfcwd(AclOrch *m_pAclOrch, string rule, string table, acl_table_type_t type);
bool validateAddMatch(string attr_name, string attr_value);
};


class AclRuleMirror: public AclRule
{
public:
Expand Down
3 changes: 2 additions & 1 deletion orchagent/pfc_detect_broadcom.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ for i = n, 1, -1 do
local is_deadlock = false
local pfc_wd_status = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_STATUS')
local pfc_wd_action = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_ACTION')
if pfc_wd_status == 'operational' or pfc_wd_action == 'alert' then
local big_red_switch_mode = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'BIG_RED_SWITCH_MODE')
if not big_red_switch_mode and (pfc_wd_status == 'operational' or pfc_wd_action == 'alert') then
local detection_time = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_DETECTION_TIME')
if detection_time then
detection_time = tonumber(detection_time)
Expand Down
4 changes: 3 additions & 1 deletion orchagent/pfc_detect_mellanox.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ for i = n, 1, -1 do
local is_deadlock = false
local pfc_wd_status = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_STATUS')
local pfc_wd_action = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_ACTION')
if pfc_wd_status == 'operational' or pfc_wd_action == 'alert' then

local big_red_switch_mode = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'BIG_RED_SWITCH_MODE')
if not big_red_switch_mode and (pfc_wd_status == 'operational' or pfc_wd_action == 'alert') then
local detection_time = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_DETECTION_TIME')
if detection_time then
detection_time = tonumber(detection_time)
Expand Down
5 changes: 3 additions & 2 deletions orchagent/pfc_restore.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ for i = n, 1, -1 do
local pfc_wd_status = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_STATUS')
local restoration_time = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_RESTORATION_TIME')
local pfc_wd_action = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_ACTION')
if pfc_wd_status ~= 'operational' and pfc_wd_action ~= 'alert' and restoration_time and restoration_time ~= '' then
local big_red_switch_mode = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'BIG_RED_SWITCH_MODE')
if not big_red_switch_mode and pfc_wd_status ~= 'operational' and pfc_wd_action ~= 'alert' and restoration_time and restoration_time ~= '' then
restoration_time = tonumber(restoration_time)
local time_left = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_RESTORATION_TIME_LEFT')
if time_left == nil then
if not time_left then
time_left = restoration_time
else
time_left = tonumber(time_left)
Expand Down
34 changes: 6 additions & 28 deletions orchagent/pfcactionhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,12 @@ PfcWdActionHandler::PfcWdActionHandler(sai_object_id_t port, sai_object_id_t que
m_countersTable(countersTable)
{
SWSS_LOG_ENTER();

Port p;
if (!gPortsOrch->getPort(port, p))
{
SWSS_LOG_ERROR("Unknown port id 0x%lx", port);
}
else
{
m_portAlias = p.m_alias;
SWSS_LOG_NOTICE(
"PFC Watchdog detected PFC storm on port %s, queue index %d, queue id 0x%lx and port id 0x%lx.",
m_portAlias.c_str(),
m_queueId,
m_queue,
m_port);
}
}

PfcWdActionHandler::~PfcWdActionHandler(void)
{
SWSS_LOG_ENTER();

SWSS_LOG_NOTICE(
"PFC Watchdog storm restored on port %s, queue index %d, queue id 0x%lx and port id 0x%lx.",
m_portAlias.c_str(),
m_queueId,
m_queue,
m_port);
}

void PfcWdActionHandler::initCounters(void)
Expand Down Expand Up @@ -211,7 +189,7 @@ PfcWdAclHandler::PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue,
{
SWSS_LOG_ENTER();

acl_table_type_t table_type = ACL_TABLE_L3;
acl_table_type_t table_type = ACL_TABLE_PFCWD;

// There is one handler instance per queue ID
string queuestr = to_string(queueId);
Expand All @@ -224,7 +202,7 @@ PfcWdAclHandler::PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue,
{
// First time of handling PFC for this queue, create ACL table, and bind
createPfcAclTable(port, m_strIngressTable, true);
shared_ptr<AclRuleL3> newRule = make_shared<AclRuleL3>(gAclOrch, m_strRule, m_strIngressTable, table_type);
shared_ptr<AclRulePfcwd> newRule = make_shared<AclRulePfcwd>(gAclOrch, m_strRule, m_strIngressTable, table_type);
createPfcAclRule(newRule, queueId, m_strIngressTable);
}
else
Expand All @@ -238,7 +216,7 @@ PfcWdAclHandler::PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue,
{
// First time of handling PFC for this queue, create ACL table, and bind
createPfcAclTable(port, m_strEgressTable, false);
shared_ptr<AclRuleL3> newRule = make_shared<AclRuleL3>(gAclOrch, m_strRule, m_strEgressTable, table_type);
shared_ptr<AclRulePfcwd> newRule = make_shared<AclRulePfcwd>(gAclOrch, m_strRule, m_strEgressTable, table_type);
createPfcAclRule(newRule, queueId, m_strEgressTable);
}
else
Expand Down Expand Up @@ -281,14 +259,14 @@ void PfcWdAclHandler::createPfcAclTable(sai_object_id_t port, string strTable, b
assert(inserted.second);

AclTable& aclTable = inserted.first->second;
aclTable.type = ACL_TABLE_L3;
aclTable.type = ACL_TABLE_PFCWD;
aclTable.link(port);
aclTable.id = strTable;
aclTable.stage = ingress ? ACL_STAGE_INGRESS : ACL_STAGE_EGRESS;
gAclOrch->addAclTable(aclTable, strTable);
}

void PfcWdAclHandler::createPfcAclRule(shared_ptr<AclRuleL3> rule, uint8_t queueId, string strTable)
void PfcWdAclHandler::createPfcAclRule(shared_ptr<AclRulePfcwd> rule, uint8_t queueId, string strTable)
{
SWSS_LOG_ENTER();

Expand Down Expand Up @@ -615,7 +593,7 @@ void PfcWdZeroBufferHandler::ZeroBufferProfile::createZeroBufferProfile(bool ing
attribs.push_back(attr);

attr.id = SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH;
attr.value.u32 = 1;
attr.value.u32 = -8; // ALPHA_0
attribs.push_back(attr);

status = sai_buffer_api->create_buffer_profile(
Expand Down
2 changes: 1 addition & 1 deletion orchagent/pfcactionhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class PfcWdAclHandler: public PfcWdLossyHandler
string m_strEgressTable;
string m_strRule;
void createPfcAclTable(sai_object_id_t port, string strTable, bool ingress);
void createPfcAclRule(shared_ptr<AclRuleL3> rule, uint8_t queueId, string strTable);
void createPfcAclRule(shared_ptr<AclRulePfcwd> rule, uint8_t queueId, string strTable);
};

// PFC queue that implements drop action by draining queue with buffer of zero size
Expand Down
Loading

0 comments on commit 0591513

Please sign in to comment.