Skip to content

Commit 6b76077

Browse files
nazariigkeboliu
authored andcommitted
[trim]: Add Packet Trimming Drop Counters to OA (sonic-net#3777)
* [trim]: Add Packet Trimming Drop Counters to OA Signed-off-by: Nazarii Hnydyn <[email protected]> * [trim]: Handle review comments Signed-off-by: Nazarii Hnydyn <[email protected]> --------- Signed-off-by: Nazarii Hnydyn <[email protected]>
1 parent ba5013b commit 6b76077

13 files changed

Lines changed: 549 additions & 45 deletions

orchagent/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ CFLAGS_SAI = -I /usr/include/sai
1515
swssdir = $(datadir)/swss
1616

1717
dist_swss_DATA = \
18+
nvda_port_trim_drop.lua \
1819
eliminate_events.lua \
1920
rif_rates.lua \
2021
pfc_detect_marvell_teralynx.lua \

orchagent/flex_counter/flex_counter_manager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const unordered_map<CounterType, string> FlexCounterManager::counter_id_field_lo
5151
{ CounterType::ROUTE, FLOW_COUNTER_ID_LIST },
5252
{ CounterType::ENI, ENI_COUNTER_ID_LIST },
5353
{ CounterType::SRV6, SRV6_COUNTER_ID_LIST },
54+
{ CounterType::SWITCH, SWITCH_COUNTER_ID_LIST },
5455
};
5556

5657
FlexManagerDirectory g_FlexManagerDirectory;

orchagent/flex_counter/flex_counter_manager.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ enum class CounterType
3939
HOSTIF_TRAP,
4040
ROUTE,
4141
ENI,
42-
SRV6
42+
DASH_METER,
43+
SRV6,
44+
SWITCH,
4345
};
4446

4547
extern bool gTraditionalFlexCounter;

orchagent/flexcounterorch.cpp

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
#include <unordered_map>
2-
#include "portsorch.h"
3-
#include "fabricportsorch.h"
4-
#include "select.h"
2+
3+
#include <select.h>
4+
#include <tokenize.h>
5+
#include <warm_restart.h>
6+
#include <sai_serialize.h>
7+
58
#include "notifier.h"
6-
#include "sai_serialize.h"
7-
#include "pfcwdorch.h"
8-
#include "bufferorch.h"
9-
#include "flexcounterorch.h"
10-
#include "debugcounterorch.h"
119
#include "directory.h"
10+
11+
#include "bufferorch.h"
1212
#include "copporch.h"
13-
#include <swss/tokenize.h>
14-
#include "routeorch.h"
1513
#include "macsecorch.h"
14+
#include "portsorch.h"
15+
#include "pfcwdorch.h"
16+
#include "routeorch.h"
17+
#include "srv6orch.h"
18+
#include "switchorch.h"
19+
#include "debugcounterorch.h"
20+
#include "fabricportsorch.h"
21+
1622
#include "dash/dashorch.h"
17-
#include "flowcounterrouteorch.h"
18-
#include "warm_restart.h"
23+
#include "dash/dashmeterorch.h"
24+
#include "flex_counter/flowcounterrouteorch.h"
25+
26+
#include "flexcounterorch.h"
1927

2028
extern sai_port_api_t *sai_port_api;
2129
extern sai_switch_api_t *sai_switch_api;
@@ -28,6 +36,7 @@ extern Directory<Orch*> gDirectory;
2836
extern CoppOrch *gCoppOrch;
2937
extern FlowCounterRouteOrch *gFlowCounterRouteOrch;
3038
extern Srv6Orch *gSrv6Orch;
39+
extern SwitchOrch *gSwitchOrch;
3140
extern sai_object_id_t gSwitchId;
3241

3342
#define FLEX_COUNTER_DELAY_SEC 60
@@ -48,6 +57,7 @@ extern sai_object_id_t gSwitchId;
4857
#define WRED_QUEUE_KEY "WRED_ECN_QUEUE"
4958
#define WRED_PORT_KEY "WRED_ECN_PORT"
5059
#define SRV6_KEY "SRV6"
60+
#define SWITCH_KEY "SWITCH"
5161

5262
unordered_map<string, string> flexCounterGroupMap =
5363
{
@@ -74,6 +84,7 @@ unordered_map<string, string> flexCounterGroupMap =
7484
{"WRED_ECN_PORT", WRED_PORT_STAT_COUNTER_FLEX_COUNTER_GROUP},
7585
{"WRED_ECN_QUEUE", WRED_QUEUE_STAT_COUNTER_FLEX_COUNTER_GROUP},
7686
{SRV6_KEY, SRV6_STAT_COUNTER_FLEX_COUNTER_GROUP},
87+
{SWITCH_KEY, SWITCH_STAT_COUNTER_FLEX_COUNTER_GROUP}
7788
};
7889

7990

@@ -215,17 +226,17 @@ void FlexCounterOrch::doTask(Consumer &consumer)
215226
m_pg_watermark_enabled = true;
216227
gPortsOrch->addPriorityGroupWatermarkFlexCounters(getPgConfigurations());
217228
}
218-
else if(key == WRED_PORT_KEY)
219-
{
229+
else if(key == WRED_PORT_KEY)
230+
{
220231
gPortsOrch->generateWredPortCounterMap();
221232
m_wred_port_counter_enabled = true;
222-
}
223-
else if(key == WRED_QUEUE_KEY)
224-
{
233+
}
234+
else if(key == WRED_QUEUE_KEY)
235+
{
225236
gPortsOrch->generateQueueMap(getQueueConfigurations());
226237
m_wred_queue_counter_enabled = true;
227238
gPortsOrch->addWredQueueFlexCounters(getQueueConfigurations());
228-
}
239+
}
229240
}
230241
if(gIntfsOrch && (key == RIF_KEY) && (value == "enable"))
231242
{
@@ -277,6 +288,10 @@ void FlexCounterOrch::doTask(Consumer &consumer)
277288
{
278289
gSrv6Orch->setCountersState((value == "enable"));
279290
}
291+
if (gSwitchOrch && (key == SWITCH_KEY) && (value == "enable"))
292+
{
293+
gSwitchOrch->generateSwitchCounterIdList();
294+
}
280295

281296
if (gPortsOrch)
282297
{

orchagent/nvda_port_trim_drop.lua

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-- KEYS - port IDs
2+
-- ARGV[1] - counters db index
3+
-- ARGV[2] - counters table name
4+
-- ARGV[3] - poll time interval
5+
-- return log
6+
7+
local logtable = {}
8+
9+
local function logit(msg)
10+
logtable[#logtable+1] = tostring(msg)
11+
end
12+
13+
local counters_db = ARGV[1]
14+
local counters_table_name = ARGV[2]
15+
16+
-- Get configuration
17+
redis.call('SELECT', counters_db)
18+
19+
-- For each port ID in KEYS
20+
for _, port in ipairs(KEYS) do
21+
-- Get current values from COUNTERS DB
22+
local trim_packets = redis.call('HGET', counters_table_name .. ':' .. port, 'SAI_PORT_STAT_TRIM_PACKETS')
23+
local trim_sent_packets = redis.call('HGET', counters_table_name .. ':' .. port, 'SAI_PORT_STAT_TX_TRIM_PACKETS')
24+
25+
if trim_packets and trim_sent_packets then
26+
-- Calculate dropped packets
27+
local dropped_packets = tonumber(trim_packets) - tonumber(trim_sent_packets)
28+
-- Write result back to COUNTERS DB
29+
redis.call('HSET', counters_table_name .. ':' .. port, 'SAI_PORT_STAT_DROPPED_TRIM_PACKETS', dropped_packets)
30+
logit("Port " .. port .. " DROPPED_TRIM_PACKETS: " .. dropped_packets)
31+
else
32+
logit("Port " .. port .. " missing required counters")
33+
end
34+
end
35+
36+
return logtable

orchagent/portsorch.cpp

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#include <cstdlib>
2+
#include <cstring>
3+
#include <algorithm>
4+
15
#include "portsorch.h"
26
#include "intfsorch.h"
37
#include "bufferorch.h"
@@ -302,7 +306,9 @@ const vector<sai_port_stat_t> port_stat_ids =
302306
SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S14,
303307
SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S15,
304308
SAI_PORT_STAT_IF_IN_FEC_CORRECTED_BITS,
305-
SAI_PORT_STAT_TRIM_PACKETS
309+
SAI_PORT_STAT_TRIM_PACKETS,
310+
SAI_PORT_STAT_DROPPED_TRIM_PACKETS,
311+
SAI_PORT_STAT_TX_TRIM_PACKETS
306312
};
307313

308314
const vector<sai_port_stat_t> gbport_stat_ids =
@@ -339,7 +345,9 @@ static const vector<sai_queue_stat_t> queue_stat_ids =
339345
SAI_QUEUE_STAT_BYTES,
340346
SAI_QUEUE_STAT_DROPPED_PACKETS,
341347
SAI_QUEUE_STAT_DROPPED_BYTES,
342-
SAI_QUEUE_STAT_TRIM_PACKETS
348+
SAI_QUEUE_STAT_TRIM_PACKETS,
349+
SAI_QUEUE_STAT_DROPPED_TRIM_PACKETS,
350+
SAI_QUEUE_STAT_TX_TRIM_PACKETS
343351
};
344352
static const vector<sai_queue_stat_t> voq_stat_ids =
345353
{
@@ -585,6 +593,56 @@ bool PortsOrch::checkPathTracingCapability()
585593
return m_isPathTracingSupported;
586594
}
587595

596+
static bool isPortStatSupported(sai_port_stat_t stat)
597+
{
598+
static std::vector<sai_stat_capability_t> statList;
599+
600+
if (statList.empty())
601+
{
602+
sai_stat_capability_list_t capList = { .count = 0, .list = nullptr };
603+
604+
auto status = sai_query_stats_capability(gSwitchId, SAI_OBJECT_TYPE_PORT, &capList);
605+
if ((status != SAI_STATUS_SUCCESS) && (status != SAI_STATUS_BUFFER_OVERFLOW))
606+
{
607+
return false;
608+
}
609+
610+
statList.resize(capList.count);
611+
capList.list = statList.data();
612+
613+
status = sai_query_stats_capability(gSwitchId, SAI_OBJECT_TYPE_PORT, &capList);
614+
if (status != SAI_STATUS_SUCCESS)
615+
{
616+
return false;
617+
}
618+
}
619+
620+
return std::any_of(
621+
statList.cbegin(),
622+
statList.cend(),
623+
[stat](const sai_stat_capability_t &cap) {
624+
return static_cast<sai_port_stat_t>(cap.stat_enum) == stat;
625+
}
626+
);
627+
}
628+
629+
static bool isMlnxPlatform()
630+
{
631+
const auto *platform = std::getenv("platform");
632+
if (platform == nullptr)
633+
{
634+
return false;
635+
}
636+
637+
const auto *result = std::strstr(platform, MLNX_PLATFORM_SUBSTRING);
638+
if (result == nullptr)
639+
{
640+
return false;
641+
}
642+
643+
return true;
644+
}
645+
588646
// Port OA ------------------------------------------------------------------------------------------------------------
589647

590648
/*
@@ -671,10 +729,11 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
671729

672730
initGearbox();
673731

674-
string queueWmSha, pgWmSha, portRateSha;
732+
string queueWmSha, pgWmSha, portRateSha, nvdaPortTrimSha;
675733
string queueWmPluginName = "watermark_queue.lua";
676734
string pgWmPluginName = "watermark_pg.lua";
677735
string portRatePluginName = "port_rates.lua";
736+
string nvdaPortTrimPluginName = "nvda_port_trim_drop.lua";
678737

679738
try
680739
{
@@ -686,12 +745,26 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
686745

687746
string portRateLuaScript = swss::loadLuaScript(portRatePluginName);
688747
portRateSha = swss::loadRedisScript(m_counter_db.get(), portRateLuaScript);
748+
749+
string nvdaPortTrimLuaScript = swss::loadLuaScript(nvdaPortTrimPluginName);
750+
nvdaPortTrimSha = swss::loadRedisScript(m_counter_db.get(), nvdaPortTrimLuaScript);
689751
}
690752
catch (const runtime_error &e)
691753
{
692754
SWSS_LOG_ERROR("Port flex counter groups were not set successfully: %s", e.what());
693755
}
694756

757+
std::string portStatPlugins = portRateSha;
758+
759+
// Nvidia custom trim stat calculation
760+
if (isMlnxPlatform() && \
761+
isPortStatSupported(SAI_PORT_STAT_TRIM_PACKETS) && \
762+
isPortStatSupported(SAI_PORT_STAT_TX_TRIM_PACKETS) && \
763+
!isPortStatSupported(SAI_PORT_STAT_DROPPED_TRIM_PACKETS))
764+
{
765+
portStatPlugins += "," + nvdaPortTrimSha;
766+
}
767+
695768
setFlexCounterGroupParameter(QUEUE_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP,
696769
QUEUE_WATERMARK_FLEX_STAT_COUNTER_POLL_MSECS,
697770
STATS_MODE_READ_AND_CLEAR,
@@ -708,7 +781,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
708781
PORT_RATE_FLEX_COUNTER_POLLING_INTERVAL_MS,
709782
STATS_MODE_READ,
710783
PORT_PLUGIN_FIELD,
711-
portRateSha);
784+
portStatPlugins);
712785

713786
setFlexCounterGroupParameter(PG_DROP_STAT_COUNTER_FLEX_COUNTER_GROUP,
714787
PG_DROP_FLEX_STAT_COUNTER_POLL_MSECS,

orchagent/switchorch.cpp

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ extern CrmOrch *gCrmOrch;
2727
extern event_handle_t g_events_handle;
2828
extern string gMyAsicName;
2929

30+
// defines ------------------------------------------------------------------------------------------------------------
31+
32+
#define SWITCH_STAT_COUNTER_POLLING_INTERVAL_MS 60000
33+
34+
// constants ----------------------------------------------------------------------------------------------------------
35+
36+
static const vector<sai_switch_stat_t> switch_stat_ids =
37+
{
38+
SAI_SWITCH_STAT_DROPPED_TRIM_PACKETS,
39+
SAI_SWITCH_STAT_TX_TRIM_PACKETS
40+
};
41+
3042
const map<string, sai_switch_attr_t> switch_attribute_map =
3143
{
3244
{"fdb_unicast_miss_packet_action", SAI_SWITCH_ATTR_FDB_UNICAST_MISS_PACKET_ACTION},
@@ -95,6 +107,22 @@ const std::set<sai_switch_asic_sdk_health_category_t> switch_asic_sdk_health_eve
95107

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

110+
// functions ----------------------------------------------------------------------------------------------------------
111+
112+
static std::unordered_set<std::string> serializeSwitchCounterStats(const std::vector<sai_switch_stat_t> statIdList)
113+
{
114+
std::unordered_set<std::string> stats;
115+
116+
for (const auto &cit : statIdList)
117+
{
118+
stats.emplace(sai_serialize_switch_stat(cit));
119+
}
120+
121+
return stats;
122+
}
123+
124+
// Switch OA ----------------------------------------------------------------------------------------------------------
125+
98126
void SwitchOrch::set_switch_pfc_dlr_init_capability()
99127
{
100128
vector<FieldValueTuple> fvVector;
@@ -124,7 +152,8 @@ SwitchOrch::SwitchOrch(DBConnector *db, vector<TableConnector>& connectors, Tabl
124152
m_asicSensorsTable(new Table(m_stateDb.get(), ASIC_TEMPERATURE_INFO_TABLE_NAME)),
125153
m_sensorsPollerTimer (new SelectableTimer((timespec { .tv_sec = DEFAULT_ASIC_SENSORS_POLLER_INTERVAL, .tv_nsec = 0 }))),
126154
m_stateDbForNotification(new DBConnector("STATE_DB", 0)),
127-
m_asicSdkHealthEventTable(new Table(m_stateDbForNotification.get(), STATE_ASIC_SDK_HEALTH_EVENT_TABLE_NAME))
155+
m_asicSdkHealthEventTable(new Table(m_stateDbForNotification.get(), STATE_ASIC_SDK_HEALTH_EVENT_TABLE_NAME)),
156+
m_counterManager(SWITCH_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ, SWITCH_STAT_COUNTER_POLLING_INTERVAL_MS, false)
128157
{
129158
m_restartCheckNotificationConsumer = new NotificationConsumer(db, "RESTARTCHECK");
130159
auto restartCheckNotifier = new Notifier(m_restartCheckNotificationConsumer, this, "RESTARTCHECK");
@@ -142,6 +171,36 @@ SwitchOrch::SwitchOrch(DBConnector *db, vector<TableConnector>& connectors, Tabl
142171
Orch::addExecutor(executorT);
143172
}
144173

174+
void SwitchOrch::generateSwitchCounterNameMap() const
175+
{
176+
SWSS_LOG_ENTER();
177+
178+
DBConnector db("COUNTERS_DB", 0);
179+
Table table(&db, COUNTERS_SWITCH_NAME_MAP);
180+
181+
FieldValueTuple tuple("ASIC", sai_serialize_object_id(gSwitchId));
182+
std::vector<FieldValueTuple> fvList = { tuple };
183+
184+
table.set("", fvList);
185+
186+
SWSS_LOG_NOTICE("Wrote switch name mapping to Counters DB");
187+
}
188+
189+
void SwitchOrch::generateSwitchCounterIdList()
190+
{
191+
if (m_isSwitchCounterIdListGenerated)
192+
{
193+
return;
194+
}
195+
196+
auto switchStats = serializeSwitchCounterStats(switch_stat_ids);
197+
m_counterManager.setCounterIdList(gSwitchId, CounterType::SWITCH, switchStats);
198+
199+
generateSwitchCounterNameMap();
200+
201+
m_isSwitchCounterIdListGenerated = true;
202+
}
203+
145204
void SwitchOrch::initAsicSdkHealthEventNotification()
146205
{
147206
sai_attribute_t attr;

0 commit comments

Comments
 (0)