-
Notifications
You must be signed in to change notification settings - Fork 520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[portsorch,intfsorch] add port, rif rates FC groups #1201
Changes from 6 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
-- KEYS - port IDs | ||
-- ARGV[1] - counters db index | ||
-- ARGV[2] - counters table name | ||
-- ARGV[3] - poll time interval | ||
-- return log | ||
|
||
local logtable = {} | ||
|
||
local function logit(msg) | ||
logtable[#logtable+1] = tostring(msg) | ||
end | ||
|
||
local counters_db = ARGV[1] | ||
local counters_table_name = ARGV[2] | ||
local rates_table_name = "RATES" | ||
|
||
-- Get configuration | ||
redis.call('SELECT', counters_db) | ||
local smooth_interval = redis.call('HGET', rates_table_name .. ':' .. 'PORT', 'PORT_SMOOTH_INTERVAL') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The table separator are from database_config.json. Do not hardcode. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not trivial to access the database config from the lua script. Should we pass the separator as one of the parameters? Some scripts have other dbs/table names hardcoded, and ATM receive the same ARGV. Need to suggest broad solution. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lua parameter is good enough. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @qiluo-msft Created issue #1319 |
||
local alpha = redis.call('HGET', rates_table_name .. ':' .. 'PORT', 'PORT_ALPHA') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this changes causes the following issue on latest SONiC master
Please double check. |
||
local one_minus_alpha = 1.0 - alpha | ||
local delta = tonumber(ARGV[3]) | ||
|
||
logit(alpha) | ||
logit(one_minus_alpha) | ||
logit(delta) | ||
|
||
local initialized = redis.call('HGET', rates_table_name, 'INIT_DONE') | ||
|
||
logit(initialized) | ||
|
||
for i = 1, n do | ||
-- Get new COUNTERS values | ||
local in_ucast_pkts = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_IN_UCAST_PKTS') | ||
local in_non_ucast_pkts = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_IN_NON_UCAST_PKTS') | ||
local out_ucast_pkts = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_OUT_UCAST_PKTS') | ||
local out_non_ucast_pkts = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_OUT_NON_UCAST_PKTS') | ||
local in_octets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_IN_OCTETS') | ||
local out_octets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_OUT_OCTETS') | ||
|
||
if initialized == 'DONE' or initialized == 'COUNTERS_LAST' then | ||
-- Get old COUNTERS values | ||
local in_ucast_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_IN_UCAST_PKTS_last') | ||
local in_non_ucast_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_IN_NON_UCAST_PKTS_last') | ||
local out_ucast_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_OUT_UCAST_PKTS_last') | ||
local out_non_ucast_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_OUT_NON_UCAST_PKTS_last') | ||
local in_octets_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_IN_OCTETS_last') | ||
local out_octets_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_OUT_OCTETS_last') | ||
|
||
-- Calculate new rates values | ||
local rx_bps_new = (in_octets - in_octets_last)/delta | ||
local tx_bps_new = (out_octets - out_octets_last)/delta | ||
local rx_pps_new = ((in_ucast_pkts + in_non_ucast_pkts) - (in_ucast_pkts_last + in_non_ucast_pkts_last))/delta | ||
local tx_pps_new = ((out_ucast_pkts + out_non_ucast_pkts) - (out_ucast_pkts_last + out_non_ucast_pkts_last))/delta | ||
|
||
if initialized == "DONE" then | ||
-- Get old rates values | ||
local rx_bps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'RX_BPS') | ||
local rx_pps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'RX_PPS') | ||
local tx_bps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'TX_BPS') | ||
local tx_pps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'TX_PPS') | ||
|
||
-- Smooth the rates values and store them in DB | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_BPS', alpha*rx_bps_new + one_minus_alpha*rx_bps_old) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_PPS', alpha*rx_pps_new + one_minus_alpha*rx_pps_old) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_BPS', alpha*tx_bps_new + one_minus_alpha*tx_bps_old) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_PPS', alpha*tx_pps_new + one_minus_alpha*tx_pps_old) | ||
else | ||
-- Store unsmoothed initial rates values in DB | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_BPS', rx_bps_new) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_PPS', rx_pps_new) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_BPS', tx_bps_new) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_PPS', tx_pps_new) | ||
redis.call('HSET', rates_table_name, 'INIT_DONE', 'DONE') | ||
end | ||
else | ||
-- Set old COUNTERS values | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_IN_UCAST_PKTS_last', in_ucast_pkts) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_IN_NON_UCAST_PKTS_last', in_non_ucast_pkts) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_OUT_UCAST_PKTS_last', out_ucast_pkts) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_OUT_NON_UCAST_PKTS_last', out_non_ucast_pkts) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_IN_OCTETS_last', in_octets) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_PORT_STAT_IF_OUT_OCTETS_last', out_octets) | ||
redis.call('HSET', rates_table_name, 'INIT_DONE', 'COUNTERS_LAST') | ||
end | ||
end | ||
|
||
return logtable |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,7 @@ extern BufferOrch *gBufferOrch; | |
#define QUEUE_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS 10000 | ||
#define QUEUE_WATERMARK_FLEX_STAT_COUNTER_POLL_MSECS "10000" | ||
#define PG_WATERMARK_FLEX_STAT_COUNTER_POLL_MSECS "10000" | ||
#define PORT_RATE_FLEX_COUNTER_POLLING_INTERVAL_MS "1000" | ||
|
||
|
||
static map<string, sai_port_fec_mode_t> fec_mode_map = | ||
|
@@ -185,6 +186,7 @@ PortsOrch::PortsOrch(DBConnector *db, vector<table_name_with_pri_t> &tableNames) | |
string queueWmSha, pgWmSha; | ||
string queueWmPluginName = "watermark_queue.lua"; | ||
string pgWmPluginName = "watermark_pg.lua"; | ||
string portRatePluginName = "port_rates.lua"; | ||
|
||
try | ||
{ | ||
|
@@ -194,6 +196,9 @@ PortsOrch::PortsOrch(DBConnector *db, vector<table_name_with_pri_t> &tableNames) | |
string pgLuaScript = swss::loadLuaScript(pgWmPluginName); | ||
pgWmSha = swss::loadRedisScript(m_counter_db.get(), pgLuaScript); | ||
|
||
string portRateLuaScript = swss::loadLuaScript(portRatePluginName); | ||
string portRateSha = swss::loadRedisScript(m_counter_db.get(), portRateLuaScript); | ||
|
||
vector<FieldValueTuple> fieldValues; | ||
fieldValues.emplace_back(QUEUE_PLUGIN_FIELD, queueWmSha); | ||
fieldValues.emplace_back(POLL_INTERVAL_FIELD, QUEUE_WATERMARK_FLEX_STAT_COUNTER_POLL_MSECS); | ||
|
@@ -205,10 +210,16 @@ PortsOrch::PortsOrch(DBConnector *db, vector<table_name_with_pri_t> &tableNames) | |
fieldValues.emplace_back(POLL_INTERVAL_FIELD, PG_WATERMARK_FLEX_STAT_COUNTER_POLL_MSECS); | ||
fieldValues.emplace_back(STATS_MODE_FIELD, STATS_MODE_READ_AND_CLEAR); | ||
m_flexCounterGroupTable->set(PG_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP, fieldValues); | ||
|
||
fieldValues.clear(); | ||
fieldValues.emplace_back(PORT_PLUGIN_FIELD, portRateSha); | ||
fieldValues.emplace_back(POLL_INTERVAL_FIELD, PORT_RATE_FLEX_COUNTER_POLLING_INTERVAL_MS); | ||
fieldValues.emplace_back(STATS_MODE_FIELD, STATS_MODE_READ); | ||
m_flexCounterGroupTable->set(PORT_STAT_COUNTER_FLEX_COUNTER_GROUP, fieldValues); | ||
} | ||
catch (const runtime_error &e) | ||
{ | ||
SWSS_LOG_ERROR("Watermark flex counter groups were not set successfully: %s", e.what()); | ||
SWSS_LOG_ERROR("Port flex counter groups were not set successfully: %s", e.what()); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. duplicated code #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Combined into one try block There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for misleading. I mean the code change is almost the same as in In reply to: 412570352 [](ancestors = 412570352) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest that I revert this particular change, |
||
|
||
uint32_t i, j; | ||
|
@@ -1503,15 +1514,13 @@ bool PortsOrch::initPort(const string &alias, const set<int> &lane_set) | |
vector<FieldValueTuple> fields; | ||
fields.push_back(tuple); | ||
m_counterTable->set("", fields); | ||
|
||
// Install a flex counter for this port to track stats | ||
std::unordered_set<std::string> counter_stats; | ||
for (const auto& it: port_stat_ids) | ||
{ | ||
counter_stats.emplace(sai_serialize_port_stat(it)); | ||
} | ||
port_stat_manager.setCounterIdList(p.m_port_id, CounterType::PORT, counter_stats); | ||
|
||
PortUpdate update = { p, true }; | ||
notify(SUBJECT_TYPE_PORT_CHANGE, static_cast<void *>(&update)); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
-- KEYS - rif IDs | ||
-- ARGV[1] - counters db index | ||
-- ARGV[2] - counters table name | ||
-- ARGV[3] - poll time interval | ||
-- return log | ||
|
||
local logtable = {} | ||
|
||
local function logit(msg) | ||
logtable[#logtable+1] = tostring(msg) | ||
end | ||
|
||
local counters_db = ARGV[1] | ||
local counters_table_name = ARGV[2] | ||
local rates_table_name = "RATES" | ||
|
||
-- Get configuration | ||
redis.call('SELECT', counters_db) | ||
local smooth_interval = redis.call('HGET', rates_table_name .. ':' .. 'RIF', 'RIF_SMOOTH_INTERVAL') | ||
local alpha = redis.call('HGET', rates_table_name .. ':' .. 'RIF', 'RIF_ALPHA') | ||
local one_minus_alpha = 1.0 - alpha | ||
local delta = tonumber(ARGV[3]) | ||
|
||
local initialized = redis.call('HGET', rates_table_name, 'INIT_DONE') | ||
logit(initialized) | ||
|
||
for i = 1, n do | ||
-- Get new COUNTERS values | ||
local in_octets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_IN_OCTETS') | ||
local in_pkts = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_IN_PACKETS') | ||
local out_octets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_OUT_OCTETS') | ||
local out_pkts = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_OUT_PACKETS') | ||
|
||
if initialized == "DONE" or initialized == "COUNTERS_LAST" then | ||
-- Get old COUNTERS values | ||
local in_octets_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_IN_OCTETS_last') | ||
local in_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_IN_PACKETS_last') | ||
local out_octets_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_OUT_OCTETS_last') | ||
local out_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_OUT_PACKETS_last') | ||
|
||
-- Calculate new rates values | ||
local rx_bps_new = (in_octets - in_octets_last)/delta | ||
local tx_bps_new = (out_octets - out_octets_last)/delta | ||
local rx_pps_new = (in_pkts - in_pkts_last)/delta | ||
local tx_pps_new = (out_pkts - out_pkts_last)/delta | ||
|
||
if initialized == "DONE" then | ||
-- Get old rates values | ||
local rx_bps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'RX_BPS') | ||
local rx_pps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'RX_PPS') | ||
local tx_bps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'TX_BPS') | ||
local tx_pps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'TX_PPS') | ||
|
||
-- Smooth the rates values and store them in DB | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_BPS', alpha*rx_bps_new + one_minus_alpha*rx_bps_old) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_PPS', alpha*rx_pps_new + one_minus_alpha*rx_pps_old) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_BPS', alpha*tx_bps_new + one_minus_alpha*tx_bps_old) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_PPS', alpha*tx_pps_new + one_minus_alpha*tx_pps_old) | ||
else | ||
-- Store unsmoothed initial rates values in DB | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_BPS', rx_bps_new) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_PPS', rx_pps_new) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_BPS', tx_bps_new) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_PPS', tx_pps_new) | ||
redis.call('HSET', rates_table_name, 'INIT_DONE', 'DONE') | ||
end | ||
else | ||
-- Set old COUNTERS values | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_IN_OCTETS_last', in_octets) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_IN_PACKETS_last', in_pkts) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_OUT_OCTETS_last', out_octets) | ||
redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_ROUTER_INTERFACE_STAT_OUT_PACKETS_last', out_pkts) | ||
redis.call('HSET', rates_table_name, 'INIT_DONE', 'COUNTERS_LAST') | ||
end | ||
end | ||
|
||
return logtable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
above line uses RouterIntfs, here uses Rif. Are they different? #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latter refers to RIF_RATE Flex Counter group instead of Router Interface.