From 72bc218b854dee6540ffb214457c8f8aaf4968eb Mon Sep 17 00:00:00 2001 From: Andriy Yurkiv <70649192+ayurkiv-nvda@users.noreply.github.com> Date: Wed, 17 Feb 2021 02:56:34 +0200 Subject: [PATCH] Add SAI_INGRESS_PRIORITY_GROUP_STAT_DROPPED_PACKETS counter, create new FlexCounter group (#1600) Signed-off-by: Andriy Yurkiv depends on : Azure/sonic-utilities#1355 Azure/sonic-buildimage#6444 What I did Added new option for "counterpoll" util Why I did it Add appropriate code to counterpoll/main.py How I verified it admin@arc-switch1041:~$ counterpoll pg-drop enable --> enable new counter admin@arc-switch1041:~$ counterpoll show --> check new PG_DROP_STAT counter status check counters admin@arc-switch1041:~$ redis-cli -n 2 127.0.0.1:6379[2]> HGETALL COUNTERS:oid:0x1a000000000062 1) "SAI_INGRESS_PRIORITY_GROUP_STAT_XOFF_ROOM_WATERMARK_BYTES" 2) "0" 3) "SAI_INGRESS_PRIORITY_GROUP_STAT_SHARED_WATERMARK_BYTES" 4) "0" 5) "SAI_INGRESS_PRIORITY_GROUP_STAT_DROPPED_PACKETS" 6) "0" --- orchagent/flexcounterorch.cpp | 1 + orchagent/portsorch.cpp | 31 ++++++++++++ orchagent/portsorch.h | 3 +- tests/test_pg_drop_counter.py | 94 +++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 tests/test_pg_drop_counter.py diff --git a/orchagent/flexcounterorch.cpp b/orchagent/flexcounterorch.cpp index 25dd95834e2..a1034331130 100644 --- a/orchagent/flexcounterorch.cpp +++ b/orchagent/flexcounterorch.cpp @@ -26,6 +26,7 @@ unordered_map flexCounterGroupMap = {"PFCWD", PFC_WD_FLEX_COUNTER_GROUP}, {"QUEUE_WATERMARK", QUEUE_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP}, {"PG_WATERMARK", PG_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP}, + {"PG_DROP", PG_DROP_STAT_COUNTER_FLEX_COUNTER_GROUP}, {BUFFER_POOL_WATERMARK_KEY, BUFFER_POOL_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP}, {"RIF", RIF_STAT_COUNTER_FLEX_COUNTER_GROUP}, {"RIF_RATES", RIF_RATE_COUNTER_FLEX_COUNTER_GROUP}, diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index c845cafba83..89d8c53802a 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -56,6 +56,7 @@ extern sai_system_port_api_t *sai_system_port_api; #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 PG_DROP_FLEX_STAT_COUNTER_POLL_MSECS "10000" #define PORT_RATE_FLEX_COUNTER_POLLING_INTERVAL_MS "1000" @@ -199,6 +200,11 @@ static const vector ingressPriorityGroupWater SAI_INGRESS_PRIORITY_GROUP_STAT_SHARED_WATERMARK_BYTES, }; +static const vector ingressPriorityGroupDropStatIds = +{ + SAI_INGRESS_PRIORITY_GROUP_STAT_DROPPED_PACKETS +}; + static char* hostif_vlan_tag[] = { [SAI_HOSTIF_VLAN_TAG_STRIP] = "SAI_HOSTIF_VLAN_TAG_STRIP", [SAI_HOSTIF_VLAN_TAG_KEEP] = "SAI_HOSTIF_VLAN_TAG_KEEP", @@ -295,6 +301,11 @@ PortsOrch::PortsOrch(DBConnector *db, vector &tableNames) 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); + + fieldValues.clear(); + fieldValues.emplace_back(POLL_INTERVAL_FIELD, PG_DROP_FLEX_STAT_COUNTER_POLL_MSECS); + fieldValues.emplace_back(STATS_MODE_FIELD, STATS_MODE_READ); + m_flexCounterGroupTable->set(PG_DROP_STAT_COUNTER_FLEX_COUNTER_GROUP, fieldValues); } catch (const runtime_error &e) { @@ -1899,6 +1910,11 @@ string PortsOrch::getPriorityGroupWatermarkFlexCounterTableKey(string key) return string(PG_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP) + ":" + key; } +string PortsOrch::getPriorityGroupDropPacketsFlexCounterTableKey(string key) +{ + return string(PG_DROP_STAT_COUNTER_FLEX_COUNTER_GROUP) + ":" + key; +} + bool PortsOrch::initPort(const string &alias, const int index, const set &lane_set) { SWSS_LOG_ENTER(); @@ -4241,7 +4257,22 @@ void PortsOrch::generatePriorityGroupMapPerPort(const Port& port) vector fieldValues; fieldValues.emplace_back(PG_COUNTER_ID_LIST, counters_stream.str()); + m_flexCounterTable->set(key, fieldValues); + delimiter = ""; + std::ostringstream ingress_pg_drop_packets_counters_stream; + key = getPriorityGroupDropPacketsFlexCounterTableKey(id); + /* Add dropped packets counters to flex_counter */ + for (const auto& it: ingressPriorityGroupDropStatIds) + { + ingress_pg_drop_packets_counters_stream << delimiter << sai_serialize_ingress_priority_group_stat(it); + if (delimiter.empty()) + { + delimiter = comma; + } + } + fieldValues.clear(); + fieldValues.emplace_back(PG_COUNTER_ID_LIST, ingress_pg_drop_packets_counters_stream.str()); m_flexCounterTable->set(key, fieldValues); } diff --git a/orchagent/portsorch.h b/orchagent/portsorch.h index d692b17661a..627a4f4b38b 100755 --- a/orchagent/portsorch.h +++ b/orchagent/portsorch.h @@ -22,7 +22,7 @@ #define QUEUE_STAT_COUNTER_FLEX_COUNTER_GROUP "QUEUE_STAT_COUNTER" #define QUEUE_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP "QUEUE_WATERMARK_STAT_COUNTER" #define PG_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP "PG_WATERMARK_STAT_COUNTER" - +#define PG_DROP_STAT_COUNTER_FLEX_COUNTER_GROUP "PG_DROP_STAT_COUNTER" typedef std::vector PortSupportedSpeeds; @@ -161,6 +161,7 @@ class PortsOrch : public Orch, public Subject std::string getQueueWatermarkFlexCounterTableKey(std::string s); std::string getPriorityGroupWatermarkFlexCounterTableKey(std::string s); + std::string getPriorityGroupDropPacketsFlexCounterTableKey(std::string s); std::string getPortRateFlexCounterTableKey(std::string s); shared_ptr m_counter_db; diff --git a/tests/test_pg_drop_counter.py b/tests/test_pg_drop_counter.py new file mode 100644 index 00000000000..dedee82c1af --- /dev/null +++ b/tests/test_pg_drop_counter.py @@ -0,0 +1,94 @@ +import os +import re +import time +import json +import pytest +import redis + +from swsscommon import swsscommon + +pg_drop_attr = "SAI_INGRESS_PRIORITY_GROUP_STAT_DROPPED_PACKETS" + +class TestPGDropCounter(object): + DEFAULT_POLL_INTERVAL = 10 + pgs = {} + + def setup_dbs(self, dvs): + self.asic_db = dvs.get_asic_db() + self.counters_db = dvs.get_counters_db() + self.config_db = dvs.get_config_db() + self.flex_db = dvs.get_flex_db() + + def set_counter(self, dvs, obj_type, obj_id, attr, val): + + db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0) + ntf = swsscommon.NotificationProducer(db, "SAI_VS_UNITTEST_CHANNEL") + + r = redis.Redis(unix_socket_path=dvs.redis_sock, db=swsscommon.ASIC_DB, + encoding="utf-8", decode_responses=True) + rid = r.hget("VIDTORID", obj_id) + + assert rid is not None + + fvp = swsscommon.FieldValuePairs([(attr, val)]) + key = rid + + # explicit convert unicode string to str for python2 + ntf.send("set_stats", str(key), fvp) + + def populate_asic(self, dvs, val): + for obj_id in self.pgs: + self.set_counter(dvs, "SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP", obj_id, pg_drop_attr, val) + + def verify_value(self, dvs, obj_ids, entry_name, expected_value): + counters_db = swsscommon.DBConnector(swsscommon.COUNTERS_DB, dvs.redis_sock, 0) + table = swsscommon.Table(counters_db, "COUNTERS") + + for obj_id in obj_ids: + ret = table.get(obj_id) + + status = ret[0] + assert status + keyvalues = ret[1] + found = False + for key, value in keyvalues: + if key == entry_name: + assert value == expected_value, "Saved value not the same as expected" + found = True + assert found, "entry name %s not found" % (entry_name) + + def set_up_flex_counter(self): + pg_stats_entry = {"PG_COUNTER_ID_LIST": "{}".format(pg_drop_attr)} + for pg in self.pgs: + self.flex_db.create_entry("FLEX_COUNTER_TABLE", "PG_DROP_STAT_COUNTER:{}".format(pg), pg_stats_entry) + + fc_status_enable = {"FLEX_COUNTER_STATUS": "enable"} + + self.config_db.create_entry("FLEX_COUNTER_TABLE", "PG_DROP", fc_status_enable) + + def clear_flex_counter(self): + for pg in self.pgs: + self.flex_db.delete_entry("FLEX_COUNTER_TABLE", "PG_DROP_STAT_COUNTER:{}".format(pg)) + + self.config_db.delete_entry("FLEX_COUNTER_TABLE", "PG_DROP") + + + def test_pg_drop_counters(self, dvs): + self.setup_dbs(dvs) + self.pgs = self.asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP") + try: + self.set_up_flex_counter() + + self.populate_asic(dvs, "0") + time.sleep(self.DEFAULT_POLL_INTERVAL) + self.verify_value(dvs, self.pgs, pg_drop_attr, "0") + + self.populate_asic(dvs, "100") + time.sleep(self.DEFAULT_POLL_INTERVAL) + self.verify_value(dvs, self.pgs, pg_drop_attr, "100") + + self.populate_asic(dvs, "123") + time.sleep(self.DEFAULT_POLL_INTERVAL) + self.verify_value(dvs, self.pgs, pg_drop_attr, "123") + finally: + self.clear_flex_counter()