Skip to content
Merged
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
1 change: 1 addition & 0 deletions orchagent/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ CFLAGS_SAI = -I /usr/include/sai
swssdir = $(datadir)/swss

dist_swss_DATA = \
nvda_port_trim_drop.lua \
eliminate_events.lua \
rif_rates.lua \
pfc_detect_marvell_teralynx.lua \
Expand Down
1 change: 1 addition & 0 deletions orchagent/flex_counter/flex_counter_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const unordered_map<CounterType, string> FlexCounterManager::counter_id_field_lo
{ CounterType::ENI, ENI_COUNTER_ID_LIST },
{ CounterType::DASH_METER, DASH_METER_COUNTER_ID_LIST },
{ CounterType::SRV6, SRV6_COUNTER_ID_LIST },
{ CounterType::SWITCH, SWITCH_COUNTER_ID_LIST },
};

FlexManagerDirectory g_FlexManagerDirectory;
Expand Down
3 changes: 2 additions & 1 deletion orchagent/flex_counter/flex_counter_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ enum class CounterType
ROUTE,
ENI,
DASH_METER,
SRV6
SRV6,
SWITCH,
};

extern bool gTraditionalFlexCounter;
Expand Down
50 changes: 32 additions & 18 deletions orchagent/flexcounterorch.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
#include <unordered_map>
#include "portsorch.h"
#include "fabricportsorch.h"
#include "select.h"

#include <select.h>
#include <tokenize.h>
#include <warm_restart.h>
#include <sai_serialize.h>

#include "notifier.h"
#include "sai_serialize.h"
#include "pfcwdorch.h"
#include "bufferorch.h"
#include "flexcounterorch.h"
#include "debugcounterorch.h"
#include "directory.h"

#include "bufferorch.h"
#include "copporch.h"
#include <swss/tokenize.h>
#include "routeorch.h"
#include "macsecorch.h"
#include "portsorch.h"
#include "pfcwdorch.h"
#include "routeorch.h"
#include "srv6orch.h"
#include "switchorch.h"
#include "debugcounterorch.h"
#include "fabricportsorch.h"

#include "dash/dashorch.h"
#include "dash/dashmeterorch.h"
#include "flowcounterrouteorch.h"
#include "warm_restart.h"
#include "flex_counter/flowcounterrouteorch.h"

#include "flexcounterorch.h"

extern sai_port_api_t *sai_port_api;
extern sai_switch_api_t *sai_switch_api;
Expand All @@ -29,6 +36,7 @@ extern Directory<Orch*> gDirectory;
extern CoppOrch *gCoppOrch;
extern FlowCounterRouteOrch *gFlowCounterRouteOrch;
extern Srv6Orch *gSrv6Orch;
extern SwitchOrch *gSwitchOrch;
extern sai_object_id_t gSwitchId;

#define FLEX_COUNTER_DELAY_SEC 60
Expand All @@ -50,6 +58,7 @@ extern sai_object_id_t gSwitchId;
#define WRED_QUEUE_KEY "WRED_ECN_QUEUE"
#define WRED_PORT_KEY "WRED_ECN_PORT"
#define SRV6_KEY "SRV6"
#define SWITCH_KEY "SWITCH"

unordered_map<string, string> flexCounterGroupMap =
{
Expand Down Expand Up @@ -77,6 +86,7 @@ unordered_map<string, string> flexCounterGroupMap =
{"WRED_ECN_PORT", WRED_PORT_STAT_COUNTER_FLEX_COUNTER_GROUP},
{"WRED_ECN_QUEUE", WRED_QUEUE_STAT_COUNTER_FLEX_COUNTER_GROUP},
{SRV6_KEY, SRV6_STAT_COUNTER_FLEX_COUNTER_GROUP},
{SWITCH_KEY, SWITCH_STAT_COUNTER_FLEX_COUNTER_GROUP}
};


Expand Down Expand Up @@ -219,17 +229,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 @@ -285,6 +295,10 @@ void FlexCounterOrch::doTask(Consumer &consumer)
{
gSrv6Orch->setCountersState((value == "enable"));
}
if (gSwitchOrch && (key == SWITCH_KEY) && (value == "enable"))
{
gSwitchOrch->generateSwitchCounterIdList();
}

if (gPortsOrch)
{
Expand Down
36 changes: 36 additions & 0 deletions orchagent/nvda_port_trim_drop.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-- 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]

-- Get configuration
redis.call('SELECT', counters_db)

-- For each port ID in KEYS
for _, port in ipairs(KEYS) do
-- Get current values from COUNTERS DB
local trim_packets = redis.call('HGET', counters_table_name .. ':' .. port, 'SAI_PORT_STAT_TRIM_PACKETS')
local trim_sent_packets = redis.call('HGET', counters_table_name .. ':' .. port, 'SAI_PORT_STAT_TX_TRIM_PACKETS')

if trim_packets and trim_sent_packets then
-- Calculate dropped packets
local dropped_packets = tonumber(trim_packets) - tonumber(trim_sent_packets)
-- Write result back to COUNTERS DB
redis.call('HSET', counters_table_name .. ':' .. port, 'SAI_PORT_STAT_DROPPED_TRIM_PACKETS', dropped_packets)
logit("Port " .. port .. " DROPPED_TRIM_PACKETS: " .. dropped_packets)
else
logit("Port " .. port .. " missing required counters")
end
end

return logtable
81 changes: 77 additions & 4 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#include <cstdlib>
#include <cstring>
#include <algorithm>

#include "portsorch.h"
#include "intfsorch.h"
#include "bufferorch.h"
Expand Down Expand Up @@ -257,7 +261,9 @@ const vector<sai_port_stat_t> port_stat_ids =
SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S14,
SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S15,
SAI_PORT_STAT_IF_IN_FEC_CORRECTED_BITS,
SAI_PORT_STAT_TRIM_PACKETS
SAI_PORT_STAT_TRIM_PACKETS,
SAI_PORT_STAT_DROPPED_TRIM_PACKETS,
SAI_PORT_STAT_TX_TRIM_PACKETS
};

const vector<sai_port_stat_t> gbport_stat_ids =
Expand Down Expand Up @@ -294,7 +300,9 @@ static const vector<sai_queue_stat_t> queue_stat_ids =
SAI_QUEUE_STAT_BYTES,
SAI_QUEUE_STAT_DROPPED_PACKETS,
SAI_QUEUE_STAT_DROPPED_BYTES,
SAI_QUEUE_STAT_TRIM_PACKETS
SAI_QUEUE_STAT_TRIM_PACKETS,
Copy link
Contributor

@dhanasekar-arista dhanasekar-arista Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nazariig TRIM specific stats are introducing more new SAI errors on non TH5 platforms, do you have plan to address this? @lolyu @aaronpayment @pandurangan-arista FYI.


2025 Aug 19 06:08:38.448632 gd231 ERR syncd#syncd: [none] SAI_API_SWITCH:_brcm_sai_xgs_pkt_trim_get_mapped_counter:102 Packet trim feature is not supported
2025 Aug 19 06:08:38.448632 gd231 ERR syncd#syncd: [none] SAI_API_QUEUE:_brcm_sai_xgs_queue_pkt_trim_get_clear_ctr:164 Get Trim mapped counter failed with error -2.
2025 Aug 19 06:08:38.448632 gd231 ERR syncd#syncd: [none] SAI_API_QUEUE:_brcm_sai_cosq_stat_get:1970 Get Trim stats packets failed with error -2.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dhanasekar-arista since feature is not supported, please make sure SAI returns the relevant stats capabilities. Then counter polling won't take place. The capabilities check is already part of the flex counter infra

SAI_QUEUE_STAT_DROPPED_TRIM_PACKETS,
SAI_QUEUE_STAT_TX_TRIM_PACKETS
};
static const vector<sai_queue_stat_t> voq_stat_ids =
{
Expand Down Expand Up @@ -540,6 +548,56 @@ bool PortsOrch::checkPathTracingCapability()
return m_isPathTracingSupported;
}

static bool isPortStatSupported(sai_port_stat_t stat)
{
static std::vector<sai_stat_capability_t> statList;

if (statList.empty())
{
sai_stat_capability_list_t capList = { .count = 0, .list = nullptr };

auto status = sai_query_stats_capability(gSwitchId, SAI_OBJECT_TYPE_PORT, &capList);
if ((status != SAI_STATUS_SUCCESS) && (status != SAI_STATUS_BUFFER_OVERFLOW))
{
return false;
}

statList.resize(capList.count);
capList.list = statList.data();

status = sai_query_stats_capability(gSwitchId, SAI_OBJECT_TYPE_PORT, &capList);
if (status != SAI_STATUS_SUCCESS)
{
return false;
}
}

return std::any_of(
statList.cbegin(),
statList.cend(),
[stat](const sai_stat_capability_t &cap) {
return static_cast<sai_port_stat_t>(cap.stat_enum) == stat;
}
);
}

static bool isMlnxPlatform()
{
const auto *platform = std::getenv("platform");
if (platform == nullptr)
{
return false;
}

const auto *result = std::strstr(platform, MLNX_PLATFORM_SUBSTRING);
if (result == nullptr)
{
return false;
}

return true;
}

// Port OA ------------------------------------------------------------------------------------------------------------

/*
Expand Down Expand Up @@ -627,10 +685,11 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi

initGearbox();

string queueWmSha, pgWmSha, portRateSha;
string queueWmSha, pgWmSha, portRateSha, nvdaPortTrimSha;
string queueWmPluginName = "watermark_queue.lua";
string pgWmPluginName = "watermark_pg.lua";
string portRatePluginName = "port_rates.lua";
string nvdaPortTrimPluginName = "nvda_port_trim_drop.lua";

try
{
Expand All @@ -642,12 +701,26 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi

string portRateLuaScript = swss::loadLuaScript(portRatePluginName);
portRateSha = swss::loadRedisScript(m_counter_db.get(), portRateLuaScript);

string nvdaPortTrimLuaScript = swss::loadLuaScript(nvdaPortTrimPluginName);
nvdaPortTrimSha = swss::loadRedisScript(m_counter_db.get(), nvdaPortTrimLuaScript);
}
catch (const runtime_error &e)
{
SWSS_LOG_ERROR("Port flex counter groups were not set successfully: %s", e.what());
}

std::string portStatPlugins = portRateSha;

// Nvidia custom trim stat calculation
if (isMlnxPlatform() && \
isPortStatSupported(SAI_PORT_STAT_TRIM_PACKETS) && \
isPortStatSupported(SAI_PORT_STAT_TX_TRIM_PACKETS) && \
!isPortStatSupported(SAI_PORT_STAT_DROPPED_TRIM_PACKETS))
{
portStatPlugins += "," + nvdaPortTrimSha;
}

setFlexCounterGroupParameter(QUEUE_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP,
QUEUE_WATERMARK_FLEX_STAT_COUNTER_POLL_MSECS,
STATS_MODE_READ_AND_CLEAR,
Expand All @@ -664,7 +737,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
PORT_RATE_FLEX_COUNTER_POLLING_INTERVAL_MS,
STATS_MODE_READ,
PORT_PLUGIN_FIELD,
portRateSha);
portStatPlugins);

setFlexCounterGroupParameter(PG_DROP_STAT_COUNTER_FLEX_COUNTER_GROUP,
PG_DROP_FLEX_STAT_COUNTER_POLL_MSECS,
Expand Down
61 changes: 60 additions & 1 deletion orchagent/switchorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ extern CrmOrch *gCrmOrch;
extern event_handle_t g_events_handle;
extern string gMyAsicName;

// defines ------------------------------------------------------------------------------------------------------------

#define SWITCH_STAT_COUNTER_POLLING_INTERVAL_MS 60000

// constants ----------------------------------------------------------------------------------------------------------

static const vector<sai_switch_stat_t> switch_stat_ids =
{
SAI_SWITCH_STAT_DROPPED_TRIM_PACKETS,
SAI_SWITCH_STAT_TX_TRIM_PACKETS
};

const map<string, sai_switch_attr_t> switch_attribute_map =
{
{"fdb_unicast_miss_packet_action", SAI_SWITCH_ATTR_FDB_UNICAST_MISS_PACKET_ACTION},
Expand Down Expand Up @@ -95,6 +107,22 @@ const std::set<sai_switch_asic_sdk_health_category_t> switch_asic_sdk_health_eve

const std::set<std::string> switch_non_sai_attribute_set = {"ordered_ecmp"};

// functions ----------------------------------------------------------------------------------------------------------

static std::unordered_set<std::string> serializeSwitchCounterStats(const std::vector<sai_switch_stat_t> statIdList)
{
std::unordered_set<std::string> stats;

for (const auto &cit : statIdList)
{
stats.emplace(sai_serialize_switch_stat(cit));
}

return stats;
}

// Switch OA ----------------------------------------------------------------------------------------------------------

void SwitchOrch::set_switch_pfc_dlr_init_capability()
{
vector<FieldValueTuple> fvVector;
Expand Down Expand Up @@ -124,7 +152,8 @@ SwitchOrch::SwitchOrch(DBConnector *db, vector<TableConnector>& connectors, Tabl
m_asicSensorsTable(new Table(m_stateDb.get(), ASIC_TEMPERATURE_INFO_TABLE_NAME)),
m_sensorsPollerTimer (new SelectableTimer((timespec { .tv_sec = DEFAULT_ASIC_SENSORS_POLLER_INTERVAL, .tv_nsec = 0 }))),
m_stateDbForNotification(new DBConnector("STATE_DB", 0)),
m_asicSdkHealthEventTable(new Table(m_stateDbForNotification.get(), STATE_ASIC_SDK_HEALTH_EVENT_TABLE_NAME))
m_asicSdkHealthEventTable(new Table(m_stateDbForNotification.get(), STATE_ASIC_SDK_HEALTH_EVENT_TABLE_NAME)),
m_counterManager(SWITCH_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ, SWITCH_STAT_COUNTER_POLLING_INTERVAL_MS, false)
{
m_restartCheckNotificationConsumer = new NotificationConsumer(db, "RESTARTCHECK");
auto restartCheckNotifier = new Notifier(m_restartCheckNotificationConsumer, this, "RESTARTCHECK");
Expand All @@ -142,6 +171,36 @@ SwitchOrch::SwitchOrch(DBConnector *db, vector<TableConnector>& connectors, Tabl
Orch::addExecutor(executorT);
}

void SwitchOrch::generateSwitchCounterNameMap() const
{
SWSS_LOG_ENTER();

DBConnector db("COUNTERS_DB", 0);
Table table(&db, COUNTERS_SWITCH_NAME_MAP);

FieldValueTuple tuple("ASIC", sai_serialize_object_id(gSwitchId));
std::vector<FieldValueTuple> fvList = { tuple };

table.set("", fvList);

SWSS_LOG_NOTICE("Wrote switch name mapping to Counters DB");
}

void SwitchOrch::generateSwitchCounterIdList()
{
if (m_isSwitchCounterIdListGenerated)
{
return;
}

auto switchStats = serializeSwitchCounterStats(switch_stat_ids);
m_counterManager.setCounterIdList(gSwitchId, CounterType::SWITCH, switchStats);

generateSwitchCounterNameMap();

m_isSwitchCounterIdListGenerated = true;
}

void SwitchOrch::initAsicSdkHealthEventNotification()
{
sai_attribute_t attr;
Expand Down
Loading
Loading