From 2de0ce5e5d048aa6219fa5b2321883b4e6e9c470 Mon Sep 17 00:00:00 2001 From: dbarashinvd <105214075+dbarashinvd@users.noreply.github.com> Date: Fri, 16 Dec 2022 21:48:25 +0200 Subject: [PATCH] Align watermark flow with port configuration (#2525) *Align watermark flow with port configuration correct the queue, watermark and pg-drop counterpoll functionality according to cli commands --- orchagent/bufferorch.cpp | 36 ++-- orchagent/flexcounterorch.cpp | 34 ++- orchagent/flexcounterorch.h | 8 +- orchagent/portsorch.cpp | 380 ++++++++++++++++++++++++---------- orchagent/portsorch.h | 22 +- tests/test_flex_counters.py | 46 +++- 6 files changed, 389 insertions(+), 137 deletions(-) diff --git a/orchagent/bufferorch.cpp b/orchagent/bufferorch.cpp index 3519ba432f..68a715d1a3 100644 --- a/orchagent/bufferorch.cpp +++ b/orchagent/bufferorch.cpp @@ -822,11 +822,13 @@ task_process_status BufferOrch::processQueue(KeyOpFieldsValuesTuple &tuple) { auto flexCounterOrch = gDirectory.get(); auto queues = tokens[1]; - if (op == SET_COMMAND && flexCounterOrch->getQueueCountersState()) + if (op == SET_COMMAND && + (flexCounterOrch->getQueueCountersState() || flexCounterOrch->getQueueWatermarkCountersState())) { gPortsOrch->createPortBufferQueueCounters(port, queues); } - else if (op == DEL_COMMAND && flexCounterOrch->getQueueCountersState()) + else if (op == DEL_COMMAND && + (flexCounterOrch->getQueueCountersState() || flexCounterOrch->getQueueWatermarkCountersState())) { gPortsOrch->removePortBufferQueueCounters(port, queues); } @@ -841,23 +843,23 @@ task_process_status BufferOrch::processQueue(KeyOpFieldsValuesTuple &tuple) * so we added a map that will help us to know what was the last command for this port and priority - * if the last command was set command then it is a modify command and we dont need to increase the buffer counter * all other cases (no last command exist or del command was the last command) it means that we need to increase the ref counter */ - if (op == SET_COMMAND) + if (op == SET_COMMAND) { - if (queue_port_flags[port_name][ind] != SET_COMMAND) + if (queue_port_flags[port_name][ind] != SET_COMMAND) { /* if the last operation was not "set" then it's create and not modify - need to increase ref counter */ gPortsOrch->increasePortRefCount(port_name); } - } + } else if (op == DEL_COMMAND) { - if (queue_port_flags[port_name][ind] == SET_COMMAND) + if (queue_port_flags[port_name][ind] == SET_COMMAND) { /* we need to decrease ref counter only if the last operation was "SET_COMMAND" */ gPortsOrch->decreasePortRefCount(port_name); } - } - else + } + else { SWSS_LOG_ERROR("operation value is not SET or DEL (op = %s)", op.c_str()); return task_process_status::task_invalid_entry; @@ -1001,11 +1003,13 @@ task_process_status BufferOrch::processPriorityGroup(KeyOpFieldsValuesTuple &tup { auto flexCounterOrch = gDirectory.get(); auto pgs = tokens[1]; - if (op == SET_COMMAND && flexCounterOrch->getPgWatermarkCountersState()) + if (op == SET_COMMAND && + (flexCounterOrch->getPgCountersState() || flexCounterOrch->getPgWatermarkCountersState())) { gPortsOrch->createPortBufferPgCounters(port, pgs); } - else if (op == DEL_COMMAND && flexCounterOrch->getPgWatermarkCountersState()) + else if (op == DEL_COMMAND && + (flexCounterOrch->getPgCountersState() || flexCounterOrch->getPgWatermarkCountersState())) { gPortsOrch->removePortBufferPgCounters(port, pgs); } @@ -1021,23 +1025,23 @@ task_process_status BufferOrch::processPriorityGroup(KeyOpFieldsValuesTuple &tup * so we added a map that will help us to know what was the last command for this port and priority - * if the last command was set command then it is a modify command and we dont need to increase the buffer counter * all other cases (no last command exist or del command was the last command) it means that we need to increase the ref counter */ - if (op == SET_COMMAND) + if (op == SET_COMMAND) { - if (pg_port_flags[port_name][ind] != SET_COMMAND) + if (pg_port_flags[port_name][ind] != SET_COMMAND) { /* if the last operation was not "set" then it's create and not modify - need to increase ref counter */ gPortsOrch->increasePortRefCount(port_name); } - } + } else if (op == DEL_COMMAND) { - if (pg_port_flags[port_name][ind] == SET_COMMAND) + if (pg_port_flags[port_name][ind] == SET_COMMAND) { /* we need to decrease ref counter only if the last operation was "SET_COMMAND" */ gPortsOrch->decreasePortRefCount(port_name); } - } - else + } + else { SWSS_LOG_ERROR("operation value is not SET or DEL (op = %s)", op.c_str()); return task_process_status::task_invalid_entry; diff --git a/orchagent/flexcounterorch.cpp b/orchagent/flexcounterorch.cpp index e30b9a0cb1..a48bd9ceb7 100644 --- a/orchagent/flexcounterorch.cpp +++ b/orchagent/flexcounterorch.cpp @@ -29,7 +29,9 @@ extern FlowCounterRouteOrch *gFlowCounterRouteOrch; #define PORT_KEY "PORT" #define PORT_BUFFER_DROP_KEY "PORT_BUFFER_DROP" #define QUEUE_KEY "QUEUE" +#define QUEUE_WATERMARK "QUEUE_WATERMARK" #define PG_WATERMARK_KEY "PG_WATERMARK" +#define PG_DROP_KEY "PG_DROP" #define RIF_KEY "RIF" #define ACL_KEY "ACL" #define TUNNEL_KEY "TUNNEL" @@ -162,11 +164,25 @@ void FlexCounterOrch::doTask(Consumer &consumer) { gPortsOrch->generateQueueMap(getQueueConfigurations()); m_queue_enabled = true; + gPortsOrch->addQueueFlexCounters(getQueueConfigurations()); + } + else if(key == QUEUE_WATERMARK) + { + gPortsOrch->generateQueueMap(getQueueConfigurations()); + m_queue_watermark_enabled = true; + gPortsOrch->addQueueWatermarkFlexCounters(getQueueConfigurations()); + } + else if(key == PG_DROP_KEY) + { + gPortsOrch->generatePriorityGroupMap(getPgConfigurations()); + m_pg_enabled = true; + gPortsOrch->addPriorityGroupFlexCounters(getPgConfigurations()); } else if(key == PG_WATERMARK_KEY) { gPortsOrch->generatePriorityGroupMap(getPgConfigurations()); m_pg_watermark_enabled = true; + gPortsOrch->addPriorityGroupWatermarkFlexCounters(getPgConfigurations()); } } if(gIntfsOrch && (key == RIF_KEY) && (value == "enable")) @@ -250,14 +266,24 @@ bool FlexCounterOrch::getPortBufferDropCountersState() const return m_port_buffer_drop_counter_enabled; } -bool FlexCounterOrch::getPgWatermarkCountersState() const +bool FlexCounterOrch::getQueueCountersState() const { - return m_pg_watermark_enabled; + return m_queue_enabled; } -bool FlexCounterOrch::getQueueCountersState() const +bool FlexCounterOrch::getQueueWatermarkCountersState() const { - return m_queue_enabled; + return m_queue_watermark_enabled; +} + +bool FlexCounterOrch::getPgCountersState() const +{ + return m_pg_enabled; +} + +bool FlexCounterOrch::getPgWatermarkCountersState() const +{ + return m_pg_watermark_enabled; } bool FlexCounterOrch::bake() diff --git a/orchagent/flexcounterorch.h b/orchagent/flexcounterorch.h index a6e7527a05..6126588261 100644 --- a/orchagent/flexcounterorch.h +++ b/orchagent/flexcounterorch.h @@ -42,8 +42,10 @@ class FlexCounterOrch: public Orch virtual ~FlexCounterOrch(void); bool getPortCountersState() const; bool getPortBufferDropCountersState() const; - bool getPgWatermarkCountersState() const; bool getQueueCountersState() const; + bool getQueueWatermarkCountersState() const; + bool getPgCountersState() const; + bool getPgWatermarkCountersState() const; std::map getQueueConfigurations(); std::map getPgConfigurations(); bool getHostIfTrapCounterState() const {return m_hostif_trap_counter_enabled;} @@ -57,8 +59,10 @@ class FlexCounterOrch: public Orch std::shared_ptr m_gbflexCounterGroupTable = nullptr; bool m_port_counter_enabled = false; bool m_port_buffer_drop_counter_enabled = false; - bool m_pg_watermark_enabled = false; bool m_queue_enabled = false; + bool m_queue_watermark_enabled = false; + bool m_pg_enabled = false; + bool m_pg_watermark_enabled = false; bool m_hostif_trap_counter_enabled = false; bool m_route_flow_counter_enabled = false; Table m_flexCounterConfigTable; diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index a7a6e25548..376328fac8 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -6088,7 +6088,6 @@ void PortsOrch::generateQueueMap(map queuesState void PortsOrch::generateQueueMapPerPort(const Port& port, FlexCounterQueueStates& queuesState, bool voq) { /* Create the Queue map in the Counter DB */ - /* Add stat counters to flex_counter */ vector queueVector; vector queuePortVector; vector queueIndexVector; @@ -6140,50 +6139,139 @@ void PortsOrch::generateQueueMapPerPort(const Port& port, FlexCounterQueueStates { queuePortVector.emplace_back(id, sai_serialize_object_id(port.m_port_id)); } + } + + if (voq) + { + m_voqTable->set("", queueVector); + } + else + { + m_queueTable->set("", queueVector); + } + m_queuePortTable->set("", queuePortVector); + m_queueIndexTable->set("", queueIndexVector); + m_queueTypeTable->set("", queueTypeVector); + + CounterCheckOrch::getInstance().addPort(port); +} - // Install a flex counter for this queue to track stats - std::unordered_set counter_stats; - for (const auto& it: queue_stat_ids) +void PortsOrch::addQueueFlexCounters(map queuesStateVector) +{ + if (m_isQueueFlexCountersAdded) + { + return; + } + + for (const auto& it: m_portList) + { + if (it.second.m_type == Port::PHY) { - counter_stats.emplace(sai_serialize_queue_stat(it)); + if (!queuesStateVector.count(it.second.m_alias)) + { + auto maxQueueNumber = getNumberOfPortSupportedQueueCounters(it.second.m_alias); + FlexCounterQueueStates flexCounterQueueState(maxQueueNumber); + queuesStateVector.insert(make_pair(it.second.m_alias, flexCounterQueueState)); + } + addQueueFlexCountersPerPort(it.second, queuesStateVector.at(it.second.m_alias)); } - queue_stat_manager.setCounterIdList(queue_ids[queueIndex], CounterType::QUEUE, counter_stats); + } - if (voq) + m_isQueueFlexCountersAdded = true; +} + + +void PortsOrch::addQueueFlexCountersPerPort(const Port& port, FlexCounterQueueStates& queuesState) +{ + for (size_t queueIndex = 0; queueIndex < port.m_queue_ids.size(); ++queueIndex) + { + string queueType; + uint8_t queueRealIndex = 0; + if (getQueueTypeAndIndex(port.m_queue_ids[queueIndex], queueType, queueRealIndex)) { - continue; + if (!queuesState.isQueueCounterEnabled(queueRealIndex)) + { + continue; + } + // Install a flex counter for this queue to track stats + addQueueFlexCountersPerPortPerQueueIndex(port, queueIndex); } + } +} + +void PortsOrch::addQueueFlexCountersPerPortPerQueueIndex(const Port& port, size_t queueIndex) +{ + std::unordered_set counter_stats; + for (const auto& it: queue_stat_ids) + { + counter_stats.emplace(sai_serialize_queue_stat(it)); + } + queue_stat_manager.setCounterIdList(port.m_queue_ids[queueIndex], CounterType::QUEUE, counter_stats); +} - /* add watermark queue counters */ - string key = getQueueWatermarkFlexCounterTableKey(id); - string delimiter(""); - std::ostringstream counters_stream; - for (const auto& it: queueWatermarkStatIds) +void PortsOrch::addQueueWatermarkFlexCounters(map queuesStateVector) +{ + if (m_isQueueWatermarkFlexCountersAdded) + { + return; + } + + for (const auto& it: m_portList) + { + if (it.second.m_type == Port::PHY) { - counters_stream << delimiter << sai_serialize_queue_stat(it); - delimiter = comma; + if (!queuesStateVector.count(it.second.m_alias)) + { + auto maxQueueNumber = getNumberOfPortSupportedQueueCounters(it.second.m_alias); + FlexCounterQueueStates flexCounterQueueState(maxQueueNumber); + queuesStateVector.insert(make_pair(it.second.m_alias, flexCounterQueueState)); + } + addQueueWatermarkFlexCountersPerPort(it.second, queuesStateVector.at(it.second.m_alias)); } + } - vector fieldValues; - fieldValues.emplace_back(QUEUE_COUNTER_ID_LIST, counters_stream.str()); + m_isQueueWatermarkFlexCountersAdded = true; +} - m_flexCounterTable->set(key, fieldValues); - } +void PortsOrch::addQueueWatermarkFlexCountersPerPort(const Port& port, FlexCounterQueueStates& queuesState) +{ + /* Add stat counters to flex_counter */ - if (voq) + for (size_t queueIndex = 0; queueIndex < port.m_queue_ids.size(); ++queueIndex) { - m_voqTable->set("", queueVector); + string queueType; + uint8_t queueRealIndex = 0; + if (getQueueTypeAndIndex(port.m_queue_ids[queueIndex], queueType, queueRealIndex)) + { + if (!queuesState.isQueueCounterEnabled(queueRealIndex)) + { + continue; + } + addQueueWatermarkFlexCountersPerPortPerQueueIndex(port, queueIndex); + } } - else +} + +void PortsOrch::addQueueWatermarkFlexCountersPerPortPerQueueIndex(const Port& port, size_t queueIndex) +{ + const auto id = sai_serialize_object_id(port.m_queue_ids[queueIndex]); + + /* add watermark queue counters */ + string key = getQueueWatermarkFlexCounterTableKey(id); + + string delimiter(""); + std::ostringstream counters_stream; + for (const auto& it: queueWatermarkStatIds) { - m_queueTable->set("", queueVector); + counters_stream << delimiter << sai_serialize_queue_stat(it); + delimiter = comma; } - m_queuePortTable->set("", queuePortVector); - m_queueIndexTable->set("", queueIndexVector); - m_queueTypeTable->set("", queueTypeVector); - CounterCheckOrch::getInstance().addPort(port); + vector fieldValues; + fieldValues.emplace_back(QUEUE_COUNTER_ID_LIST, counters_stream.str()); + + m_flexCounterTable->set(key, fieldValues); } void PortsOrch::createPortBufferQueueCounters(const Port &port, string queues) @@ -6191,7 +6279,6 @@ void PortsOrch::createPortBufferQueueCounters(const Port &port, string queues) SWSS_LOG_ENTER(); /* Create the Queue map in the Counter DB */ - /* Add stat counters to flex_counter */ vector queueVector; vector queuePortVector; vector queueIndexVector; @@ -6223,29 +6310,17 @@ void PortsOrch::createPortBufferQueueCounters(const Port &port, string queues) queueVector.emplace_back(name.str(), id); queuePortVector.emplace_back(id, sai_serialize_object_id(port.m_port_id)); - // Install a flex counter for this queue to track stats - std::unordered_set counter_stats; - for (const auto& it: queue_stat_ids) + auto flexCounterOrch = gDirectory.get(); + if (flexCounterOrch->getQueueCountersState()) { - counter_stats.emplace(sai_serialize_queue_stat(it)); + // Install a flex counter for this queue to track stats + addQueueFlexCountersPerPortPerQueueIndex(port, queueIndex); } - queue_stat_manager.setCounterIdList(port.m_queue_ids[queueIndex], CounterType::QUEUE, counter_stats); - - /* add watermark queue counters */ - string key = getQueueWatermarkFlexCounterTableKey(id); - - string delimiter(""); - std::ostringstream counters_stream; - for (const auto& it: queueWatermarkStatIds) + if (flexCounterOrch->getQueueWatermarkCountersState()) { - counters_stream << delimiter << sai_serialize_queue_stat(it); - delimiter = comma; + /* add watermark queue counters */ + addQueueWatermarkFlexCountersPerPortPerQueueIndex(port, queueIndex); } - - vector fieldValues; - fieldValues.emplace_back(QUEUE_COUNTER_ID_LIST, counters_stream.str()); - - m_flexCounterTable->set(key, fieldValues); } m_queueTable->set("", queueVector); @@ -6288,12 +6363,19 @@ void PortsOrch::removePortBufferQueueCounters(const Port &port, string queues) m_queueIndexTable->hdel("", id); } - // Remove the flex counter for this queue - queue_stat_manager.clearCounterIdList(port.m_queue_ids[queueIndex]); + auto flexCounterOrch = gDirectory.get(); + if (flexCounterOrch->getQueueCountersState()) + { + // Remove the flex counter for this queue + queue_stat_manager.clearCounterIdList(port.m_queue_ids[queueIndex]); + } - // Remove watermark queue counters - string key = getQueueWatermarkFlexCounterTableKey(id); - m_flexCounterTable->del(key); + if (flexCounterOrch->getQueueWatermarkCountersState()) + { + // Remove watermark queue counters + string key = getQueueWatermarkFlexCounterTableKey(id); + m_flexCounterTable->del(key); + } } CounterCheckOrch::getInstance().removePort(port); @@ -6326,7 +6408,6 @@ void PortsOrch::generatePriorityGroupMap(map pgsSta void PortsOrch::generatePriorityGroupMapPerPort(const Port& port, FlexCounterPgStates& pgsState) { /* Create the PG map in the Counter DB */ - /* Add stat counters to flex_counter */ vector pgVector; vector pgPortVector; vector pgIndexVector; @@ -6346,36 +6427,6 @@ void PortsOrch::generatePriorityGroupMapPerPort(const Port& port, FlexCounterPgS pgPortVector.emplace_back(id, sai_serialize_object_id(port.m_port_id)); pgIndexVector.emplace_back(id, to_string(pgIndex)); - string key = getPriorityGroupWatermarkFlexCounterTableKey(id); - - std::string delimiter = ""; - std::ostringstream counters_stream; - /* Add watermark counters to flex_counter */ - for (const auto& it: ingressPriorityGroupWatermarkStatIds) - { - counters_stream << delimiter << sai_serialize_ingress_priority_group_stat(it); - delimiter = comma; - } - - 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); } m_pgTable->set("", pgVector); @@ -6414,43 +6465,139 @@ void PortsOrch::createPortBufferPgCounters(const Port& port, string pgs) pgPortVector.emplace_back(id, sai_serialize_object_id(port.m_port_id)); pgIndexVector.emplace_back(id, to_string(pgIndex)); - string key = getPriorityGroupWatermarkFlexCounterTableKey(id); + auto flexCounterOrch = gDirectory.get(); + if (flexCounterOrch->getPgCountersState()) + { + /* Add dropped packets counters to flex_counter */ + addPriorityGroupFlexCountersPerPortPerPgIndex(port, pgIndex); + } + if (flexCounterOrch->getPgWatermarkCountersState()) + { + /* Add watermark counters to flex_counter */ + addPriorityGroupWatermarkFlexCountersPerPortPerPgIndex(port, pgIndex); + } + } + + m_pgTable->set("", pgVector); + m_pgPortTable->set("", pgPortVector); + m_pgIndexTable->set("", pgIndexVector); + + CounterCheckOrch::getInstance().addPort(port); +} + +void PortsOrch::addPriorityGroupFlexCounters(map pgsStateVector) +{ + if (m_isPriorityGroupFlexCountersAdded) + { + return; + } + + for (const auto& it: m_portList) + { + if (it.second.m_type == Port::PHY) + { + if (!pgsStateVector.count(it.second.m_alias)) + { + auto maxPgNumber = getNumberOfPortSupportedPgCounters(it.second.m_alias); + FlexCounterPgStates flexCounterPgState(maxPgNumber); + pgsStateVector.insert(make_pair(it.second.m_alias, flexCounterPgState)); + } + addPriorityGroupFlexCountersPerPort(it.second, pgsStateVector.at(it.second.m_alias)); + } + } + + m_isPriorityGroupFlexCountersAdded = true; +} + +void PortsOrch::addPriorityGroupFlexCountersPerPort(const Port& port, FlexCounterPgStates& pgsState) +{ + for (size_t pgIndex = 0; pgIndex < port.m_priority_group_ids.size(); ++pgIndex) + { + if (!pgsState.isPgCounterEnabled(static_cast(pgIndex))) + { + continue; + } + addPriorityGroupFlexCountersPerPortPerPgIndex(port, pgIndex); + } +} + +void PortsOrch::addPriorityGroupFlexCountersPerPortPerPgIndex(const Port& port, size_t pgIndex) +{ + const auto id = sai_serialize_object_id(port.m_priority_group_ids[pgIndex]); - std::string delimiter = ""; - std::ostringstream counters_stream; - /* Add watermark counters to flex_counter */ - for (const auto& it: ingressPriorityGroupWatermarkStatIds) + string delimiter = ""; + std::ostringstream ingress_pg_drop_packets_counters_stream; + string 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()) { - counters_stream << delimiter << sai_serialize_ingress_priority_group_stat(it); delimiter = comma; } + } + vector fieldValues; + fieldValues.emplace_back(PG_COUNTER_ID_LIST, ingress_pg_drop_packets_counters_stream.str()); + m_flexCounterTable->set(key, fieldValues); +} - vector fieldValues; - fieldValues.emplace_back(PG_COUNTER_ID_LIST, counters_stream.str()); - m_flexCounterTable->set(key, fieldValues); +void PortsOrch::addPriorityGroupWatermarkFlexCounters(map pgsStateVector) +{ + if (m_isPriorityGroupWatermarkFlexCountersAdded) + { + return; + } - delimiter = ""; - std::ostringstream ingress_pg_drop_packets_counters_stream; - key = getPriorityGroupDropPacketsFlexCounterTableKey(id); - /* Add dropped packets counters to flex_counter */ - for (const auto& it: ingressPriorityGroupDropStatIds) + for (const auto& it: m_portList) + { + if (it.second.m_type == Port::PHY) { - ingress_pg_drop_packets_counters_stream << delimiter << sai_serialize_ingress_priority_group_stat(it); - if (delimiter.empty()) + if (!pgsStateVector.count(it.second.m_alias)) { - delimiter = comma; + auto maxPgNumber = getNumberOfPortSupportedPgCounters(it.second.m_alias); + FlexCounterPgStates flexCounterPgState(maxPgNumber); + pgsStateVector.insert(make_pair(it.second.m_alias, flexCounterPgState)); } + addPriorityGroupWatermarkFlexCountersPerPort(it.second, pgsStateVector.at(it.second.m_alias)); } - fieldValues.clear(); - fieldValues.emplace_back(PG_COUNTER_ID_LIST, ingress_pg_drop_packets_counters_stream.str()); - m_flexCounterTable->set(key, fieldValues); } - m_pgTable->set("", pgVector); - m_pgPortTable->set("", pgPortVector); - m_pgIndexTable->set("", pgIndexVector); + m_isPriorityGroupWatermarkFlexCountersAdded = true; +} - CounterCheckOrch::getInstance().addPort(port); +void PortsOrch::addPriorityGroupWatermarkFlexCountersPerPort(const Port& port, FlexCounterPgStates& pgsState) +{ + /* Add stat counters to flex_counter */ + + for (size_t pgIndex = 0; pgIndex < port.m_priority_group_ids.size(); ++pgIndex) + { + if (!pgsState.isPgCounterEnabled(static_cast(pgIndex))) + { + continue; + } + addPriorityGroupWatermarkFlexCountersPerPortPerPgIndex(port, pgIndex); + } +} + +void PortsOrch::addPriorityGroupWatermarkFlexCountersPerPortPerPgIndex(const Port& port, size_t pgIndex) +{ + const auto id = sai_serialize_object_id(port.m_priority_group_ids[pgIndex]); + + string key = getPriorityGroupWatermarkFlexCounterTableKey(id); + + std::string delimiter = ""; + std::ostringstream counters_stream; + /* Add watermark counters to flex_counter */ + for (const auto& it: ingressPriorityGroupWatermarkStatIds) + { + counters_stream << delimiter << sai_serialize_ingress_priority_group_stat(it); + delimiter = comma; + } + + vector fieldValues; + fieldValues.emplace_back(PG_COUNTER_ID_LIST, counters_stream.str()); + m_flexCounterTable->set(key, fieldValues); } void PortsOrch::removePortBufferPgCounters(const Port& port, string pgs) @@ -6478,13 +6625,20 @@ void PortsOrch::removePortBufferPgCounters(const Port& port, string pgs) m_pgPortTable->hdel("", id); m_pgIndexTable->hdel("", id); - // Remove dropped packets counters from flex_counter - string key = getPriorityGroupDropPacketsFlexCounterTableKey(id); - m_flexCounterTable->del(key); + auto flexCounterOrch = gDirectory.get(); + if (flexCounterOrch->getPgCountersState()) + { + // Remove dropped packets counters from flex_counter + string key = getPriorityGroupDropPacketsFlexCounterTableKey(id); + m_flexCounterTable->del(key); + } - // Remove watermark counters from flex_counter - key = getPriorityGroupWatermarkFlexCounterTableKey(id); - m_flexCounterTable->del(key); + if (flexCounterOrch->getPgWatermarkCountersState()) + { + // Remove watermark counters from flex_counter + string key = getPriorityGroupWatermarkFlexCounterTableKey(id); + m_flexCounterTable->del(key); + } } CounterCheckOrch::getInstance().removePort(port); diff --git a/orchagent/portsorch.h b/orchagent/portsorch.h index 446d6bc8de..e33ed80810 100644 --- a/orchagent/portsorch.h +++ b/orchagent/portsorch.h @@ -131,16 +131,20 @@ class PortsOrch : public Orch, public Subject bool setPortPfcWatchdogStatus(sai_object_id_t portId, uint8_t pfc_bitmask); bool getPortPfcWatchdogStatus(sai_object_id_t portId, uint8_t *pfc_bitmask); - + void generateQueueMap(map queuesStateVector); uint32_t getNumberOfPortSupportedQueueCounters(string port); void createPortBufferQueueCounters(const Port &port, string queues); void removePortBufferQueueCounters(const Port &port, string queues); + void addQueueFlexCounters(map queuesStateVector); + void addQueueWatermarkFlexCounters(map queuesStateVector); void generatePriorityGroupMap(map pgsStateVector); uint32_t getNumberOfPortSupportedPgCounters(string port); void createPortBufferPgCounters(const Port &port, string pgs); void removePortBufferPgCounters(const Port& port, string pgs); + void addPriorityGroupFlexCounters(map pgsStateVector); + void addPriorityGroupWatermarkFlexCounters(map pgsStateVector); void generatePortCounterMap(); void generatePortBufferDropCounterMap(); @@ -358,8 +362,24 @@ class PortsOrch : public Orch, public Subject bool m_isQueueMapGenerated = false; void generateQueueMapPerPort(const Port& port, FlexCounterQueueStates& queuesState, bool voq); + bool m_isQueueFlexCountersAdded = false; + void addQueueFlexCountersPerPort(const Port& port, FlexCounterQueueStates& queuesState); + void addQueueFlexCountersPerPortPerQueueIndex(const Port& port, size_t queueIndex); + + bool m_isQueueWatermarkFlexCountersAdded = false; + void addQueueWatermarkFlexCountersPerPort(const Port& port, FlexCounterQueueStates& queuesState); + void addQueueWatermarkFlexCountersPerPortPerQueueIndex(const Port& port, size_t queueIndex); + bool m_isPriorityGroupMapGenerated = false; void generatePriorityGroupMapPerPort(const Port& port, FlexCounterPgStates& pgsState); + bool m_isPriorityGroupFlexCountersAdded = false; + void addPriorityGroupFlexCountersPerPort(const Port& port, FlexCounterPgStates& pgsState); + void addPriorityGroupFlexCountersPerPortPerPgIndex(const Port& port, size_t pgIndex); + + bool m_isPriorityGroupWatermarkFlexCountersAdded = false; + void addPriorityGroupWatermarkFlexCountersPerPort(const Port& port, FlexCounterPgStates& pgsState); + void addPriorityGroupWatermarkFlexCountersPerPortPerPgIndex(const Port& port, size_t pgIndex); + bool m_isPortCounterMapGenerated = false; bool m_isPortBufferDropCounterMapGenerated = false; diff --git a/tests/test_flex_counters.py b/tests/test_flex_counters.py index f5a0b146b2..eefef8bab4 100644 --- a/tests/test_flex_counters.py +++ b/tests/test_flex_counters.py @@ -20,6 +20,11 @@ 'group_name': 'QUEUE_STAT_COUNTER', 'name_map': 'COUNTERS_QUEUE_NAME_MAP', }, + 'queue_watermark_counter': { + 'key': 'QUEUE_WATERMARK', + 'group_name': 'QUEUE_WATERMARK_STAT_COUNTER', + 'name_map': 'COUNTERS_QUEUE_NAME_MAP', + }, 'rif_counter': { 'key': 'RIF', 'group_name': 'RIF_STAT_COUNTER', @@ -37,6 +42,11 @@ 'group_name': 'PORT_BUFFER_DROP_STAT', 'name_map': 'COUNTERS_PORT_NAME_MAP', }, + 'pg_drop_counter': { + 'key': 'PG_DROP', + 'group_name': 'PG_DROP_STAT_COUNTER', + 'name_map': 'COUNTERS_PG_NAME_MAP', + }, 'pg_watermark_counter': { 'key': 'PG_WATERMARK', 'group_name': 'PG_WATERMARK_STAT_COUNTER', @@ -702,7 +712,7 @@ def remove_ip_address(self, interface, ip): def set_admin_status(self, interface, status): self.config_db.update_entry("PORT", interface, {"admin_status": status}) - def test_create_remove_buffer_pg_counter(self, dvs): + def test_create_remove_buffer_pg_watermark_counter(self, dvs): """ Test steps: 1. Enable PG flex counters. @@ -751,3 +761,37 @@ def test_create_remove_buffer_queue_counter(self, dvs): self.config_db.delete_entry('BUFFER_QUEUE', 'Ethernet0|7') self.wait_for_buffer_pg_queue_counter(meta_data['name_map'], 'Ethernet0', '7', False) self.wait_for_id_list_remove(meta_data['group_name'], "Ethernet0", counter_oid) + + def test_create_remove_buffer_watermark_queue_pg_counter(self, dvs): + """ + Test steps: + 1. Enable Queue/Watermark/PG-drop flex counters. + 2. Configure new buffer queue for a port + 3. Verify counters is automatically created + 4. Remove the new buffer queue for the port + 5. Verify counters is automatically removed + + Args: + dvs (object): virtual switch object + """ + self.setup_dbs(dvs) + + # set flex counter + for counterpoll_type, meta_data in counter_group_meta.items(): + if 'queue' in counterpoll_type or 'pg' in counterpoll_type: + self.set_flex_counter_group_status(meta_data['key'], meta_data['name_map']) + + self.config_db.update_entry('BUFFER_PG', 'Ethernet0|7', {'profile': 'ingress_lossy_profile'}) + self.config_db.update_entry('BUFFER_QUEUE', 'Ethernet0|7', {'profile': 'egress_lossless_profile'}) + + for counterpoll_type, meta_data in counter_group_meta.items(): + if 'queue' in counterpoll_type or 'pg' in counterpoll_type: + counter_oid = self.wait_for_buffer_pg_queue_counter(meta_data['name_map'], 'Ethernet0', '7', True) + self.wait_for_id_list(meta_data['group_name'], "Ethernet0", counter_oid) + + self.config_db.delete_entry('BUFFER_QUEUE', 'Ethernet0|7') + self.config_db.delete_entry('BUFFER_PG', 'Ethernet0|7') + for counterpoll_type, meta_data in counter_group_meta.items(): + if 'queue' in counterpoll_type or 'pg' in counterpoll_type: + self.wait_for_buffer_pg_queue_counter(meta_data['name_map'], 'Ethernet0', '7', False) + self.wait_for_id_list_remove(meta_data['group_name'], "Ethernet0", counter_oid)