Skip to content

Commit 8af6462

Browse files
authored
Merge branch 'master' into master
2 parents a2fc65b + 60433c7 commit 8af6462

File tree

6 files changed

+137
-4
lines changed

6 files changed

+137
-4
lines changed

orchagent/flexcounterorch.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ void FlexCounterOrch::doTask(Consumer &consumer)
118118
{
119119
auto itDelay = std::find(std::begin(data), std::end(data), FieldValueTuple(FLEX_COUNTER_DELAY_STATUS_FIELD, "true"));
120120
string poll_interval;
121+
string bulk_chunk_size;
122+
string bulk_chunk_size_per_counter;
121123

122124
if (itDelay != data.end())
123125
{
@@ -141,6 +143,14 @@ void FlexCounterOrch::doTask(Consumer &consumer)
141143
}
142144
}
143145
}
146+
else if (field == BULK_CHUNK_SIZE_FIELD)
147+
{
148+
bulk_chunk_size = value;
149+
}
150+
else if (field == BULK_CHUNK_SIZE_PER_PREFIX_FIELD)
151+
{
152+
bulk_chunk_size_per_counter = value;
153+
}
144154
else if(field == FLEX_COUNTER_STATUS_FIELD)
145155
{
146156
// Currently, the counters are disabled for polling by default
@@ -256,6 +266,19 @@ void FlexCounterOrch::doTask(Consumer &consumer)
256266
SWSS_LOG_NOTICE("Unsupported field %s", field.c_str());
257267
}
258268
}
269+
270+
if (!bulk_chunk_size.empty() || !bulk_chunk_size_per_counter.empty())
271+
{
272+
m_groupsWithBulkChunkSize.insert(key);
273+
setFlexCounterGroupBulkChunkSize(flexCounterGroupMap[key],
274+
bulk_chunk_size.empty() ? "NULL" : bulk_chunk_size,
275+
bulk_chunk_size_per_counter.empty() ? "NULL" : bulk_chunk_size_per_counter);
276+
}
277+
else if (m_groupsWithBulkChunkSize.find(key) != m_groupsWithBulkChunkSize.end())
278+
{
279+
setFlexCounterGroupBulkChunkSize(flexCounterGroupMap[key], "NULL", "NULL");
280+
m_groupsWithBulkChunkSize.erase(key);
281+
}
259282
}
260283

261284
consumer.m_toSync.erase(it++);

orchagent/flexcounterorch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class FlexCounterOrch: public Orch
6767
Table m_bufferQueueConfigTable;
6868
Table m_bufferPgConfigTable;
6969
Table m_deviceMetadataConfigTable;
70+
std::unordered_set<std::string> m_groupsWithBulkChunkSize;
7071
};
7172

7273
#endif

orchagent/pfc_detect_mellanox.lua

100644100755
Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,20 @@ local timestamp_struct = redis.call('TIME')
1818
local timestamp_current = timestamp_struct[1] + timestamp_struct[2] / 1000000
1919
local timestamp_string = tostring(timestamp_current)
2020
redis.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')
2323
if 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)
2626
end
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
2936
local n = table.getn(KEYS)
3037
for 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

orchagent/saihelper.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,8 @@ static inline void initSaiRedisCounterEmptyParameter(sai_redis_flex_counter_grou
854854
initSaiRedisCounterEmptyParameter(flex_counter_group_param.stats_mode);
855855
initSaiRedisCounterEmptyParameter(flex_counter_group_param.plugin_name);
856856
initSaiRedisCounterEmptyParameter(flex_counter_group_param.plugins);
857+
initSaiRedisCounterEmptyParameter(flex_counter_group_param.bulk_chunk_size);
858+
initSaiRedisCounterEmptyParameter(flex_counter_group_param.bulk_chunk_size_per_prefix);
857859
}
858860

859861
static inline void initSaiRedisCounterParameterFromString(sai_s8_list_t &sai_s8_list, const std::string &str)
@@ -938,6 +940,8 @@ void setFlexCounterGroupParameter(const string &group,
938940
attr.id = SAI_REDIS_SWITCH_ATTR_FLEX_COUNTER_GROUP;
939941
attr.value.ptr = &flex_counter_group_param;
940942

943+
initSaiRedisCounterEmptyParameter(flex_counter_group_param.bulk_chunk_size);
944+
initSaiRedisCounterEmptyParameter(flex_counter_group_param.bulk_chunk_size_per_prefix);
941945
initSaiRedisCounterParameterFromString(flex_counter_group_param.counter_group_name, group);
942946
initSaiRedisCounterParameterFromString(flex_counter_group_param.poll_interval, poll_interval);
943947
initSaiRedisCounterParameterFromString(flex_counter_group_param.operation, operation);
@@ -1017,6 +1021,25 @@ void setFlexCounterGroupStatsMode(const std::string &group,
10171021
notifySyncdCounterOperation(is_gearbox, attr);
10181022
}
10191023

1024+
void setFlexCounterGroupBulkChunkSize(const std::string &group,
1025+
const std::string &bulk_chunk_size,
1026+
const std::string &bulk_chunk_size_per_prefix,
1027+
bool is_gearbox)
1028+
{
1029+
sai_attribute_t attr;
1030+
sai_redis_flex_counter_group_parameter_t flex_counter_group_param;
1031+
1032+
attr.id = SAI_REDIS_SWITCH_ATTR_FLEX_COUNTER_GROUP;
1033+
attr.value.ptr = &flex_counter_group_param;
1034+
1035+
initSaiRedisCounterEmptyParameter(flex_counter_group_param);
1036+
initSaiRedisCounterParameterFromString(flex_counter_group_param.counter_group_name, group);
1037+
initSaiRedisCounterParameterFromString(flex_counter_group_param.bulk_chunk_size, bulk_chunk_size);
1038+
initSaiRedisCounterParameterFromString(flex_counter_group_param.bulk_chunk_size_per_prefix, bulk_chunk_size_per_prefix);
1039+
1040+
notifySyncdCounterOperation(is_gearbox, attr);
1041+
}
1042+
10201043
void delFlexCounterGroup(const std::string &group,
10211044
bool is_gearbox)
10221045
{

orchagent/saihelper.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ void setFlexCounterGroupStatsMode(const std::string &group,
3939
const std::string &stats_mode,
4040
bool is_gearbox=false);
4141

42+
void setFlexCounterGroupBulkChunkSize(const std::string &group,
43+
const std::string &bulk_size,
44+
const std::string &bulk_chunk_size_per_prefix,
45+
bool is_gearbox=false);
46+
4247
void delFlexCounterGroup(const std::string &group,
4348
bool is_gearbox=false);
4449

tests/mock_tests/flexcounter_ut.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ namespace flexcounter_test
111111
}
112112
else
113113
{
114+
if (flexCounterGroupParam->bulk_chunk_size.list != nullptr || flexCounterGroupParam->bulk_chunk_size_per_prefix.list != nullptr)
115+
{
116+
return SAI_STATUS_SUCCESS;
117+
}
114118
mockFlexCounterGroupTable->del(key);
115119
}
116120

@@ -824,6 +828,47 @@ namespace flexcounter_test
824828
consumer->addToSync(entries);
825829
entries.clear();
826830
static_cast<Orch *>(gBufferOrch)->doTask();
831+
832+
if (!gTraditionalFlexCounter)
833+
{
834+
// Verify bulk chunk size fields which can be verified in any combination of parameters.
835+
// We verify it here just for convenience.
836+
consumer = dynamic_cast<Consumer *>(flexCounterOrch->getExecutor(CFG_FLEX_COUNTER_TABLE_NAME));
837+
838+
entries.push_back({"PORT", "SET", {
839+
{"FLEX_COUNTER_STATUS", "enable"},
840+
{"BULK_CHUNK_SIZE", "64"}
841+
}});
842+
consumer->addToSync(entries);
843+
entries.clear();
844+
static_cast<Orch *>(flexCounterOrch)->doTask();
845+
ASSERT_TRUE(flexCounterOrch->m_groupsWithBulkChunkSize.find("PORT") != flexCounterOrch->m_groupsWithBulkChunkSize.end());
846+
847+
entries.push_back({"PORT", "SET", {
848+
{"FLEX_COUNTER_STATUS", "enable"}
849+
}});
850+
consumer->addToSync(entries);
851+
entries.clear();
852+
static_cast<Orch *>(flexCounterOrch)->doTask();
853+
ASSERT_EQ(flexCounterOrch->m_groupsWithBulkChunkSize.find("PORT"), flexCounterOrch->m_groupsWithBulkChunkSize.end());
854+
855+
entries.push_back({"PORT", "SET", {
856+
{"FLEX_COUNTER_STATUS", "enable"},
857+
{"BULK_CHUNK_SIZE_PER_PREFIX", "SAI_PORT_STAT_IF_OUT_QLEN:0;SAI_PORT_STAT_IF_IN_FEC:32"}
858+
}});
859+
consumer->addToSync(entries);
860+
entries.clear();
861+
static_cast<Orch *>(flexCounterOrch)->doTask();
862+
ASSERT_TRUE(flexCounterOrch->m_groupsWithBulkChunkSize.find("PORT") != flexCounterOrch->m_groupsWithBulkChunkSize.end());
863+
864+
entries.push_back({"PORT", "SET", {
865+
{"FLEX_COUNTER_STATUS", "enable"}
866+
}});
867+
consumer->addToSync(entries);
868+
entries.clear();
869+
static_cast<Orch *>(flexCounterOrch)->doTask();
870+
ASSERT_EQ(flexCounterOrch->m_groupsWithBulkChunkSize.find("PORT"), flexCounterOrch->m_groupsWithBulkChunkSize.end());
871+
}
827872
}
828873

829874
// Remove buffer pools

0 commit comments

Comments
 (0)