Skip to content

Commit 84642f3

Browse files
authored
[Dynamic buffer calculation][Mellanox] Enhance the logic to identify buffer pools and profiles (sonic-net#2498)
Signed-off-by: Stephen Sun <[email protected]> What I did Originally, it was assumed the names of all the buffer pools follow the community buffer pool name convention ({ingress|egress}_{lossless|lossy}_pool). The heuristic algorithm to identify buffer pools and profiles was designed based on the assumption. However, some users can define the buffer pool names in other ways, which breaks the logic in the Lua plugin and introduces degradation, the pool sizes of those pools can not be generated the additional reserved memory for lossy PG can not be calculated In this PR, the logic is improved to tolerate the case. Signed-off-by: Stephen Sun [email protected] How I verified it Manually and regression test. It has been covered by regression test and vs test. No new test case is required. Details if related Separate the buffer pools into two tables according to the direction. Iterate all the profiles, generating and recording the type (lossless/lossy) for each ingress profile which is identified by checking the pool it references Identify buffer profiles for lossy PG by checking the type (lossless/lossy) generated in 2 instead of the hardcoded name ingress_lossy_profile
1 parent e04bb43 commit 84642f3

File tree

1 file changed

+45
-15
lines changed

1 file changed

+45
-15
lines changed

cfgmgr/buffer_pool_mellanox.lua

+45-15
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ local port_count_8lanes = 0
1010
-- Number of lossy PG on ports with 8 lanes
1111
local lossypg_8lanes = 0
1212

13+
local ingress_profile_is_lossless = {}
14+
1315
-- Private headrom
1416
local private_headroom = 10 * 1024
1517

1618
local result = {}
1719
local profiles = {}
18-
local lossless_profiles = {}
1920

2021
local total_port = 0
2122

@@ -52,11 +53,11 @@ local function iterate_all_items(all_items, check_lossless)
5253
port = string.match(all_items[i], "Ethernet%d+")
5354
if port ~= nil then
5455
local range = string.match(all_items[i], "Ethernet%d+:([^%s]+)$")
55-
local profile_name = redis.call('HGET', all_items[i], 'profile')
56-
if not profile_name then
56+
local profile_name_without_table = redis.call('HGET', all_items[i], 'profile')
57+
if not profile_name_without_table then
5758
return 1
5859
end
59-
profile_name = "BUFFER_PROFILE_TABLE:" .. profile_name
60+
local profile_name = "BUFFER_PROFILE_TABLE:" .. profile_name_without_table
6061
local profile_ref_count = profiles[profile_name]
6162
if profile_ref_count == nil then
6263
-- Indicate an error in case the referenced profile hasn't been inserted or has been removed
@@ -71,10 +72,11 @@ local function iterate_all_items(all_items, check_lossless)
7172
size = 1 + tonumber(string.sub(range, -1)) - tonumber(string.sub(range, 1, 1))
7273
end
7374
profiles[profile_name] = profile_ref_count + size
74-
if port_set_8lanes[port] and profile_name == 'BUFFER_PROFILE_TABLE:ingress_lossy_profile' then
75+
if port_set_8lanes[port] and ingress_profile_is_lossless[profile_name] == false then
76+
-- Handle additional buffer reserved for lossy PG on 8-lane ports
7577
lossypg_8lanes = lossypg_8lanes + size
7678
end
77-
if check_lossless and lossless_profiles[profile_name] then
79+
if check_lossless and ingress_profile_is_lossless[profile_name] then
7880
if lossless_ports[port] == nil then
7981
lossless_port_count = lossless_port_count + 1
8082
lossless_ports[port] = true
@@ -113,7 +115,8 @@ local function iterate_profile_list(all_items)
113115
-- To distinguish both cases, a new name "ingress_lossy_profile_list" is introduced to indicate
114116
-- the profile is used by the profile list where its size should be zero.
115117
profile_name = 'BUFFER_PROFILE_TABLE:' .. profile_name
116-
if profile_name == 'BUFFER_PROFILE_TABLE:ingress_lossy_profile' then
118+
-- TODO CHECK ALL LOSSY PROFILES
119+
if ingress_profile_is_lossless[profile_name] == false then
117120
profile_name = profile_name .. '_list'
118121
if profiles[profile_name] == nil then
119122
profiles[profile_name] = 0
@@ -162,9 +165,25 @@ local function fetch_buffer_pool_size_from_appldb()
162165
end
163166
end
164167

168+
-- Main --
165169
-- Connect to CONFIG_DB
166170
redis.call('SELECT', config_db)
167171

172+
-- Parse all the pools and seperate them according to the direction
173+
local ipools = {}
174+
local epools = {}
175+
local pools = redis.call('KEYS', 'BUFFER_POOL|*')
176+
for i = 1, #pools, 1 do
177+
local type = redis.call('HGET', pools[i], 'type')
178+
if type == 'ingress' then
179+
table.insert(ipools, pools[i])
180+
else
181+
if type == 'egress' then
182+
table.insert(epools, pools[i])
183+
end
184+
end
185+
end
186+
168187
local ports_table = redis.call('KEYS', 'PORT|*')
169188

170189
total_port = #ports_table
@@ -250,9 +269,19 @@ redis.call('SELECT', appl_db)
250269
local all_profiles = redis.call('KEYS', 'BUFFER_PROFILE*')
251270
for i = 1, #all_profiles, 1 do
252271
if all_profiles[i] ~= "BUFFER_PROFILE_TABLE_KEY_SET" and all_profiles[i] ~= "BUFFER_PROFILE_TABLE_DEL_SET" then
253-
local xoff = redis.call('HGET', all_profiles[i], 'xoff')
254-
if xoff then
255-
lossless_profiles[all_profiles[i]] = true
272+
local pool = redis.call('HGET', all_profiles[i], 'pool')
273+
for j = 1, #ipools, 1 do
274+
if "BUFFER_POOL|" .. pool == ipools[j] then
275+
-- For ingress profiles, check whether it is lossless or lossy
276+
-- For lossy profiles, there is buffer implicitly reserved when they are applied on PGs
277+
local xoff = redis.call('HGET', all_profiles[i], 'xoff')
278+
if xoff then
279+
ingress_profile_is_lossless[all_profiles[i]] = true
280+
else
281+
ingress_profile_is_lossless[all_profiles[i]] = false
282+
end
283+
break
284+
end
256285
end
257286
profiles[all_profiles[i]] = 0
258287
end
@@ -289,9 +318,10 @@ local accumulative_xoff = 0
289318
for name in pairs(profiles) do
290319
if name ~= "BUFFER_PROFILE_TABLE_KEY_SET" and name ~= "BUFFER_PROFILE_TABLE_DEL_SET" then
291320
local size = tonumber(redis.call('HGET', name, 'size'))
292-
if size ~= nil then
293-
if name == "BUFFER_PROFILE_TABLE:ingress_lossy_profile" then
294-
size = size + lossypg_reserved
321+
if size ~= nil then
322+
-- Handle the implicitly reserved buffer for lossy profile applied on PG
323+
if ingress_profile_is_lossless[name] == false then
324+
size = size + lossypg_reserved
295325
end
296326
if size ~= 0 then
297327
if shp_enabled and shp_size == 0 then
@@ -304,6 +334,8 @@ for name in pairs(profiles) do
304334
accumulative_occupied_buffer = accumulative_occupied_buffer + size * profiles[name]
305335
end
306336
table.insert(statistics, {name, size, profiles[name]})
337+
else
338+
table.insert(statistics, {name, "-", profiles[name]})
307339
end
308340
end
309341
end
@@ -336,7 +368,6 @@ redis.call('SELECT', config_db)
336368

337369
-- Fetch all the pools that need update
338370
local pools_need_update = {}
339-
local ipools = redis.call('KEYS', 'BUFFER_POOL|ingress*')
340371
local ingress_pool_count = 0
341372
local ingress_lossless_pool_size = nil
342373
for i = 1, #ipools, 1 do
@@ -351,7 +382,6 @@ for i = 1, #ipools, 1 do
351382
end
352383
end
353384

354-
local epools = redis.call('KEYS', 'BUFFER_POOL|egress*')
355385
for i = 1, #epools, 1 do
356386
local size = redis.call('HGET', epools[i], 'size')
357387
if not size then

0 commit comments

Comments
 (0)