Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions orchagent/flex_counter/flex_counter_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,22 @@ const unordered_map<bool, string> FlexCounterManager::status_lookup =

const unordered_map<CounterType, string> FlexCounterManager::counter_id_field_lookup =
{
{ CounterType::PORT_DEBUG, PORT_DEBUG_COUNTER_ID_LIST },
{ CounterType::SWITCH_DEBUG, SWITCH_DEBUG_COUNTER_ID_LIST },
{ CounterType::PORT, PORT_COUNTER_ID_LIST },
{ CounterType::QUEUE, QUEUE_COUNTER_ID_LIST },
{ CounterType::QUEUE_ATTR, QUEUE_ATTR_ID_LIST },
{ CounterType::PRIORITY_GROUP, PG_COUNTER_ID_LIST },
{ CounterType::MACSEC_SA_ATTR, MACSEC_SA_ATTR_ID_LIST },
{ CounterType::MACSEC_SA, MACSEC_SA_COUNTER_ID_LIST },
{ CounterType::MACSEC_FLOW, MACSEC_FLOW_COUNTER_ID_LIST },
{ CounterType::ACL_COUNTER, ACL_COUNTER_ATTR_ID_LIST },
{ CounterType::TUNNEL, TUNNEL_COUNTER_ID_LIST },
{ CounterType::HOSTIF_TRAP, FLOW_COUNTER_ID_LIST },
{ CounterType::ROUTE, FLOW_COUNTER_ID_LIST },
{ CounterType::ENI, ENI_COUNTER_ID_LIST },
{ CounterType::SRV6, SRV6_COUNTER_ID_LIST },
{ CounterType::PORT_DEBUG, PORT_DEBUG_COUNTER_ID_LIST },
{ CounterType::PORT_ATTR, PORT_ATTR_ID_LIST },
{ CounterType::SWITCH_DEBUG, SWITCH_DEBUG_COUNTER_ID_LIST },
{ CounterType::PORT, PORT_COUNTER_ID_LIST },
{ CounterType::QUEUE, QUEUE_COUNTER_ID_LIST },
{ CounterType::QUEUE_ATTR, QUEUE_ATTR_ID_LIST },
{ CounterType::PRIORITY_GROUP, PG_COUNTER_ID_LIST },
{ CounterType::MACSEC_SA_ATTR, MACSEC_SA_ATTR_ID_LIST },
{ CounterType::MACSEC_SA, MACSEC_SA_COUNTER_ID_LIST },
{ CounterType::MACSEC_FLOW, MACSEC_FLOW_COUNTER_ID_LIST },
{ CounterType::ACL_COUNTER, ACL_COUNTER_ATTR_ID_LIST },
{ CounterType::TUNNEL, TUNNEL_COUNTER_ID_LIST },
{ CounterType::HOSTIF_TRAP, FLOW_COUNTER_ID_LIST },
{ CounterType::ROUTE, FLOW_COUNTER_ID_LIST },
{ CounterType::ENI, ENI_COUNTER_ID_LIST },
{ CounterType::SRV6, SRV6_COUNTER_ID_LIST },
};

FlexManagerDirectory g_FlexManagerDirectory;
Expand Down
1 change: 1 addition & 0 deletions orchagent/flex_counter/flex_counter_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum class StatsMode
enum class CounterType
{
PORT,
PORT_ATTR,
QUEUE,
QUEUE_ATTR,
PRIORITY_GROUP,
Expand Down
32 changes: 26 additions & 6 deletions orchagent/flexcounterorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ extern sai_object_id_t gSwitchId;

#define BUFFER_POOL_WATERMARK_KEY "BUFFER_POOL_WATERMARK"
#define PORT_KEY "PORT"
#define PORT_ATTR_KEY "PORT_ATTR"
#define PORT_BUFFER_DROP_KEY "PORT_BUFFER_DROP"
#define QUEUE_KEY "QUEUE"
#define QUEUE_WATERMARK "QUEUE_WATERMARK"
Expand All @@ -52,6 +53,7 @@ extern sai_object_id_t gSwitchId;
unordered_map<string, string> flexCounterGroupMap =
{
{"PORT", PORT_STAT_COUNTER_FLEX_COUNTER_GROUP},
{"PORT_ATTR", PORT_ATTR_FLEX_COUNTER_GROUP},
{"PORT_RATES", PORT_RATE_COUNTER_FLEX_COUNTER_GROUP},
{"PORT_BUFFER_DROP", PORT_BUFFER_DROP_STAT_FLEX_COUNTER_GROUP},
{"QUEUE", QUEUE_STAT_COUNTER_FLEX_COUNTER_GROUP},
Expand Down Expand Up @@ -215,17 +217,17 @@ void FlexCounterOrch::doTask(Consumer &consumer)
m_pg_watermark_enabled = true;
gPortsOrch->addPriorityGroupWatermarkFlexCounters(getPgConfigurations());
}
else if(key == WRED_PORT_KEY)
{
else if(key == WRED_PORT_KEY)
{
gPortsOrch->generateWredPortCounterMap();
m_wred_port_counter_enabled = true;
}
else if(key == WRED_QUEUE_KEY)
{
}
else if(key == WRED_QUEUE_KEY)
{
gPortsOrch->generateQueueMap(getQueueConfigurations());
m_wred_queue_counter_enabled = true;
gPortsOrch->addWredQueueFlexCounters(getQueueConfigurations());
}
}
}
if(gIntfsOrch && (key == RIF_KEY) && (value == "enable"))
{
Expand Down Expand Up @@ -277,6 +279,19 @@ void FlexCounterOrch::doTask(Consumer &consumer)
{
gSrv6Orch->setCountersState((value == "enable"));
}
if (gPortsOrch && (key == PORT_ATTR_KEY))
{
if(value == "enable" && !m_port_attr_enabled)
{
m_port_attr_enabled = true;
gPortsOrch->generatePortAttrCounterMap();
}
if (value == "disable" && m_port_attr_enabled)
{
gPortsOrch->clearPortAttrCounterMap();
m_port_attr_enabled = false;
}
}

if (gPortsOrch)
{
Expand Down Expand Up @@ -336,6 +351,11 @@ bool FlexCounterOrch::getPortCountersState() const
return m_port_counter_enabled;
}

bool FlexCounterOrch::getPortAttrCountersState() const
{
return m_port_attr_enabled;
}

bool FlexCounterOrch::getPortBufferDropCountersState() const
{
return m_port_buffer_drop_counter_enabled;
Expand Down
2 changes: 2 additions & 0 deletions orchagent/flexcounterorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class FlexCounterOrch: public Orch
FlexCounterOrch(swss::DBConnector *db, std::vector<std::string> &tableNames);
virtual ~FlexCounterOrch(void);
bool getPortCountersState() const;
bool getPortAttrCountersState() const;
bool getPortBufferDropCountersState() const;
bool getQueueCountersState() const;
bool getQueueWatermarkCountersState() const;
Expand All @@ -60,6 +61,7 @@ class FlexCounterOrch: public Orch

private:
bool m_port_counter_enabled = false;
bool m_port_attr_enabled = false;
bool m_port_buffer_drop_counter_enabled = false;
bool m_queue_enabled = false;
bool m_queue_watermark_enabled = false;
Expand Down
7 changes: 7 additions & 0 deletions orchagent/p4orch/tests/fake_portorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
m_portOpErrTable(stateDb, STATE_PORT_OPER_ERR_TABLE_NAME),
port_stat_manager(PORT_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ,
PORT_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, true),
port_attr_manager(PORT_ATTR_FLEX_COUNTER_GROUP, StatsMode::READ, PORT_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false),
port_buffer_drop_stat_manager(PORT_BUFFER_DROP_STAT_FLEX_COUNTER_GROUP, StatsMode::READ,
PORT_BUFFER_DROP_STAT_POLLING_INTERVAL_MS, true),
queue_stat_manager(QUEUE_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ, QUEUE_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false),
Expand Down Expand Up @@ -706,6 +707,12 @@ std::unordered_set<std::string> PortsOrch::generateCounterStats(const vector<T>
return {};
}

const std::vector<sai_port_attr_t>& PortsOrch::getPortAttrIds() const
{
static const std::vector<sai_port_attr_t> empty_vector = {};
return empty_vector;
}

void PortsOrch::doTask(swss::SelectableTimer &timer)
{
}
Expand Down
182 changes: 182 additions & 0 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ static map<sai_queue_type_t, string> sai_queue_type_string_map =
{SAI_QUEUE_TYPE_UNICAST_VOQ, "SAI_QUEUE_TYPE_UNICAST_VOQ"},
};

const vector<sai_port_attr_t> port_attr_ids =
{
SAI_PORT_ATTR_RX_SIGNAL_DETECT, // RX signal detection per lane
SAI_PORT_ATTR_FEC_ALIGNMENT_LOCK, // FEC alignment lock status per lane
SAI_PORT_ATTR_RX_SNR // Receive Signal-to-Noise Ratio per lane
};

const vector<sai_port_stat_t> port_stat_ids =
{
SAI_PORT_STAT_IF_IN_OCTETS,
Expand Down Expand Up @@ -562,6 +569,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
m_portStateTable(stateDb, STATE_PORT_TABLE_NAME),
m_portOpErrTable(stateDb, STATE_PORT_OPER_ERR_TABLE_NAME),
port_stat_manager(PORT_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ, PORT_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false),
port_attr_manager(PORT_ATTR_FLEX_COUNTER_GROUP, StatsMode::READ, PORT_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false),
gb_port_stat_manager(true,
PORT_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ,
PORT_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false),
Expand All @@ -574,6 +582,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
wred_queue_stat_manager(WRED_QUEUE_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ, QUEUE_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false),
counter_managers({
ref(port_stat_manager),
ref(port_attr_manager),
ref(port_buffer_drop_stat_manager),
ref(queue_stat_manager),
ref(queue_watermark_manager),
Expand Down Expand Up @@ -3801,6 +3810,18 @@ bool PortsOrch::initPort(const PortConfig &port)
gb_port_stat_manager.setCounterIdList(p.m_line_side_id,
CounterType::PORT, gbport_counter_stats, p.m_switch_id);
}
if (flex_counters_orch->getPortAttrCountersState())
{
if (p.m_type == Port::Type::PHY && supportsPortAttr(p.m_port_id, p.m_alias.c_str()))
{
if (!m_supported_phy_attrs.empty())
{
auto port_attr_stats = generateCounterStats(m_supported_phy_attrs, sai_serialize_port_attr);
port_attr_manager.setCounterIdList(p.m_port_id,
CounterType::PORT_ATTR, port_attr_stats);
}
}
}
if (flex_counters_orch->getPortBufferDropCountersState())
{
auto port_buffer_drop_stats = generateCounterStats(port_buffer_drop_stat_ids, sai_serialize_port_stat);
Expand Down Expand Up @@ -3885,6 +3906,13 @@ void PortsOrch::deInitPort(string alias, sai_object_id_t port_id)
{
wred_port_stat_manager.clearCounterIdList(p.m_port_id);
}
if (p.m_type == Port::Type::PHY && supportsPortAttr(p.m_port_id, p.m_alias.c_str()))
{
if (!m_supported_phy_attrs.empty())
{
port_attr_manager.clearCounterIdList(p.m_port_id);
}
}

/* remove port name map from counter table */
m_counterTable->hdel("", alias);
Expand Down Expand Up @@ -8361,6 +8389,160 @@ void PortsOrch::generatePortBufferDropCounterMap()
m_isPortBufferDropCounterMapGenerated = true;
}

void PortsOrch::queryPortAttrCapabilities()
{
if (m_phy_attr_capability_checked)
{
return;
}

for (const auto& attr_id : port_attr_ids)
{
sai_attr_capability_t capability;

sai_status_t status = sai_query_attribute_capability(
gSwitchId,
SAI_OBJECT_TYPE_PORT,
attr_id,
&capability
);

auto meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_PORT, attr_id);
std::string attr_id_str = std::to_string(attr_id);
const char* attr_name = meta ? meta->attridname : attr_id_str.c_str();

if (status == SAI_STATUS_SUCCESS && capability.get_implemented)
{
m_supported_phy_attrs.push_back(attr_id);
SWSS_LOG_NOTICE("PORT_ATTR: Attribute %s is SUPPORTED for GET",
attr_name);
}
else
{
SWSS_LOG_NOTICE("PORT_ATTR: Attribute %s is NOT supported (status=%d, get_implemented=%d)",
attr_name, status, capability.get_implemented);
}
//TODO: remove the next line once brcm support attribute query capability
m_supported_phy_attrs.push_back(attr_id);
}

m_phy_attr_capability_checked = true;
}

bool PortsOrch::supportsPortAttr(sai_object_id_t port_id, const char* port_name)
{
// Verify port supports ALL SERDES attributes
// Query with count=0 to check if attribute is supported (expect BUFFER_OVERFLOW)

// Check RX_SIGNAL_DETECT
sai_attribute_t test_attr;
test_attr.id = SAI_PORT_ATTR_RX_SIGNAL_DETECT;
test_attr.value.portlanelatchstatuslist.count = 0;
test_attr.value.portlanelatchstatuslist.list = nullptr;

sai_status_t status = sai_port_api->get_port_attribute(port_id, 1, &test_attr);
if (status != SAI_STATUS_BUFFER_OVERFLOW)
{
SWSS_LOG_ERROR("PORT_ATTR: Port %s does not support RX_SIGNAL_DETECT attribute (status=%d)",
port_name, status);
return false;
}
SWSS_LOG_DEBUG("PORT_ATTR: Port %s supports RX_SIGNAL_DETECT attribute (count=%d)",
port_name, test_attr.value.portlanelatchstatuslist.count);

// Check FEC_ALIGNMENT_LOCK
test_attr.id = SAI_PORT_ATTR_FEC_ALIGNMENT_LOCK;
test_attr.value.portlanelatchstatuslist.count = 0;
test_attr.value.portlanelatchstatuslist.list = nullptr;

status = sai_port_api->get_port_attribute(port_id, 1, &test_attr);
if (status != SAI_STATUS_BUFFER_OVERFLOW)
{
SWSS_LOG_ERROR("PORT_ATTR: Port %s does not support FEC_ALIGNMENT_LOCK attribute (status=%d)",
port_name, status);
return false;
}
SWSS_LOG_DEBUG("PORT_ATTR: Port %s supports FEC_ALIGNMENT_LOCK attribute (count=%d)",
port_name, test_attr.value.portlanelatchstatuslist.count);

// Check RX_SNR
test_attr.id = SAI_PORT_ATTR_RX_SNR;
test_attr.value.portsnrlist.count = 0;
test_attr.value.portsnrlist.list = nullptr;

status = sai_port_api->get_port_attribute(port_id, 1, &test_attr);
if (status != SAI_STATUS_BUFFER_OVERFLOW)
{
SWSS_LOG_ERROR("PORT_ATTR: Port %s does not support RX_SNR attribute (status=%d)",
port_name, status);
return false;
}
SWSS_LOG_DEBUG("PORT_ATTR: Port %s supports RX_SNR attribute (count=%d)",
port_name, test_attr.value.portsnrlist.count);
return true;
}

void PortsOrch::generatePortAttrCounterMap()
{
if (m_isPortAttrCounterMapGenerated)
{
return;
}

queryPortAttrCapabilities();

if (m_supported_phy_attrs.empty())
{
SWSS_LOG_WARN("PORT_ATTR: No PHY attributes supported on this platform");
m_isPortAttrCounterMapGenerated = true;
return;
}

auto port_attr_stats = generateCounterStats(m_supported_phy_attrs, sai_serialize_port_attr);

for (const auto& it: m_portList)
{
if (it.second.m_type == Port::Type::PHY && supportsPortAttr(it.second.m_port_id, it.second.m_alias.c_str()))
{
SWSS_LOG_DEBUG("PORT_ATTR: Setting counter ID list for port %s",
it.second.m_alias.c_str());

port_attr_manager.setCounterIdList(it.second.m_port_id,
CounterType::PORT_ATTR, port_attr_stats);
}
}

m_isPortAttrCounterMapGenerated = true;
}

void PortsOrch::clearPortAttrCounterMap()
{
if (!m_isPortAttrCounterMapGenerated)
{
return;
}

for (const auto& it: m_portList)
{
// Clear counter stats only for PHY ports that were previously configured
if (it.second.m_type != Port::Type::PHY)
{
continue;
}

SWSS_LOG_DEBUG("PORT_ATTR: Clearing counter ID list for port %s", it.second.m_alias.c_str());

port_attr_manager.clearCounterIdList(it.second.m_port_id);
}

m_isPortAttrCounterMapGenerated = false;
}

const std::vector<sai_port_attr_t>& PortsOrch::getPortAttrIds() const
{
return port_attr_ids;
}

/****
* Func Name : generateWredPortCounterMap
* Parameters : None
Expand Down
Loading
Loading