@@ -21,70 +21,81 @@ for i = n, 1, -1 do
21
21
local is_deadlock = false
22
22
local pfc_wd_status = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' PFC_WD_STATUS' )
23
23
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
25
- local detection_time = tonumber (redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' PFC_WD_DETECTION_TIME' ))
26
- local time_left = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' PFC_WD_DETECTION_TIME_LEFT' )
27
- if not time_left then
28
- time_left = detection_time
29
- else
30
- time_left = tonumber (time_left )
31
- end
32
24
33
- local queue_index = redis .call (' HGET' , ' COUNTERS_QUEUE_INDEX_MAP' , KEYS [i ])
34
- local port_id = redis .call (' HGET' , ' COUNTERS_QUEUE_PORT_MAP' , KEYS [i ])
35
- local pfc_rx_pkt_key = ' SAI_PORT_STAT_PFC_' .. queue_index .. ' _RX_PKTS'
36
- local pfc_on2off_key = ' SAI_PORT_STAT_PFC_' .. queue_index .. ' _ON2OFF_RX_PKTS'
37
-
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
27
+ local detection_time = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' PFC_WD_DETECTION_TIME' )
28
+ if detection_time then
29
+ detection_time = tonumber (detection_time )
30
+ local time_left = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' PFC_WD_DETECTION_TIME_LEFT' )
31
+ if not time_left then
32
+ time_left = detection_time
33
+ else
34
+ time_left = tonumber (time_left )
35
+ end
38
36
39
- -- Get all counters
40
- local occupancy_bytes = tonumber (redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_STAT_CURR_OCCUPANCY_BYTES' ))
41
- local packets = tonumber (redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_STAT_PACKETS' ))
42
- local pfc_rx_packets = tonumber (redis .call (' HGET' , counters_table_name .. ' :' .. port_id , pfc_rx_pkt_key ))
43
- local pfc_on2off = tonumber (redis .call (' HGET' , counters_table_name .. ' :' .. port_id , pfc_on2off_key ))
44
- local queue_pause_status = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_ATTR_PAUSE_STATUS' )
45
-
46
- local packets_last = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_STAT_PACKETS_last' )
47
- local pfc_rx_packets_last = redis .call (' HGET' , counters_table_name .. ' :' .. port_id , pfc_rx_pkt_key .. ' _last' )
48
- local pfc_on2off_last = redis .call (' HGET' , counters_table_name .. ' :' .. port_id , pfc_on2off_key .. ' _last' )
49
- local queue_pause_status_last = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_ATTR_PAUSE_STATUS_last' )
37
+ local queue_index = redis .call (' HGET' , ' COUNTERS_QUEUE_INDEX_MAP' , KEYS [i ])
38
+ local port_id = redis .call (' HGET' , ' COUNTERS_QUEUE_PORT_MAP' , KEYS [i ])
39
+ local pfc_rx_pkt_key = ' SAI_PORT_STAT_PFC_' .. queue_index .. ' _RX_PKTS'
40
+ local pfc_duration_key = ' SAI_PORT_STAT_PFC_' .. queue_index .. ' _RX_PAUSE_DURATION'
50
41
51
- -- DEBUG CODE START. Uncomment to enable
52
- local debug_storm = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' DEBUG_STORM' )
53
- -- DEBUG CODE END.
42
+ -- Get all counters
43
+ local occupancy_bytes = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_STAT_CURR_OCCUPANCY_BYTES' )
44
+ local packets = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_STAT_PACKETS' )
45
+ local pfc_rx_packets = redis .call (' HGET' , counters_table_name .. ' :' .. port_id , pfc_rx_pkt_key )
46
+ local pfc_duration = redis .call (' HGET' , counters_table_name .. ' :' .. port_id , pfc_duration_key )
54
47
55
- -- If this is not a first run, then we have last values available
56
- if packets_last and pfc_rx_packets_last and pfc_on2off_last and queue_pause_status_last then
57
- packets_last = tonumber (packets_last )
58
- pfc_rx_packets_last = tonumber (pfc_rx_packets_last )
59
- pfc_on2off_last = tonumber (pfc_on2off_last )
48
+ if occupancy_bytes and packets and pfc_rx_packets and pfc_duration then
49
+ occupancy_bytes = tonumber ( occupancy_bytes )
50
+ packets = tonumber (packets )
51
+ pfc_rx_packets = tonumber (pfc_rx_packets )
52
+ pfc_duration = tonumber (pfc_duration )
60
53
61
- -- Check actual condition of queue being in PFC storm
62
- if (occupancy_bytes > 0 and packets - packets_last == 0 and pfc_rx_packets - pfc_rx_packets_last > 0 ) or
54
+ local packets_last = redis .call (' HGET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_STAT_PACKETS_last' )
55
+ local pfc_rx_packets_last = redis .call (' HGET' , counters_table_name .. ' :' .. port_id , pfc_rx_pkt_key .. ' _last' )
56
+ local pfc_duration_last = redis .call (' HGET' , counters_table_name .. ' :' .. port_id , pfc_duration_key .. ' _last' )
63
57
-- DEBUG CODE START. Uncomment to enable
64
- ( debug_storm == " enabled " ) or
58
+ local debug_storm = redis . call ( ' HGET ' , counters_table_name .. ' : ' .. KEYS [ i ], ' DEBUG_STORM ' )
65
59
-- DEBUG CODE END.
66
- (occupancy_bytes == 0 and pfc_rx_packets - pfc_rx_packets_last > 0 and pfc_on2off - pfc_on2off_last == 0 and queue_pause_status_last == ' true' and queue_pause_status == ' true' ) then
67
- if time_left <= poll_time then
68
- redis .call (' PUBLISH' , ' PFC_WD_ACTION' , ' ["' .. KEYS [i ] .. ' ","storm"]' )
69
- is_deadlock = true
70
- time_left = detection_time
71
- else
72
- time_left = time_left - poll_time
60
+
61
+ -- If this is not a first run, then we have last values available
62
+ if packets_last and pfc_rx_packets_last and pfc_duration_last then
63
+ packets_last = tonumber (packets_last )
64
+ pfc_rx_packets_last = tonumber (pfc_rx_packets_last )
65
+ pfc_duration_last = tonumber (pfc_duration_last )
66
+
67
+ -- Check actual condition of queue being in PFC storm
68
+ if (occupancy_bytes > 0 and packets - packets_last == 0 and pfc_rx_packets - pfc_rx_packets_last > 0 ) or
69
+ -- DEBUG CODE START. Uncomment to enable
70
+ (debug_storm == " enabled" ) or
71
+ -- DEBUG CODE END.
72
+ (occupancy_bytes == 0 and packets - packets_last == 0 and (pfc_duration - pfc_duration_last ) > poll_time * 0.8 ) then
73
+ if time_left <= poll_time then
74
+ redis .call (' HDEL' , counters_table_name .. ' :' .. port_id , pfc_rx_pkt_key .. ' _last' )
75
+ redis .call (' HDEL' , counters_table_name .. ' :' .. port_id , pfc_duration_key .. ' _last' )
76
+ redis .call (' PUBLISH' , ' PFC_WD_ACTION' , ' ["' .. KEYS [i ] .. ' ","storm"]' )
77
+ is_deadlock = true
78
+ time_left = detection_time
79
+ else
80
+ time_left = time_left - poll_time
81
+ end
82
+ else
83
+ if pfc_wd_action == ' alert' and pfc_wd_status ~= ' operational' then
84
+ redis .call (' PUBLISH' , ' PFC_WD_ACTION' , ' ["' .. KEYS [i ] .. ' ","restore"]' )
85
+ end
86
+ time_left = detection_time
87
+ end
73
88
end
74
- else
75
- if pfc_wd_action == ' alert' and pfc_wd_status ~= ' operational' then
76
- redis .call (' PUBLISH' , ' PFC_WD_ACTION' , ' ["' .. KEYS [i ] .. ' ","restore"]' )
89
+
90
+ -- Save values for next run
91
+ redis .call (' HSET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_STAT_PACKETS_last' , packets )
92
+ redis .call (' HSET' , counters_table_name .. ' :' .. KEYS [i ], ' PFC_WD_DETECTION_TIME_LEFT' , time_left )
93
+ if is_deadlock == false then
94
+ redis .call (' HSET' , counters_table_name .. ' :' .. port_id , pfc_rx_pkt_key .. ' _last' , pfc_rx_packets )
95
+ redis .call (' HSET' , counters_table_name .. ' :' .. port_id , pfc_duration_key .. ' _last' , pfc_duration )
77
96
end
78
- time_left = detection_time
79
97
end
80
98
end
81
-
82
- -- Save values for next run
83
- redis .call (' HSET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_ATTR_PAUSE_STATUS_last' , queue_pause_status )
84
- redis .call (' HSET' , counters_table_name .. ' :' .. KEYS [i ], ' SAI_QUEUE_STAT_PACKETS_last' , packets )
85
- redis .call (' HSET' , counters_table_name .. ' :' .. KEYS [i ], ' PFC_WD_DETECTION_TIME_LEFT' , time_left )
86
- redis .call (' HSET' , counters_table_name .. ' :' .. port_id , pfc_rx_pkt_key .. ' _last' , pfc_rx_packets )
87
- redis .call (' HSET' , counters_table_name .. ' :' .. port_id , pfc_on2off_key .. ' _last' , pfc_on2off )
88
99
end
89
100
end
90
101
0 commit comments