From e8c2b1f54555d86bec5f6f989665cf76d5cfac4c Mon Sep 17 00:00:00 2001 From: songqh2022 Date: Tue, 26 Jul 2022 19:36:57 +0800 Subject: [PATCH 1/4] Support for platforms based on Clounix Networks' device --- orchagent/Makefile.am | 1 + orchagent/aclorch.cpp | 4 +- orchagent/orch.h | 1 + orchagent/orchdaemon.cpp | 4 +- orchagent/pfc_detect_clounix.lua | 99 ++++++++++++++++++++++++++++++++ 5 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 orchagent/pfc_detect_clounix.lua diff --git a/orchagent/Makefile.am b/orchagent/Makefile.am index f1160c4da1..2a211f4ce5 100644 --- a/orchagent/Makefile.am +++ b/orchagent/Makefile.am @@ -8,6 +8,7 @@ dist_swss_DATA = \ rif_rates.lua \ pfc_detect_innovium.lua \ pfc_detect_mellanox.lua \ + pfc_detect_clounix.lua \ pfc_detect_broadcom.lua \ pfc_detect_barefoot.lua \ pfc_detect_nephos.lua \ diff --git a/orchagent/aclorch.cpp b/orchagent/aclorch.cpp index d7121e7ee7..9a3717f42a 100644 --- a/orchagent/aclorch.cpp +++ b/orchagent/aclorch.cpp @@ -2243,6 +2243,7 @@ void AclOrch::init(vector& connectors, PortsOrch *portOrch, Mirr platform == CISCO_8000_PLATFORM_SUBSTRING || platform == MLNX_PLATFORM_SUBSTRING || platform == BFN_PLATFORM_SUBSTRING || + platform == CLX_PLATFORM_SUBSTRING || platform == MRVL_PLATFORM_SUBSTRING || platform == INVM_PLATFORM_SUBSTRING || platform == NPS_PLATFORM_SUBSTRING) @@ -2279,7 +2280,8 @@ void AclOrch::init(vector& connectors, PortsOrch *portOrch, Mirr // In Mellanox platform, V4 and V6 rules are stored in different tables if (platform == MLNX_PLATFORM_SUBSTRING || platform == CISCO_8000_PLATFORM_SUBSTRING || - platform == MRVL_PLATFORM_SUBSTRING) { + platform == MRVL_PLATFORM_SUBSTRING || + platform == CLX_PLATFORM_SUBSTRING)) { m_isCombinedMirrorV6Table = false; } diff --git a/orchagent/orch.h b/orchagent/orch.h index 610e93590e..0485908a10 100644 --- a/orchagent/orch.h +++ b/orchagent/orch.h @@ -38,6 +38,7 @@ const char state_db_key_delimiter = '|'; #define NPS_PLATFORM_SUBSTRING "nephos" #define MRVL_PLATFORM_SUBSTRING "marvell" #define CISCO_8000_PLATFORM_SUBSTRING "cisco-8000" +#define CLX_PLATFORM_SUBSTRING "clounix" #define CONFIGDB_KEY_SEPARATOR "|" #define DEFAULT_KEY_SEPARATOR ":" diff --git a/orchagent/orchdaemon.cpp b/orchagent/orchdaemon.cpp index 62152e103b..e67d591a82 100644 --- a/orchagent/orchdaemon.cpp +++ b/orchagent/orchdaemon.cpp @@ -384,6 +384,7 @@ bool OrchDaemon::init() PFC_WD_POLL_MSECS)); } else if ((platform == INVM_PLATFORM_SUBSTRING) + || (platform == CLX_PLATFORM_SUBSTRING) || (platform == BFN_PLATFORM_SUBSTRING) || (platform == NPS_PLATFORM_SUBSTRING)) { @@ -416,7 +417,8 @@ bool OrchDaemon::init() static const vector queueAttrIds; - if ((platform == INVM_PLATFORM_SUBSTRING) || (platform == NPS_PLATFORM_SUBSTRING)) + if ((platform == INVM_PLATFORM_SUBSTRING) || (platform == NPS_PLATFORM_SUBSTRING) + || (platform == CLX_PLATFORM_SUBSTRING)) { m_orchList.push_back(new PfcWdSwOrch( m_configDb, diff --git a/orchagent/pfc_detect_clounix.lua b/orchagent/pfc_detect_clounix.lua new file mode 100644 index 0000000000..72f1cbea94 --- /dev/null +++ b/orchagent/pfc_detect_clounix.lua @@ -0,0 +1,99 @@ +-- 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 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') + 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]) + local pfc_rx_pkt_key = 'SAI_PORT_STAT_PFC_' .. queue_index .. '_RX_PKTS' + local pfc_duration_key = 'SAI_PORT_STAT_PFC_' .. queue_index .. '_RX_PAUSE_DURATION' + + -- Get all counters + local occupancy_bytes = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_QUEUE_STAT_CURR_OCCUPANCY_BYTES') + local packets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_QUEUE_STAT_PACKETS') + local pfc_rx_packets = redis.call('HGET', counters_table_name .. ':' .. port_id, pfc_rx_pkt_key) + local pfc_duration = redis.call('HGET', counters_table_name .. ':' .. port_id, pfc_duration_key) + + if occupancy_bytes and packets and pfc_rx_packets and pfc_duration then + occupancy_bytes = tonumber(occupancy_bytes) + packets = tonumber(packets) + pfc_rx_packets = tonumber(pfc_rx_packets) + pfc_duration = tonumber(pfc_duration) + + local packets_last = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_QUEUE_STAT_PACKETS_last') + local pfc_rx_packets_last = redis.call('HGET', counters_table_name .. ':' .. port_id, pfc_rx_pkt_key .. '_last') + local pfc_duration_last = redis.call('HGET', counters_table_name .. ':' .. port_id, pfc_duration_key .. '_last') + -- DEBUG CODE START. Uncomment to enable + local debug_storm = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'DEBUG_STORM') + -- DEBUG CODE END. + + -- If this is not a first run, then we have last values available + if packets_last and pfc_rx_packets_last and pfc_duration_last then + packets_last = tonumber(packets_last) + pfc_rx_packets_last = tonumber(pfc_rx_packets_last) + pfc_duration_last = tonumber(pfc_duration_last) + + -- Check actual condition of queue being in PFC storm + if (occupancy_bytes > 0 and packets - packets_last == 0 and pfc_rx_packets - pfc_rx_packets_last > 0) or + -- DEBUG CODE START. Uncomment to enable + (debug_storm == "enabled") or + -- DEBUG CODE END. + (occupancy_bytes == 0 and packets - packets_last == 0 and (pfc_duration - pfc_duration_last) > poll_time * 0.8) then + if time_left <= poll_time then + redis.call('PUBLISH', 'PFC_WD_ACTION', '["' .. KEYS[i] .. '","storm"]') + is_deadlock = true + 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 + end + + -- Save values for next run + redis.call('HSET', counters_table_name .. ':' .. KEYS[i], 'SAI_QUEUE_STAT_PACKETS_last', packets) + redis.call('HSET', counters_table_name .. ':' .. KEYS[i], 'PFC_WD_DETECTION_TIME_LEFT', time_left) + redis.call('HSET', counters_table_name .. ':' .. port_id, pfc_rx_pkt_key .. '_last', pfc_rx_packets) + redis.call('HDEL', counters_table_name .. ':' .. port_id, pfc_duration_key .. '_last') + redis.call('HSET', counters_table_name .. ':' .. port_id, pfc_duration_key .. '_last', pfc_duration) + end + end + end +end + +return rets + From 2bddb7f670a477c31633eb671e281f3d9dc6a043 Mon Sep 17 00:00:00 2001 From: songqh2022 <101690279+songqh2022@users.noreply.github.com> Date: Tue, 26 Jul 2022 19:46:21 +0800 Subject: [PATCH 2/4] Update aclorch.cpp --- orchagent/aclorch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orchagent/aclorch.cpp b/orchagent/aclorch.cpp index 9a3717f42a..d7f87daa30 100644 --- a/orchagent/aclorch.cpp +++ b/orchagent/aclorch.cpp @@ -2281,7 +2281,7 @@ void AclOrch::init(vector& connectors, PortsOrch *portOrch, Mirr if (platform == MLNX_PLATFORM_SUBSTRING || platform == CISCO_8000_PLATFORM_SUBSTRING || platform == MRVL_PLATFORM_SUBSTRING || - platform == CLX_PLATFORM_SUBSTRING)) { + platform == CLX_PLATFORM_SUBSTRING)) { m_isCombinedMirrorV6Table = false; } From a60e770ee9b5ed94f353c98ee68dfa2e6b61f862 Mon Sep 17 00:00:00 2001 From: songqh2022 <101690279+songqh2022@users.noreply.github.com> Date: Tue, 26 Jul 2022 19:49:16 +0800 Subject: [PATCH 3/4] Update orchdaemon.cpp --- orchagent/orchdaemon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orchagent/orchdaemon.cpp b/orchagent/orchdaemon.cpp index e67d591a82..dad916f1a9 100644 --- a/orchagent/orchdaemon.cpp +++ b/orchagent/orchdaemon.cpp @@ -418,7 +418,7 @@ bool OrchDaemon::init() static const vector queueAttrIds; if ((platform == INVM_PLATFORM_SUBSTRING) || (platform == NPS_PLATFORM_SUBSTRING) - || (platform == CLX_PLATFORM_SUBSTRING)) + || (platform == CLX_PLATFORM_SUBSTRING)) { m_orchList.push_back(new PfcWdSwOrch( m_configDb, From a12a40508312d6393e888b2b201c99ce63505554 Mon Sep 17 00:00:00 2001 From: songqh2022 <101690279+songqh2022@users.noreply.github.com> Date: Wed, 27 Jul 2022 19:04:25 +0800 Subject: [PATCH 4/4] Update aclorch.cpp --- orchagent/aclorch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orchagent/aclorch.cpp b/orchagent/aclorch.cpp index d7f87daa30..854e0f6a88 100644 --- a/orchagent/aclorch.cpp +++ b/orchagent/aclorch.cpp @@ -2281,7 +2281,7 @@ void AclOrch::init(vector& connectors, PortsOrch *portOrch, Mirr if (platform == MLNX_PLATFORM_SUBSTRING || platform == CISCO_8000_PLATFORM_SUBSTRING || platform == MRVL_PLATFORM_SUBSTRING || - platform == CLX_PLATFORM_SUBSTRING)) { + platform == CLX_PLATFORM_SUBSTRING) { m_isCombinedMirrorV6Table = false; }