Skip to content

Commit e0c2055

Browse files
nazariiga114j0y
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 31f366c commit e0c2055

13 files changed

Lines changed: 547 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
@@ -52,6 +52,7 @@ const unordered_map<CounterType, string> FlexCounterManager::counter_id_field_lo
5252
{ CounterType::ENI, ENI_COUNTER_ID_LIST },
5353
{ CounterType::DASH_METER, DASH_METER_COUNTER_ID_LIST },
5454
{ CounterType::SRV6, SRV6_COUNTER_ID_LIST },
55+
{ CounterType::SWITCH, SWITCH_COUNTER_ID_LIST },
5556
};
5657

5758
FlexManagerDirectory g_FlexManagerDirectory;

orchagent/flex_counter/flex_counter_manager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ enum class CounterType
4040
ROUTE,
4141
ENI,
4242
DASH_METER,
43-
SRV6
43+
SRV6,
44+
SWITCH,
4445
};
4546

4647
extern bool gTraditionalFlexCounter;

orchagent/flexcounterorch.cpp

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +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"
1723
#include "dash/dashmeterorch.h"
18-
#include "flowcounterrouteorch.h"
19-
#include "warm_restart.h"
24+
#include "flex_counter/flowcounterrouteorch.h"
25+
26+
#include "flexcounterorch.h"
2027

2128
extern sai_port_api_t *sai_port_api;
2229
extern sai_switch_api_t *sai_switch_api;
@@ -29,6 +36,7 @@ extern Directory<Orch*> gDirectory;
2936
extern CoppOrch *gCoppOrch;
3037
extern FlowCounterRouteOrch *gFlowCounterRouteOrch;
3138
extern Srv6Orch *gSrv6Orch;
39+
extern SwitchOrch *gSwitchOrch;
3240
extern sai_object_id_t gSwitchId;
3341

3442
#define FLEX_COUNTER_DELAY_SEC 60
@@ -50,6 +58,7 @@ extern sai_object_id_t gSwitchId;
5058
#define WRED_QUEUE_KEY "WRED_ECN_QUEUE"
5159
#define WRED_PORT_KEY "WRED_ECN_PORT"
5260
#define SRV6_KEY "SRV6"
61+
#define SWITCH_KEY "SWITCH"
5362

5463
unordered_map<string, string> flexCounterGroupMap =
5564
{
@@ -77,6 +86,7 @@ unordered_map<string, string> flexCounterGroupMap =
7786
{"WRED_ECN_PORT", WRED_PORT_STAT_COUNTER_FLEX_COUNTER_GROUP},
7887
{"WRED_ECN_QUEUE", WRED_QUEUE_STAT_COUNTER_FLEX_COUNTER_GROUP},
7988
{SRV6_KEY, SRV6_STAT_COUNTER_FLEX_COUNTER_GROUP},
89+
{SWITCH_KEY, SWITCH_STAT_COUNTER_FLEX_COUNTER_GROUP}
8090
};
8191

8292

@@ -219,17 +229,17 @@ void FlexCounterOrch::doTask(Consumer &consumer)
219229
m_pg_watermark_enabled = true;
220230
gPortsOrch->addPriorityGroupWatermarkFlexCounters(getPgConfigurations());
221231
}
222-
else if(key == WRED_PORT_KEY)
223-
{
232+
else if(key == WRED_PORT_KEY)
233+
{
224234
gPortsOrch->generateWredPortCounterMap();
225235
m_wred_port_counter_enabled = true;
226-
}
227-
else if(key == WRED_QUEUE_KEY)
228-
{
236+
}
237+
else if(key == WRED_QUEUE_KEY)
238+
{
229239
gPortsOrch->generateQueueMap(getQueueConfigurations());
230240
m_wred_queue_counter_enabled = true;
231241
gPortsOrch->addWredQueueFlexCounters(getQueueConfigurations());
232-
}
242+
}
233243
}
234244
if(gIntfsOrch && (key == RIF_KEY) && (value == "enable"))
235245
{
@@ -285,6 +295,10 @@ void FlexCounterOrch::doTask(Consumer &consumer)
285295
{
286296
gSrv6Orch->setCountersState((value == "enable"));
287297
}
298+
if (gSwitchOrch && (key == SWITCH_KEY) && (value == "enable"))
299+
{
300+
gSwitchOrch->generateSwitchCounterIdList();
301+
}
288302

289303
if (gPortsOrch)
290304
{

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"
@@ -257,7 +261,9 @@ const vector<sai_port_stat_t> port_stat_ids =
257261
SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S14,
258262
SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S15,
259263
SAI_PORT_STAT_IF_IN_FEC_CORRECTED_BITS,
260-
SAI_PORT_STAT_TRIM_PACKETS
264+
SAI_PORT_STAT_TRIM_PACKETS,
265+
SAI_PORT_STAT_DROPPED_TRIM_PACKETS,
266+
SAI_PORT_STAT_TX_TRIM_PACKETS
261267
};
262268

263269
const vector<sai_port_stat_t> gbport_stat_ids =
@@ -294,7 +300,9 @@ static const vector<sai_queue_stat_t> queue_stat_ids =
294300
SAI_QUEUE_STAT_BYTES,
295301
SAI_QUEUE_STAT_DROPPED_PACKETS,
296302
SAI_QUEUE_STAT_DROPPED_BYTES,
297-
SAI_QUEUE_STAT_TRIM_PACKETS
303+
SAI_QUEUE_STAT_TRIM_PACKETS,
304+
SAI_QUEUE_STAT_DROPPED_TRIM_PACKETS,
305+
SAI_QUEUE_STAT_TX_TRIM_PACKETS
298306
};
299307
static const vector<sai_queue_stat_t> voq_stat_ids =
300308
{
@@ -540,6 +548,56 @@ bool PortsOrch::checkPathTracingCapability()
540548
return m_isPathTracingSupported;
541549
}
542550

551+
static bool isPortStatSupported(sai_port_stat_t stat)
552+
{
553+
static std::vector<sai_stat_capability_t> statList;
554+
555+
if (statList.empty())
556+
{
557+
sai_stat_capability_list_t capList = { .count = 0, .list = nullptr };
558+
559+
auto status = sai_query_stats_capability(gSwitchId, SAI_OBJECT_TYPE_PORT, &capList);
560+
if ((status != SAI_STATUS_SUCCESS) && (status != SAI_STATUS_BUFFER_OVERFLOW))
561+
{
562+
return false;
563+
}
564+
565+
statList.resize(capList.count);
566+
capList.list = statList.data();
567+
568+
status = sai_query_stats_capability(gSwitchId, SAI_OBJECT_TYPE_PORT, &capList);
569+
if (status != SAI_STATUS_SUCCESS)
570+
{
571+
return false;
572+
}
573+
}
574+
575+
return std::any_of(
576+
statList.cbegin(),
577+
statList.cend(),
578+
[stat](const sai_stat_capability_t &cap) {
579+
return static_cast<sai_port_stat_t>(cap.stat_enum) == stat;
580+
}
581+
);
582+
}
583+
584+
static bool isMlnxPlatform()
585+
{
586+
const auto *platform = std::getenv("platform");
587+
if (platform == nullptr)
588+
{
589+
return false;
590+
}
591+
592+
const auto *result = std::strstr(platform, MLNX_PLATFORM_SUBSTRING);
593+
if (result == nullptr)
594+
{
595+
return false;
596+
}
597+
598+
return true;
599+
}
600+
543601
// Port OA ------------------------------------------------------------------------------------------------------------
544602

545603
/*
@@ -627,10 +685,11 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
627685

628686
initGearbox();
629687

630-
string queueWmSha, pgWmSha, portRateSha;
688+
string queueWmSha, pgWmSha, portRateSha, nvdaPortTrimSha;
631689
string queueWmPluginName = "watermark_queue.lua";
632690
string pgWmPluginName = "watermark_pg.lua";
633691
string portRatePluginName = "port_rates.lua";
692+
string nvdaPortTrimPluginName = "nvda_port_trim_drop.lua";
634693

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

643702
string portRateLuaScript = swss::loadLuaScript(portRatePluginName);
644703
portRateSha = swss::loadRedisScript(m_counter_db.get(), portRateLuaScript);
704+
705+
string nvdaPortTrimLuaScript = swss::loadLuaScript(nvdaPortTrimPluginName);
706+
nvdaPortTrimSha = swss::loadRedisScript(m_counter_db.get(), nvdaPortTrimLuaScript);
645707
}
646708
catch (const runtime_error &e)
647709
{
648710
SWSS_LOG_ERROR("Port flex counter groups were not set successfully: %s", e.what());
649711
}
650712

713+
std::string portStatPlugins = portRateSha;
714+
715+
// Nvidia custom trim stat calculation
716+
if (isMlnxPlatform() && \
717+
isPortStatSupported(SAI_PORT_STAT_TRIM_PACKETS) && \
718+
isPortStatSupported(SAI_PORT_STAT_TX_TRIM_PACKETS) && \
719+
!isPortStatSupported(SAI_PORT_STAT_DROPPED_TRIM_PACKETS))
720+
{
721+
portStatPlugins += "," + nvdaPortTrimSha;
722+
}
723+
651724
setFlexCounterGroupParameter(QUEUE_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP,
652725
QUEUE_WATERMARK_FLEX_STAT_COUNTER_POLL_MSECS,
653726
STATS_MODE_READ_AND_CLEAR,
@@ -664,7 +737,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
664737
PORT_RATE_FLEX_COUNTER_POLLING_INTERVAL_MS,
665738
STATS_MODE_READ,
666739
PORT_PLUGIN_FIELD,
667-
portRateSha);
740+
portStatPlugins);
668741

669742
setFlexCounterGroupParameter(PG_DROP_STAT_COUNTER_FLEX_COUNTER_GROUP,
670743
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)