@@ -18,13 +18,20 @@ local timestamp_struct = redis.call('TIME')
1818local timestamp_current = timestamp_struct [1 ] + timestamp_struct [2 ] / 1000000
1919local timestamp_string = tostring (timestamp_current )
2020redis .call (' HSET' , ' TIMESTAMP' , ' pfcwd_poll_timestamp_last' , timestamp_string )
21- local effective_poll_time = poll_time
22- local effective_poll_time_lasttime = redis .call (' HGET' , ' TIMESTAMP' , ' effective_pfcwd_poll_time_last' )
21+ local global_effective_poll_time = poll_time
22+ local global_effective_poll_time_lasttime = redis .call (' HGET' , ' TIMESTAMP' , ' effective_pfcwd_poll_time_last' )
2323if timestamp_last ~= false then
24- effective_poll_time = (timestamp_current - tonumber (timestamp_last )) * 1000000
25- redis .call (' HSET' , ' TIMESTAMP' , ' effective_pfcwd_poll_time_last' , effective_poll_time )
24+ global_effective_poll_time = (timestamp_current - tonumber (timestamp_last )) * 1000000
25+ redis .call (' HSET' , ' TIMESTAMP' , ' effective_pfcwd_poll_time_last' , global_effective_poll_time )
2626end
2727
28+ local effective_poll_time
29+ local effective_poll_time_lasttime
30+ local port_timestamp_last_cache = {}
31+
32+ local debug_storm_global = redis .call (' HGET' , ' DEBUG_STORM' , ' enabled' ) == ' true'
33+ local debug_storm_threshold = tonumber (redis .call (' HGET' , ' DEBUG_STORM' , ' threshold' ))
34+
2835-- Iterate through each queue
2936local n = table .getn (KEYS )
3037for i = n , 1 , - 1 do
@@ -56,12 +63,37 @@ for i = n, 1, -1 do
5663 local pfc_rx_pkt_key = ' SAI_PORT_STAT_PFC_' .. queue_index .. ' _RX_PKTS'
5764 local pfc_duration_key = ' SAI_PORT_STAT_PFC_' .. queue_index .. ' _RX_PAUSE_DURATION_US'
5865
66+ -- Get port specific timestamp
67+ local port_timestamp_current = tonumber (redis .call (' HGET' , counters_table_name .. ' :' .. port_id , ' PFC_WD_time_stamp' ))
68+ if port_timestamp_current ~= nil then
69+ local port_timestamp_lasttime = port_timestamp_last_cache [port_id ]
70+ if port_timestamp_lasttime == nil then
71+ port_timestamp_lasttime = tonumber (redis .call (' HGET' , counters_table_name .. ' :' .. port_id , ' PFC_WD_time_stamp_last' ))
72+ port_timestamp_last_cache [port_id ] = port_timestamp_lasttime
73+ redis .call (' HSET' , counters_table_name .. ' :' .. port_id , ' PFC_WD_time_stamp_last' , port_timestamp_current )
74+ end
75+
76+ if port_timestamp_lasttime ~= nil then
77+ effective_poll_time = (port_timestamp_current - port_timestamp_lasttime ) / 1000
78+ else
79+ effective_poll_time = global_effective_poll_time
80+ end
81+ effective_poll_time_lasttime = false
82+ else
83+ effective_poll_time = global_effective_poll_time
84+ effective_poll_time_lasttime = global_effective_poll_time_lasttime
85+ end
86+
5987 -- Get all counters
6088 local occupancy_bytes = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_STAT_CURR_OCCUPANCY_BYTES' )
6189 local packets = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_STAT_PACKETS' )
6290 local pfc_rx_packets = redis .call (' HGET' , counters_table_name .. ' :' .. port_id , pfc_rx_pkt_key )
6391 local pfc_duration = redis .call (' HGET' , counters_table_name .. ' :' .. port_id , pfc_duration_key )
6492
93+ if debug_storm_global then
94+ redis .call (' PUBLISH' , ' PFC_WD_DEBUG' , ' Port ID ' .. port_id .. ' Queue index ' .. queue_index .. ' occupancy ' .. occupancy_bytes .. ' packets ' .. packets .. ' pfc rx ' .. pfc_rx_packets .. ' pfc duration ' .. pfc_duration .. ' effective poll time ' .. tostring (effective_poll_time ) .. ' (global ' .. tostring (global_effective_poll_time ) .. ' )' )
95+ end
96+
6597 if occupancy_bytes and packets and pfc_rx_packets and pfc_duration then
6698 occupancy_bytes = tonumber (occupancy_bytes )
6799 packets = tonumber (packets )
@@ -82,6 +114,10 @@ for i = n, 1, -1 do
82114 pfc_duration_last = tonumber (pfc_duration_last )
83115 local storm_condition = (pfc_duration - pfc_duration_last ) > (effective_poll_time * 0.99 )
84116
117+ if debug_storm_threshold ~= nil and (pfc_duration - pfc_duration_last ) > (effective_poll_time * debug_storm_threshold / 100 ) then
118+ redis .call (' PUBLISH' , ' PFC_WD_DEBUG' , ' Port ID ' .. port_id .. ' Queue index ' .. queue_index .. ' occupancy ' .. occupancy_bytes .. ' packets ' .. packets .. ' pfc rx ' .. pfc_rx_packets .. ' pfc duration ' .. pfc_duration .. ' effective poll time ' .. tostring (effective_poll_time ) .. ' , triggered by threshold ' .. debug_storm_threshold .. ' %' )
119+ end
120+
85121 -- Check actual condition of queue being in PFC storm
86122 if (occupancy_bytes > 0 and packets - packets_last == 0 and storm_condition ) or
87123 -- DEBUG CODE START. Uncomment to enable
0 commit comments