Skip to content

Commit 0591513

Browse files
committed
Merge branch 'github-201803'
Conflicts: cfgmgr/buffermgr.cpp RB=1312100 G=lnos-reviewers R=pchaudha,pmao,rmolina,zxu A=
2 parents 9955bf3 + c374357 commit 0591513

15 files changed

+377
-73
lines changed

cfgmgr/buffermgr.cpp

+32-10
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,10 @@ void BufferMgr::readPgProfileLookupFile(string file)
7272
infile.close();
7373
}
7474

75-
void BufferMgr::doCableTask(string port, string cable_length)
75+
task_process_status BufferMgr::doCableTask(string port, string cable_length)
7676
{
7777
m_cableLenLookup[port] = cable_length;
78+
return task_process_status::task_success;
7879
}
7980

8081
string BufferMgr::getPgPoolMode()
@@ -108,7 +109,7 @@ Create/update two tables: profile (in m_cfgBufferProfileTable) and port buffer (
108109
}
109110
}
110111
*/
111-
void BufferMgr::doSpeedUpdateTask(string port, string speed)
112+
task_process_status BufferMgr::doSpeedUpdateTask(string port, string speed)
112113
{
113114
vector<FieldValueTuple> fvVector;
114115
string cable;
@@ -117,7 +118,7 @@ void BufferMgr::doSpeedUpdateTask(string port, string speed)
117118
{
118119
/* Set to NOTICE since cable length could be left empty */
119120
SWSS_LOG_NOTICE("Unable to create/update PG profile for port %s. Cable length is not set", port.c_str());
120-
return;
121+
return task_process_status::task_need_retry;
121122
}
122123

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

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

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

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

191193
string op = kfvOp(t);
194+
task_process_status task_status = task_process_status::task_success;
192195
if (op == SET_COMMAND)
193196
{
194197
for (auto i : kfvFieldsValues(t))
195198
{
196199
if (table_name == CFG_PORT_CABLE_LEN_TABLE_NAME)
197200
{
198201
// receive and cache cable length table
199-
doCableTask(fvField(i), fvValue(i));
202+
task_status = doCableTask(fvField(i), fvValue(i));
200203
}
201204
// In case of PORT table update, Buffer Manager is interested in speed update only
202205
if (table_name == CFG_PORT_TABLE_NAME && fvField(i) == "speed")
203206
{
204207
// create/update profile for port
205-
doSpeedUpdateTask(port, fvValue(i));
208+
task_status = doSpeedUpdateTask(port, fvValue(i));
209+
}
210+
if (task_status != task_process_status::task_success)
211+
{
212+
break;
206213
}
207214
}
208215
}
209216

210-
it = consumer.m_toSync.erase(it);
211-
continue;
217+
switch (task_status)
218+
{
219+
case task_process_status::task_failed:
220+
SWSS_LOG_ERROR("Failed to process table update");
221+
return;
222+
case task_process_status::task_need_retry:
223+
SWSS_LOG_INFO("Unable to process table update. Will retry...");
224+
++it;
225+
break;
226+
case task_process_status::task_invalid_entry:
227+
SWSS_LOG_ERROR("Failed to process invalid entry, drop it");
228+
it = consumer.m_toSync.erase(it);
229+
break;
230+
default:
231+
it = consumer.m_toSync.erase(it);
232+
break;
233+
}
212234
}
213235
}

cfgmgr/buffermgr.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class BufferMgr : public Orch
4444
port_cable_length_t m_cableLenLookup;
4545
std::string getPgPoolMode();
4646
void readPgProfileLookupFile(std::string);
47-
void doCableTask(string port, string cable_length);
48-
void doSpeedUpdateTask(string port, string speed);
47+
task_process_status doCableTask(string port, string cable_length);
48+
task_process_status doSpeedUpdateTask(string port, string speed);
4949

5050
void doTask(Consumer &consumer);
5151
};

orchagent/aclorch.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,11 @@ shared_ptr<AclRule> AclRule::makeShared(acl_table_type_t type, AclOrch *acl, Mir
498498
{
499499
return make_shared<AclRuleL3V6>(acl, rule, table, type);
500500
}
501+
/* Pfcwd rules can exist only in PFCWD table */
502+
else if (type == ACL_TABLE_PFCWD)
503+
{
504+
return make_shared<AclRulePfcwd>(acl, rule, table, type);
505+
}
501506

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

747+
748+
AclRulePfcwd::AclRulePfcwd(AclOrch *aclOrch, string rule, string table, acl_table_type_t type) :
749+
AclRuleL3(aclOrch, rule, table, type)
750+
{
751+
}
752+
753+
bool AclRulePfcwd::validateAddMatch(string attr_name, string attr_value)
754+
{
755+
if (attr_name != MATCH_TC)
756+
{
757+
SWSS_LOG_ERROR("%s is not supported for the tables of type Pfcwd", attr_name.c_str());
758+
return false;
759+
}
760+
761+
return AclRule::validateAddMatch(attr_name, attr_value);
762+
}
763+
742764
AclRuleL3V6::AclRuleL3V6(AclOrch *aclOrch, string rule, string table, acl_table_type_t type) :
743765
AclRuleL3(aclOrch, rule, table, type)
744766
{
@@ -761,6 +783,7 @@ bool AclRuleL3V6::validateAddMatch(string attr_name, string attr_value)
761783
return AclRule::validateAddMatch(attr_name, attr_value);
762784
}
763785

786+
764787
AclRuleMirror::AclRuleMirror(AclOrch *aclOrch, MirrorOrch *mirror, string rule, string table, acl_table_type_t type) :
765788
AclRule(aclOrch, rule, table, type),
766789
m_state(false),
@@ -971,6 +994,26 @@ bool AclTable::create()
971994
attr.value.s32list.list = bpoint_list.data();
972995
table_attrs.push_back(attr);
973996

997+
if (type == ACL_TABLE_PFCWD)
998+
{
999+
attr.id = SAI_ACL_TABLE_ATTR_FIELD_TC;
1000+
attr.value.booldata = true;
1001+
table_attrs.push_back(attr);
1002+
1003+
attr.id = SAI_ACL_TABLE_ATTR_ACL_STAGE;
1004+
attr.value.s32 = stage == ACL_STAGE_INGRESS ? SAI_ACL_STAGE_INGRESS : SAI_ACL_STAGE_EGRESS;
1005+
table_attrs.push_back(attr);
1006+
1007+
sai_status_t status = sai_acl_api->create_acl_table(&m_oid, gSwitchId, (uint32_t)table_attrs.size(), table_attrs.data());
1008+
1009+
if (status == SAI_STATUS_SUCCESS)
1010+
{
1011+
gCrmOrch->incCrmAclUsedCounter(CrmResourceType::CRM_ACL_TABLE, (sai_acl_stage_t) attr.value.s32, SAI_ACL_BIND_POINT_TYPE_PORT);
1012+
}
1013+
1014+
return status == SAI_STATUS_SUCCESS;
1015+
}
1016+
9741017
attr.id = SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE;
9751018
attr.value.booldata = true;
9761019
table_attrs.push_back(attr);

orchagent/aclorch.h

+10
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#define TABLE_TYPE_L3 "L3"
3030
#define TABLE_TYPE_L3V6 "L3V6"
3131
#define TABLE_TYPE_MIRROR "MIRROR"
32+
#define TABLE_TYPE_PFCWD "PFCWD"
3233
#define TABLE_TYPE_CTRLPLANE "CTRLPLANE"
3334

3435
#define RULE_PRIORITY "PRIORITY"
@@ -73,6 +74,7 @@ typedef enum
7374
ACL_TABLE_L3,
7475
ACL_TABLE_L3V6,
7576
ACL_TABLE_MIRROR,
77+
ACL_TABLE_PFCWD,
7678
ACL_TABLE_CTRLPLANE
7779
} acl_table_type_t;
7880

@@ -211,6 +213,14 @@ class AclRuleL3V6: public AclRuleL3
211213
bool validateAddMatch(string attr_name, string attr_value);
212214
};
213215

216+
class AclRulePfcwd: public AclRuleL3
217+
{
218+
public:
219+
AclRulePfcwd(AclOrch *m_pAclOrch, string rule, string table, acl_table_type_t type);
220+
bool validateAddMatch(string attr_name, string attr_value);
221+
};
222+
223+
214224
class AclRuleMirror: public AclRule
215225
{
216226
public:

orchagent/pfc_detect_broadcom.lua

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ for i = n, 1, -1 do
2121
local is_deadlock = false
2222
local pfc_wd_status = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_STATUS')
2323
local pfc_wd_action = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_ACTION')
24-
if pfc_wd_status == 'operational' or pfc_wd_action == 'alert' then
24+
local big_red_switch_mode = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'BIG_RED_SWITCH_MODE')
25+
if not big_red_switch_mode and (pfc_wd_status == 'operational' or pfc_wd_action == 'alert') then
2526
local detection_time = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_DETECTION_TIME')
2627
if detection_time then
2728
detection_time = tonumber(detection_time)

orchagent/pfc_detect_mellanox.lua

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ for i = n, 1, -1 do
2121
local is_deadlock = false
2222
local pfc_wd_status = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_STATUS')
2323
local pfc_wd_action = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_ACTION')
24-
if pfc_wd_status == 'operational' or pfc_wd_action == 'alert' then
24+
25+
local big_red_switch_mode = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'BIG_RED_SWITCH_MODE')
26+
if not big_red_switch_mode and (pfc_wd_status == 'operational' or pfc_wd_action == 'alert') then
2527
local detection_time = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_DETECTION_TIME')
2628
if detection_time then
2729
detection_time = tonumber(detection_time)

orchagent/pfc_restore.lua

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ for i = n, 1, -1 do
2020
local pfc_wd_status = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_STATUS')
2121
local restoration_time = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_RESTORATION_TIME')
2222
local pfc_wd_action = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_ACTION')
23-
if pfc_wd_status ~= 'operational' and pfc_wd_action ~= 'alert' and restoration_time and restoration_time ~= '' then
23+
local big_red_switch_mode = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'BIG_RED_SWITCH_MODE')
24+
if not big_red_switch_mode and pfc_wd_status ~= 'operational' and pfc_wd_action ~= 'alert' and restoration_time and restoration_time ~= '' then
2425
restoration_time = tonumber(restoration_time)
2526
local time_left = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_RESTORATION_TIME_LEFT')
26-
if time_left == nil then
27+
if not time_left then
2728
time_left = restoration_time
2829
else
2930
time_left = tonumber(time_left)

orchagent/pfcactionhandler.cpp

+6-28
Original file line numberDiff line numberDiff line change
@@ -37,34 +37,12 @@ PfcWdActionHandler::PfcWdActionHandler(sai_object_id_t port, sai_object_id_t que
3737
m_countersTable(countersTable)
3838
{
3939
SWSS_LOG_ENTER();
40-
41-
Port p;
42-
if (!gPortsOrch->getPort(port, p))
43-
{
44-
SWSS_LOG_ERROR("Unknown port id 0x%lx", port);
45-
}
46-
else
47-
{
48-
m_portAlias = p.m_alias;
49-
SWSS_LOG_NOTICE(
50-
"PFC Watchdog detected PFC storm on port %s, queue index %d, queue id 0x%lx and port id 0x%lx.",
51-
m_portAlias.c_str(),
52-
m_queueId,
53-
m_queue,
54-
m_port);
55-
}
5640
}
5741

5842
PfcWdActionHandler::~PfcWdActionHandler(void)
5943
{
6044
SWSS_LOG_ENTER();
6145

62-
SWSS_LOG_NOTICE(
63-
"PFC Watchdog storm restored on port %s, queue index %d, queue id 0x%lx and port id 0x%lx.",
64-
m_portAlias.c_str(),
65-
m_queueId,
66-
m_queue,
67-
m_port);
6846
}
6947

7048
void PfcWdActionHandler::initCounters(void)
@@ -211,7 +189,7 @@ PfcWdAclHandler::PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue,
211189
{
212190
SWSS_LOG_ENTER();
213191

214-
acl_table_type_t table_type = ACL_TABLE_L3;
192+
acl_table_type_t table_type = ACL_TABLE_PFCWD;
215193

216194
// There is one handler instance per queue ID
217195
string queuestr = to_string(queueId);
@@ -224,7 +202,7 @@ PfcWdAclHandler::PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue,
224202
{
225203
// First time of handling PFC for this queue, create ACL table, and bind
226204
createPfcAclTable(port, m_strIngressTable, true);
227-
shared_ptr<AclRuleL3> newRule = make_shared<AclRuleL3>(gAclOrch, m_strRule, m_strIngressTable, table_type);
205+
shared_ptr<AclRulePfcwd> newRule = make_shared<AclRulePfcwd>(gAclOrch, m_strRule, m_strIngressTable, table_type);
228206
createPfcAclRule(newRule, queueId, m_strIngressTable);
229207
}
230208
else
@@ -238,7 +216,7 @@ PfcWdAclHandler::PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue,
238216
{
239217
// First time of handling PFC for this queue, create ACL table, and bind
240218
createPfcAclTable(port, m_strEgressTable, false);
241-
shared_ptr<AclRuleL3> newRule = make_shared<AclRuleL3>(gAclOrch, m_strRule, m_strEgressTable, table_type);
219+
shared_ptr<AclRulePfcwd> newRule = make_shared<AclRulePfcwd>(gAclOrch, m_strRule, m_strEgressTable, table_type);
242220
createPfcAclRule(newRule, queueId, m_strEgressTable);
243221
}
244222
else
@@ -281,14 +259,14 @@ void PfcWdAclHandler::createPfcAclTable(sai_object_id_t port, string strTable, b
281259
assert(inserted.second);
282260

283261
AclTable& aclTable = inserted.first->second;
284-
aclTable.type = ACL_TABLE_L3;
262+
aclTable.type = ACL_TABLE_PFCWD;
285263
aclTable.link(port);
286264
aclTable.id = strTable;
287265
aclTable.stage = ingress ? ACL_STAGE_INGRESS : ACL_STAGE_EGRESS;
288266
gAclOrch->addAclTable(aclTable, strTable);
289267
}
290268

291-
void PfcWdAclHandler::createPfcAclRule(shared_ptr<AclRuleL3> rule, uint8_t queueId, string strTable)
269+
void PfcWdAclHandler::createPfcAclRule(shared_ptr<AclRulePfcwd> rule, uint8_t queueId, string strTable)
292270
{
293271
SWSS_LOG_ENTER();
294272

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

617595
attr.id = SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH;
618-
attr.value.u32 = 1;
596+
attr.value.u32 = -8; // ALPHA_0
619597
attribs.push_back(attr);
620598

621599
status = sai_buffer_api->create_buffer_profile(

orchagent/pfcactionhandler.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class PfcWdAclHandler: public PfcWdLossyHandler
111111
string m_strEgressTable;
112112
string m_strRule;
113113
void createPfcAclTable(sai_object_id_t port, string strTable, bool ingress);
114-
void createPfcAclRule(shared_ptr<AclRuleL3> rule, uint8_t queueId, string strTable);
114+
void createPfcAclRule(shared_ptr<AclRulePfcwd> rule, uint8_t queueId, string strTable);
115115
};
116116

117117
// PFC queue that implements drop action by draining queue with buffer of zero size

0 commit comments

Comments
 (0)