forked from sonic-net/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cisco-8000 pfc-wd support (sonic-net#1748)
What I did Add support in sonic-swss for cisco-8000 to detect and recover the port/queue from pfc-wd events. **Why I did it Support for cisco-8000 platform for pfc-wd is missing in SONiC How I verified it interoperability with a Hardware based Traffic Generator to detect and recover the port/queue using the pfc-wd capability Details if related The support does the following: Uses SAI queue attributes for PFC-WD detection and recovery action Queues monitored querying SAI_QUEUE_ATTR_PAUSE_STATUS attribute on PFC-WD config On WD detection, initiate recovery using SAI_QUEUE_ATTR_PFC_DLR_INIT : Create PfcWdSaiDlrInitHandler object : ASIC configured to DROP packets for the queue When queue is out of pause state for restoration_time, restore queue state : ASIC configured to NOT DROP packets for the queue : Destroy PfcWdSaiDlrInitHandler object Signed-off-by: Venkat Garigipati <[email protected]>
- Loading branch information
1 parent
94d2d44
commit 1bacd10
Showing
9 changed files
with
269 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
-- KEYS - queue IDs | ||
-- ARGV[1] - counters db index | ||
-- ARGV[2] - counters table name | ||
-- ARGV[3] - poll time interval (milliseconds) | ||
-- return queue Ids that satisfy criteria | ||
|
||
local counters_db = ARGV[1] | ||
local counters_table_name = ARGV[2] | ||
local poll_time = tonumber(ARGV[3]) * 1000 | ||
|
||
local rets = {} | ||
|
||
redis.call('SELECT', counters_db) | ||
|
||
-- Iterate through each queue | ||
local n = table.getn(KEYS) | ||
for i = n, 1, -1 do | ||
local counter_keys = redis.call('HKEYS', counters_table_name .. ':' .. KEYS[i]) | ||
local counter_num = 0 | ||
local old_counter_num = 0 | ||
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') | ||
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) | ||
local time_left = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_DETECTION_TIME_LEFT') | ||
if not time_left then | ||
time_left = detection_time | ||
else | ||
time_left = tonumber(time_left) | ||
end | ||
|
||
local queue_index = redis.call('HGET', 'COUNTERS_QUEUE_INDEX_MAP', KEYS[i]) | ||
local port_id = redis.call('HGET', 'COUNTERS_QUEUE_PORT_MAP', KEYS[i]) | ||
|
||
-- Get PFC status | ||
local packets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_QUEUE_STAT_PACKETS') | ||
local queue_pause_status = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_QUEUE_ATTR_PAUSE_STATUS') | ||
|
||
if packets and queue_pause_status then | ||
|
||
-- DEBUG CODE START. Uncomment to enable | ||
local debug_storm = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'DEBUG_STORM') | ||
-- DEBUG CODE END. | ||
|
||
-- Check actual condition of queue being in PFC storm | ||
if (queue_pause_status == 'true') | ||
-- DEBUG CODE START. Uncomment to enable | ||
or (debug_storm == "enabled") | ||
-- DEBUG CODE END. | ||
then | ||
if time_left <= poll_time then | ||
redis.call('PUBLISH', 'PFC_WD_ACTION', '["' .. KEYS[i] .. '","storm"]') | ||
time_left = detection_time | ||
else | ||
time_left = time_left - poll_time | ||
end | ||
else | ||
if pfc_wd_action == 'alert' and pfc_wd_status ~= 'operational' then | ||
redis.call('PUBLISH', 'PFC_WD_ACTION', '["' .. KEYS[i] .. '","restore"]') | ||
end | ||
time_left = detection_time | ||
end | ||
|
||
-- Save values for next run | ||
redis.call('HSET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_DETECTION_TIME_LEFT', time_left) | ||
redis.call('HSET', counters_table_name .. ':' .. KEYS[i], 'SAI_QUEUE_ATTR_PAUSE_STATUS_last', queue_pause_status) | ||
redis.call('HSET', counters_table_name .. ':' .. KEYS[i], 'SAI_QUEUE_STAT_PACKETS_last', packets) | ||
end | ||
end | ||
end | ||
end | ||
|
||
return rets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
-- KEYS - queue IDs | ||
-- ARGV[1] - counters db index | ||
-- ARGV[2] - counters table name | ||
-- ARGV[3] - poll time interval (milliseconds) | ||
-- return queue Ids that satisfy criteria | ||
|
||
local counters_db = ARGV[1] | ||
local counters_table_name = ARGV[2] | ||
local poll_time = tonumber(ARGV[3]) * 1000 | ||
|
||
local rets = {} | ||
|
||
redis.call('SELECT', counters_db) | ||
|
||
-- Iterate through each queue | ||
local n = table.getn(KEYS) | ||
for i = n, 1, -1 do | ||
local counter_keys = redis.call('HKEYS', counters_table_name .. ':' .. KEYS[i]) | ||
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') | ||
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 not time_left then | ||
time_left = restoration_time | ||
else | ||
time_left = tonumber(time_left) | ||
end | ||
|
||
local queue_index = redis.call('HGET', 'COUNTERS_QUEUE_INDEX_MAP', KEYS[i]) | ||
local port_id = redis.call('HGET', 'COUNTERS_QUEUE_PORT_MAP', KEYS[i]) | ||
|
||
-- DEBUG CODE START. Uncomment to enable | ||
local debug_storm = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'DEBUG_STORM') | ||
-- DEBUG CODE END. | ||
|
||
-- Check actual condition of queue being restored from PFC storm | ||
local queue_pause_status = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_QUEUE_ATTR_PAUSE_STATUS') | ||
|
||
if (queue_pause_status == 'false') | ||
-- DEBUG CODE START. Uncomment to enable | ||
and (debug_storm ~= "enabled") | ||
-- DEBUG CODE END. | ||
then | ||
if time_left <= 0 then | ||
redis.call('PUBLISH', 'PFC_WD_ACTION', '["' .. KEYS[i] .. '","restore"]') | ||
time_left = restoration_time | ||
else | ||
time_left = time_left - poll_time | ||
end | ||
else | ||
time_left = restoration_time | ||
end | ||
|
||
-- Save values for next run | ||
redis.call('HSET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_RESTORATION_TIME_LEFT', time_left) | ||
end | ||
end | ||
|
||
return rets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters