Skip to content

Commit 3e72fa4

Browse files
authored
Merge branch 'master' into dynamic_port_counters_support
2 parents 550fe05 + 4f6cb05 commit 3e72fa4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+6313
-855
lines changed

cfgmgr/buffer_check_headroom_mellanox.lua

+4-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ end
2222
-- Initialize the accumulative size with 4096
2323
-- This is to absorb the possible deviation
2424
local accumulative_size = 4096
25+
-- Egress mirror size: 2 * maximum MTU (10k)
26+
local egress_mirror_size = 20*1024
2527

2628
local appl_db = "0"
2729
local state_db = "6"
@@ -56,8 +58,9 @@ local pipeline_latency = tonumber(redis.call('HGET', asic_keys[1], 'pipeline_lat
5658
if is_port_with_8lanes(lanes) then
5759
-- The pipeline latency should be adjusted accordingly for ports with 2 buffer units
5860
pipeline_latency = pipeline_latency * 2 - 1
61+
egress_mirror_size = egress_mirror_size * 2
5962
end
60-
accumulative_size = accumulative_size + 2 * pipeline_latency * 1024
63+
accumulative_size = accumulative_size + 2 * pipeline_latency * 1024 + egress_mirror_size
6164

6265
-- Fetch all keys in BUFFER_PG according to the port
6366
redis.call('SELECT', appl_db)

cfgmgr/buffer_headroom_mellanox.lua

+24-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,23 @@ local state_db = "6"
3535

3636
local ret = {}
3737

38+
-- pause quanta should be taken for each operating speed is defined in IEEE 802.3 31B.3.7
39+
-- the key of table pause_quanta_per_speed is operating speed at Mb/s
40+
-- the value of table pause_quanta_per_speed is the number of pause_quanta
41+
local pause_quanta_per_speed = {}
42+
pause_quanta_per_speed[400000] = 905
43+
pause_quanta_per_speed[200000] = 453
44+
pause_quanta_per_speed[100000] = 394
45+
pause_quanta_per_speed[50000] = 147
46+
pause_quanta_per_speed[40000] = 118
47+
pause_quanta_per_speed[25000] = 80
48+
pause_quanta_per_speed[10000] = 67
49+
pause_quanta_per_speed[1000] = 2
50+
pause_quanta_per_speed[100] = 1
51+
52+
-- Get pause_quanta from the pause_quanta_per_speed table
53+
local pause_quanta = pause_quanta_per_speed[port_speed]
54+
3855
if gearbox_delay == nil then
3956
gearbox_delay = 0
4057
end
@@ -55,7 +72,8 @@ for i = 1, #asic_table_content, 2 do
5572
if asic_table_content[i] == "mac_phy_delay" then
5673
mac_phy_delay = tonumber(asic_table_content[i+1]) * 1024
5774
end
58-
if asic_table_content[i] == "peer_response_time" then
75+
-- If failed to get pause_quanta from the table, then use the default peer_response_time stored in state_db
76+
if asic_table_content[i] == "peer_response_time" and pause_quanta == nil then
5977
peer_response_time = tonumber(asic_table_content[i+1]) * 1024
6078
end
6179
end
@@ -124,6 +142,11 @@ else
124142
bytes_on_gearbox = port_speed * gearbox_delay / (8 * 1024)
125143
end
126144

145+
-- If successfully get pause_quanta from the table, then calculate peer_response_time from it
146+
if pause_quanta ~= nil then
147+
peer_response_time = (pause_quanta) * 512 / 8
148+
end
149+
127150
bytes_on_cable = 2 * cable_length * port_speed * 1000000000 / speed_of_light / (8 * 1024)
128151
propagation_delay = port_mtu + bytes_on_cable + 2 * bytes_on_gearbox + mac_phy_delay + peer_response_time
129152

cfgmgr/buffermgr.cpp

+77-35
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ BufferMgr::BufferMgr(DBConnector *cfgDb, DBConnector *applDb, string pg_lookup_f
3030
m_applBufferEgressProfileListTable(applDb, APP_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME)
3131
{
3232
readPgProfileLookupFile(pg_lookup_file);
33+
34+
char *platform = getenv("ASIC_VENDOR");
35+
if (NULL == platform)
36+
{
37+
SWSS_LOG_WARN("Platform environment variable is not defined");
38+
}
39+
else
40+
{
41+
m_platform = platform;
42+
}
43+
3344
dynamic_buffer_model = false;
3445
}
3546

@@ -122,9 +133,9 @@ Create/update two tables: profile (in m_cfgBufferProfileTable) and port buffer (
122133
}
123134
}
124135
*/
125-
task_process_status BufferMgr::doSpeedUpdateTask(string port)
136+
task_process_status BufferMgr::doSpeedUpdateTask(string port, bool admin_up)
126137
{
127-
vector<FieldValueTuple> fvVector;
138+
vector<FieldValueTuple> fvVectorPg, fvVectorProfile;
128139
string cable;
129140
string speed;
130141

@@ -142,20 +153,50 @@ task_process_status BufferMgr::doSpeedUpdateTask(string port)
142153
}
143154

144155
speed = m_speedLookup[port];
156+
157+
string buffer_pg_key = port + m_cfgBufferPgTable.getTableNameSeparator() + LOSSLESS_PGS;
158+
// key format is pg_lossless_<speed>_<cable>_profile
159+
string buffer_profile_key = "pg_lossless_" + speed + "_" + cable + "_profile";
160+
string profile_ref = buffer_profile_key;
161+
162+
m_cfgBufferPgTable.get(buffer_pg_key, fvVectorPg);
163+
164+
if (!admin_up && m_platform == "mellanox")
165+
{
166+
// Remove the entry in BUFFER_PG table if any
167+
if (!fvVectorPg.empty())
168+
{
169+
for (auto &prop : fvVectorPg)
170+
{
171+
if (fvField(prop) == "profile")
172+
{
173+
if (fvValue(prop) == profile_ref)
174+
{
175+
SWSS_LOG_NOTICE("Removing PG %s from port %s which is administrative down", buffer_pg_key.c_str(), port.c_str());
176+
m_cfgBufferPgTable.del(buffer_pg_key);
177+
}
178+
else
179+
{
180+
SWSS_LOG_NOTICE("Not default profile %s is configured on PG %s, won't reclaim buffer", fvValue(prop).c_str(), buffer_pg_key.c_str());
181+
}
182+
}
183+
}
184+
}
185+
186+
return task_process_status::task_success;
187+
}
188+
145189
if (m_pgProfileLookup.count(speed) == 0 || m_pgProfileLookup[speed].count(cable) == 0)
146190
{
147191
SWSS_LOG_ERROR("Unable to create/update PG profile for port %s. No PG profile configured for speed %s and cable length %s",
148192
port.c_str(), speed.c_str(), cable.c_str());
149193
return task_process_status::task_invalid_entry;
150194
}
151195

152-
// Crete record in BUFFER_PROFILE table
153-
// key format is pg_lossless_<speed>_<cable>_profile
154-
string buffer_profile_key = "pg_lossless_" + speed + "_" + cable + "_profile";
155-
156196
// check if profile already exists - if yes - skip creation
157-
m_cfgBufferProfileTable.get(buffer_profile_key, fvVector);
158-
if (fvVector.size() == 0)
197+
m_cfgBufferProfileTable.get(buffer_profile_key, fvVectorProfile);
198+
// Create record in BUFFER_PROFILE table
199+
if (fvVectorProfile.size() == 0)
159200
{
160201
SWSS_LOG_NOTICE("Creating new profile '%s'", buffer_profile_key.c_str());
161202

@@ -170,32 +211,24 @@ task_process_status BufferMgr::doSpeedUpdateTask(string port)
170211
// profile threshold field name
171212
mode += "_th";
172213

173-
fvVector.push_back(make_pair("pool", INGRESS_LOSSLESS_PG_POOL_NAME));
174-
fvVector.push_back(make_pair("xon", m_pgProfileLookup[speed][cable].xon));
214+
fvVectorProfile.push_back(make_pair("pool", INGRESS_LOSSLESS_PG_POOL_NAME));
215+
fvVectorProfile.push_back(make_pair("xon", m_pgProfileLookup[speed][cable].xon));
175216
if (m_pgProfileLookup[speed][cable].xon_offset.length() > 0) {
176-
fvVector.push_back(make_pair("xon_offset",
217+
fvVectorProfile.push_back(make_pair("xon_offset",
177218
m_pgProfileLookup[speed][cable].xon_offset));
178219
}
179-
fvVector.push_back(make_pair("xoff", m_pgProfileLookup[speed][cable].xoff));
180-
fvVector.push_back(make_pair("size", m_pgProfileLookup[speed][cable].size));
181-
fvVector.push_back(make_pair(mode, m_pgProfileLookup[speed][cable].threshold));
182-
m_cfgBufferProfileTable.set(buffer_profile_key, fvVector);
220+
fvVectorProfile.push_back(make_pair("xoff", m_pgProfileLookup[speed][cable].xoff));
221+
fvVectorProfile.push_back(make_pair("size", m_pgProfileLookup[speed][cable].size));
222+
fvVectorProfile.push_back(make_pair(mode, m_pgProfileLookup[speed][cable].threshold));
223+
m_cfgBufferProfileTable.set(buffer_profile_key, fvVectorProfile);
183224
}
184225
else
185226
{
186227
SWSS_LOG_NOTICE("Reusing existing profile '%s'", buffer_profile_key.c_str());
187228
}
188229

189-
fvVector.clear();
190-
191-
string buffer_pg_key = port + m_cfgBufferPgTable.getTableNameSeparator() + LOSSLESS_PGS;
192-
193-
string profile_ref = buffer_profile_key;
194-
195230
/* Check if PG Mapping is already then log message and return. */
196-
m_cfgBufferPgTable.get(buffer_pg_key, fvVector);
197-
198-
for (auto& prop : fvVector)
231+
for (auto& prop : fvVectorPg)
199232
{
200233
if ((fvField(prop) == "profile") && (profile_ref == fvValue(prop)))
201234
{
@@ -204,10 +237,10 @@ task_process_status BufferMgr::doSpeedUpdateTask(string port)
204237
}
205238
}
206239

207-
fvVector.clear();
240+
fvVectorPg.clear();
208241

209-
fvVector.push_back(make_pair("profile", profile_ref));
210-
m_cfgBufferPgTable.set(buffer_pg_key, fvVector);
242+
fvVectorPg.push_back(make_pair("profile", profile_ref));
243+
m_cfgBufferPgTable.set(buffer_pg_key, fvVectorPg);
211244
return task_process_status::task_success;
212245
}
213246

@@ -379,26 +412,35 @@ void BufferMgr::doTask(Consumer &consumer)
379412
task_process_status task_status = task_process_status::task_success;
380413
if (op == SET_COMMAND)
381414
{
382-
for (auto i : kfvFieldsValues(t))
415+
if (table_name == CFG_PORT_CABLE_LEN_TABLE_NAME)
383416
{
384-
if (table_name == CFG_PORT_CABLE_LEN_TABLE_NAME)
417+
// receive and cache cable length table
418+
for (auto i : kfvFieldsValues(t))
385419
{
386-
// receive and cache cable length table
387420
task_status = doCableTask(fvField(i), fvValue(i));
388421
}
389-
if (m_pgfile_processed && table_name == CFG_PORT_TABLE_NAME && (fvField(i) == "speed" || fvField(i) == "admin_status"))
422+
}
423+
else if (m_pgfile_processed && table_name == CFG_PORT_TABLE_NAME)
424+
{
425+
bool admin_up = false;
426+
for (auto i : kfvFieldsValues(t))
390427
{
391428
if (fvField(i) == "speed")
392429
{
393430
m_speedLookup[port] = fvValue(i);
394431
}
395-
396-
if (m_speedLookup.count(port) != 0)
432+
if (fvField(i) == "admin_status")
397433
{
398-
// create/update profile for port
399-
task_status = doSpeedUpdateTask(port);
434+
admin_up = ("up" == fvValue(i));
400435
}
401436
}
437+
438+
if (m_speedLookup.count(port) != 0)
439+
{
440+
// create/update profile for port
441+
task_status = doSpeedUpdateTask(port, admin_up);
442+
}
443+
402444
if (task_status != task_process_status::task_success)
403445
{
404446
break;

cfgmgr/buffermgr.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class BufferMgr : public Orch
3636
using Orch::doTask;
3737

3838
private:
39+
std::string m_platform;
40+
3941
Table m_cfgPortTable;
4042
Table m_cfgCableLenTable;
4143
Table m_cfgBufferProfileTable;
@@ -58,7 +60,7 @@ class BufferMgr : public Orch
5860
std::string getPgPoolMode();
5961
void readPgProfileLookupFile(std::string);
6062
task_process_status doCableTask(std::string port, std::string cable_length);
61-
task_process_status doSpeedUpdateTask(std::string port);
63+
task_process_status doSpeedUpdateTask(std::string port, bool admin_up);
6264
void doBufferTableTask(Consumer &consumer, ProducerStateTable &applTable);
6365

6466
void transformSeperator(std::string &name);

cfgmgr/buffermgrd.cpp

+24-13
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ mutex gDbMutex;
3838

3939
void usage()
4040
{
41-
cout << "Usage: buffermgrd <-l pg_lookup.ini|-a asic_table.json [-p peripheral_table.json]>" << endl;
41+
cout << "Usage: buffermgrd <-l pg_lookup.ini|-a asic_table.json [-p peripheral_table.json] [-z zero_profiles.json]>" << endl;
4242
cout << " -l pg_lookup.ini: PG profile look up table file (mandatory for static mode)" << endl;
4343
cout << " format: csv" << endl;
4444
cout << " values: 'speed, cable, size, xon, xoff, dynamic_threshold, xon_offset'" << endl;
4545
cout << " -a asic_table.json: ASIC-specific parameters definition (mandatory for dynamic mode)" << endl;
46-
cout << " -p peripheral_table.json: Peripheral (eg. gearbox) parameters definition (mandatory for dynamic mode)" << endl;
46+
cout << " -p peripheral_table.json: Peripheral (eg. gearbox) parameters definition (optional for dynamic mode)" << endl;
47+
cout << " -z zero_profiles.json: Zero profiles definition for reclaiming unused buffers (optional for dynamic mode)" << endl;
4748
}
4849

4950
void dump_db_item(KeyOpFieldsValuesTuple &db_item)
@@ -109,13 +110,13 @@ int main(int argc, char **argv)
109110
string pg_lookup_file = "";
110111
string asic_table_file = "";
111112
string peripherial_table_file = "";
112-
string json_file = "";
113+
string zero_profile_file = "";
113114
Logger::linkToDbNative("buffermgrd");
114115
SWSS_LOG_ENTER();
115116

116117
SWSS_LOG_NOTICE("--- Starting buffermgrd ---");
117118

118-
while ((opt = getopt(argc, argv, "l:a:p:h")) != -1 )
119+
while ((opt = getopt(argc, argv, "l:a:p:z:h")) != -1 )
119120
{
120121
switch (opt)
121122
{
@@ -131,6 +132,9 @@ int main(int argc, char **argv)
131132
case 'p':
132133
peripherial_table_file = optarg;
133134
break;
135+
case 'z':
136+
zero_profile_file = optarg;
137+
break;
134138
default: /* '?' */
135139
usage();
136140
return EXIT_FAILURE;
@@ -141,7 +145,9 @@ int main(int argc, char **argv)
141145
{
142146
std::vector<Orch *> cfgOrchList;
143147
bool dynamicMode = false;
144-
shared_ptr<vector<KeyOpFieldsValuesTuple>> db_items_ptr;
148+
shared_ptr<vector<KeyOpFieldsValuesTuple>> asic_table_ptr = nullptr;
149+
shared_ptr<vector<KeyOpFieldsValuesTuple>> peripherial_table_ptr = nullptr;
150+
shared_ptr<vector<KeyOpFieldsValuesTuple>> zero_profiles_ptr = nullptr;
145151

146152
DBConnector cfgDb("CONFIG_DB", 0);
147153
DBConnector stateDb("STATE_DB", 0);
@@ -150,18 +156,23 @@ int main(int argc, char **argv)
150156
if (!asic_table_file.empty())
151157
{
152158
// Load the json file containing the SWITCH_TABLE
153-
db_items_ptr = load_json(asic_table_file);
154-
if (nullptr != db_items_ptr)
159+
asic_table_ptr = load_json(asic_table_file);
160+
if (nullptr != asic_table_ptr)
155161
{
156-
write_to_state_db(db_items_ptr);
157-
db_items_ptr.reset();
162+
write_to_state_db(asic_table_ptr);
158163

159164
if (!peripherial_table_file.empty())
160165
{
161166
//Load the json file containing the PERIPHERIAL_TABLE
162-
db_items_ptr = load_json(peripherial_table_file);
163-
if (nullptr != db_items_ptr)
164-
write_to_state_db(db_items_ptr);
167+
peripherial_table_ptr = load_json(peripherial_table_file);
168+
if (nullptr != peripherial_table_ptr)
169+
write_to_state_db(peripherial_table_ptr);
170+
}
171+
172+
if (!zero_profile_file.empty())
173+
{
174+
//Load the json file containing the zero profiles
175+
zero_profiles_ptr = load_json(zero_profile_file);
165176
}
166177

167178
dynamicMode = true;
@@ -183,7 +194,7 @@ int main(int argc, char **argv)
183194
TableConnector(&stateDb, STATE_BUFFER_MAXIMUM_VALUE_TABLE),
184195
TableConnector(&stateDb, STATE_PORT_TABLE_NAME)
185196
};
186-
cfgOrchList.emplace_back(new BufferMgrDynamic(&cfgDb, &stateDb, &applDb, buffer_table_connectors, db_items_ptr));
197+
cfgOrchList.emplace_back(new BufferMgrDynamic(&cfgDb, &stateDb, &applDb, buffer_table_connectors, peripherial_table_ptr, zero_profiles_ptr));
187198
}
188199
else if (!pg_lookup_file.empty())
189200
{

cfgmgr/buffermgrdyn.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
using namespace std;
2828
using namespace swss;
2929

30-
BufferMgrDynamic::BufferMgrDynamic(DBConnector *cfgDb, DBConnector *stateDb, DBConnector *applDb, const vector<TableConnector> &tables, shared_ptr<vector<KeyOpFieldsValuesTuple>> gearboxInfo = nullptr) :
30+
BufferMgrDynamic::BufferMgrDynamic(DBConnector *cfgDb, DBConnector *stateDb, DBConnector *applDb, const vector<TableConnector> &tables, shared_ptr<vector<KeyOpFieldsValuesTuple>> gearboxInfo, shared_ptr<vector<KeyOpFieldsValuesTuple>> zeroProfilesInfo) :
3131
Orch(tables),
3232
m_platform(),
3333
m_applDb(applDb),

cfgmgr/buffermgrdyn.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ typedef std::map<std::string, std::string> gearbox_delay_t;
128128
class BufferMgrDynamic : public Orch
129129
{
130130
public:
131-
BufferMgrDynamic(DBConnector *cfgDb, DBConnector *stateDb, DBConnector *applDb, const std::vector<TableConnector> &tables, std::shared_ptr<std::vector<KeyOpFieldsValuesTuple>> gearboxInfo);
131+
BufferMgrDynamic(DBConnector *cfgDb, DBConnector *stateDb, DBConnector *applDb, const std::vector<TableConnector> &tables, std::shared_ptr<std::vector<KeyOpFieldsValuesTuple>> gearboxInfo, std::shared_ptr<std::vector<KeyOpFieldsValuesTuple>> zeroProfilesInfo);
132132
using Orch::doTask;
133133

134134
private:

cfgmgr/macsecmgr.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -547,10 +547,13 @@ bool MACsecMgr::isPortStateOk(const std::string & port_name)
547547

548548
std::vector<FieldValueTuple> temp;
549549
std::string state;
550+
std::string oper_status;
550551

551552
if (m_statePortTable.get(port_name, temp)
552553
&& get_value(temp, "state", state)
553-
&& state == "ok")
554+
&& state == "ok"
555+
&& get_value(temp, "netdev_oper_status", oper_status)
556+
&& oper_status == "up")
554557
{
555558
SWSS_LOG_DEBUG("Port '%s' is ready", port_name.c_str());
556559
return true;

0 commit comments

Comments
 (0)