Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QoS] Support dynamic headroom calculation for Barefoot platforms #6151

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8381a27
[QoS] Support dynamic headroom calculation for Barefoot platforms
MariuszStachura Aug 11, 2022
d44f8c4
Merge branch 'master' into bfn-dhc
MariuszStachura Aug 31, 2022
6a37963
Use PG 6 in test_lossless_pg
MariuszStachura Aug 31, 2022
2611182
Remove unused variables
MariuszStachura Aug 31, 2022
e19d900
Merge branch 'master' into bfn-dhc
MariuszStachura Sep 1, 2022
d52c12e
Update tests/qos/test_buffer.py
MariuszStachura Sep 2, 2022
0b8c13c
Remove not needed if
MariuszStachura Sep 2, 2022
cbc3949
Do not disable log analyzer and get rid of not needed check
MariuszStachura Sep 2, 2022
019a14c
Merge branch 'master' into bfn-dhc
MariuszStachura Sep 16, 2022
18557ba
Merge branch 'master' of https://github.com/Azure/sonic-mgmt into bfn…
MariuszStachura Sep 19, 2022
243e638
Exclude all changes not related to dynamic buffer calculation
MariuszStachura Sep 23, 2022
bbc66f1
Merge branch 'master' into bfn-dhc
MariuszStachura Sep 23, 2022
4101f27
Merge branch 'master' into bfn-dhc
MariuszStachura Sep 23, 2022
85e768d
Change not needed
MariuszStachura Sep 23, 2022
78ed3dc
Merge branch 'master' into bfn-dhc
MariuszStachura Sep 28, 2022
1967c07
Fix pre-commit issues
MariuszStachura Oct 19, 2022
d9bc310
Merge branch 'master' into bfn-dhc
MariuszStachura Oct 19, 2022
b3a6b2a
Just some more formatting fixes after merge
MariuszStachura Oct 19, 2022
148dac8
Fix even more pre-commit checks
MariuszStachura Oct 19, 2022
fb31e77
Remove unused local variable 'asic_type'
MariuszStachura Oct 19, 2022
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
5 changes: 3 additions & 2 deletions tests/common/config_reload.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def config_reload(duthost, config_source='config_db', wait=120, start_bgp=True,
logger.info('reloading {}'.format(config_source))

if config_source == 'minigraph':
if start_dynamic_buffer and duthost.facts['asic_type'] == 'mellanox':
if start_dynamic_buffer and duthost.facts['asic_type'] in ['mellanox', 'barefoot']:
output = duthost.shell('redis-cli -n 4 hget "DEVICE_METADATA|localhost" buffer_model', module_ignore_errors=True)
is_buffer_model_dynamic = (output and output.get('stdout') == 'dynamic')
else:
Expand All @@ -99,7 +99,8 @@ def config_reload(duthost, config_source='config_db', wait=120, start_bgp=True,
if start_bgp:
duthost.shell('config bgp startup all')
if is_buffer_model_dynamic:
duthost.shell('enable-dynamic-buffer.py')
duthost.copy(src="./common/helpers/enable-dynamic-buffer.py", dest="/tmp/enable-dynamic-buffer.py", mode="0755")
duthost.shell('/tmp/enable-dynamic-buffer.py')
duthost.shell('config save -y')

if config_source == 'config_db':
Expand Down
3 changes: 3 additions & 0 deletions tests/common/system_utils/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from tests.common import config_reload
from tests.common.utilities import wait_until
from tests.common.helpers.assertions import pytest_assert
from tests.common.barefoot_data import is_barefoot_device
from tests.common.broadcom_data import is_broadcom_device
from tests.common.mellanox_data import is_mellanox_device
from tests.common.errors import RunAnsibleModuleFail
Expand Down Expand Up @@ -219,6 +220,8 @@ def _get_vendor_id(duthost):
vendor_id = "brcm"
elif is_mellanox_device(duthost):
vendor_id = "mlnx"
elif is_barefoot_device(duthost):
vendor_id = "bfn"
elif is_cisco_device(duthost):
vendor_id = "cisco"
elif is_innovium_device(duthost):
Expand Down
178 changes: 178 additions & 0 deletions tests/qos/files/barefoot/qos_param_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import math

class QosParamBarefoot(object):
def __init__(self, qos_params, asic_type, speed_cable_len, dutConfig, ingressLosslessProfile, ingressLossyProfile, egressLosslessProfile, egressLossyProfile, sharedHeadroomPoolSize):
asic_param_dic = {
'tf1': {
'cell_size': 80,
},
'tf2': {
'cell_size': 176,
}
}

self.asic_type = asic_type
self.cell_size = asic_param_dic[asic_type]['cell_size']
self.speed_cable_len = speed_cable_len
self.lossless_profile = "pg_lossless_{}_profile".format(speed_cable_len)
self.pools_info = {}
self.qos_parameters = {}
self.qos_params_bfn = qos_params
self.qos_params_bfn[self.speed_cable_len] = self.qos_params_bfn['profile']
self.ingressLosslessProfile = ingressLosslessProfile
self.ingressLossyProfile = ingressLossyProfile
self.egressLosslessProfile = egressLosslessProfile
self.egressLossyProfile = egressLossyProfile
if sharedHeadroomPoolSize and int(sharedHeadroomPoolSize) != 0:
self.sharedHeadroomPoolSize = sharedHeadroomPoolSize
else:
self.sharedHeadroomPoolSize = None
self.dutConfig = dutConfig

return

def run(self):
"""
Main method of the class
Returns the dictionary containing all the parameters required for the qos test
"""
self.collect_qos_configurations()
self.calculate_parameters()
return self.qos_params_bfn

def collect_qos_configurations(self):
"""
Collect qos configuration from the following fixtures
ingressLosslessProfile
egressLossyProfile
"""
xon = int(math.ceil(float(self.ingressLosslessProfile['xon']) / self.cell_size))
xoff = int(math.ceil(float(self.ingressLosslessProfile['xoff']) / self.cell_size))

# For Shared Headroom Pool Size
headroom = xon + xoff
ingress_lossless_size = int(math.ceil(float(self.ingressLosslessProfile['static_th']) / self.cell_size)) - xon
hysteresis = headroom - (xon + xoff)

egress_lossy_size = int(math.ceil(float(self.egressLossyProfile['static_th']) / self.cell_size))

pkts_num_trig_pfc = ingress_lossless_size + xon + hysteresis
pkts_num_trig_ingr_drp = ingress_lossless_size + headroom

# For Shared Headroom Pool Size
pkts_num_trig_ingr_drp += xoff
pkts_num_dismiss_pfc = ingress_lossless_size + 1
pkts_num_trig_egr_drp = egress_lossy_size + 1

# For Shared Headroom Pool Size
testPortIds = self.dutConfig['testPortIds']
ingress_ports_num_shp = 8
pkts_num_trig_pfc_shp = []
ingress_ports_list_shp = []
occupancy_per_port = ingress_lossless_size
self.qos_parameters['dst_port_id'] = testPortIds[0]
for i in range(1, ingress_ports_num_shp):
# for the first PG
pkts_num_trig_pfc_shp.append(occupancy_per_port + xon + hysteresis)
# for the second PG
occupancy_per_port /= 2
pkts_num_trig_pfc_shp.append(occupancy_per_port + xon + hysteresis)
occupancy_per_port /= 2
ingress_ports_list_shp.append(testPortIds[i])
self.qos_parameters['pkts_num_trig_pfc_shp'] = pkts_num_trig_pfc_shp
self.qos_parameters['src_port_ids'] = ingress_ports_list_shp
self.qos_parameters['pkts_num_hdrm_full'] = xoff - 2
self.qos_parameters['pkts_num_hdrm_partial'] = xoff - 2

self.qos_parameters['pkts_num_trig_pfc'] = pkts_num_trig_pfc
self.qos_parameters['pkts_num_trig_ingr_drp'] = pkts_num_trig_ingr_drp
self.qos_parameters['pkts_num_dismiss_pfc'] = pkts_num_dismiss_pfc
self.qos_parameters['pkts_num_trig_egr_drp'] = pkts_num_trig_egr_drp
self.qos_parameters['pkts_num_hysteresis'] = hysteresis

def calculate_parameters(self):
"""
Generate qos test parameters based on the configuration
xon
xoff
wm_pg_headroom
wm_pg_shared_lossless
wm_q_shared_lossless
lossy_queue_1
wm_pg_shared_lossy
wm_q_shared_lossy
wm_buf_pool_lossless
wm_buf_pool_lossy
"""
pkts_num_trig_pfc = self.qos_parameters['pkts_num_trig_pfc']
pkts_num_trig_ingr_drp = self.qos_parameters['pkts_num_trig_ingr_drp']
pkts_num_dismiss_pfc = self.qos_parameters['pkts_num_dismiss_pfc']
pkts_num_trig_egr_drp = self.qos_parameters['pkts_num_trig_egr_drp']
pkts_num_hysteresis = self.qos_parameters['pkts_num_hysteresis']

# For Shared Headroom Pool Size
hdrm_pool_size = self.qos_params_bfn[self.speed_cable_len]['hdrm_pool_size']
hdrm_pool_size['pkts_num_trig_pfc_shp'] = self.qos_parameters['pkts_num_trig_pfc_shp']
hdrm_pool_size['pkts_num_hdrm_full'] = self.qos_parameters['pkts_num_hdrm_full']
hdrm_pool_size['pkts_num_hdrm_partial'] = self.qos_parameters['pkts_num_hdrm_partial']
hdrm_pool_size['dst_port_id'] = self.qos_parameters['dst_port_id']
hdrm_pool_size['src_port_ids'] = self.qos_parameters['src_port_ids']
hdrm_pool_size['pgs_num'] = 2 * len(self.qos_parameters['src_port_ids'])
hdrm_pool_size['cell_size'] = self.cell_size
hdrm_pool_size['margin'] = 3

xoff = {}
xoff['pkts_num_trig_pfc'] = pkts_num_trig_pfc
xoff['pkts_num_trig_ingr_drp'] = pkts_num_trig_ingr_drp
# One motivation of margin is to tolerance the deviation.
xoff['pkts_num_margin'] = 3
self.qos_params_bfn[self.speed_cable_len]['xoff_1'].update(xoff)
self.qos_params_bfn[self.speed_cable_len]['xoff_2'].update(xoff)

xon = {}
xon['pkts_num_trig_pfc'] = pkts_num_trig_pfc
xon['pkts_num_dismiss_pfc'] = pkts_num_dismiss_pfc + self.extra_margin
xon['pkts_num_hysteresis'] = pkts_num_hysteresis + 16
xon['pkts_num_margin'] = 3
self.qos_params_bfn['xon_1'].update(xon)
self.qos_params_bfn['xon_2'].update(xon)

wm_pg_headroom = self.qos_params_bfn[self.speed_cable_len]['wm_pg_headroom']
wm_pg_headroom['pkts_num_trig_pfc'] = pkts_num_trig_pfc
wm_pg_headroom['pkts_num_trig_ingr_drp'] = pkts_num_trig_ingr_drp
wm_pg_headroom['cell_size'] = self.cell_size
wm_pg_headroom['pkts_num_margin'] = 3

wm_pg_shared_lossless = self.qos_params_bfn['wm_pg_shared_lossless']
wm_pg_shared_lossless['pkts_num_trig_pfc'] = pkts_num_dismiss_pfc
wm_pg_shared_lossless['cell_size'] = self.cell_size
wm_pg_shared_lossless["pkts_num_margin"] = 3

wm_q_shared_lossless = self.qos_params_bfn[self.speed_cable_len]['wm_q_shared_lossless']
wm_q_shared_lossless['pkts_num_trig_ingr_drp'] = pkts_num_trig_ingr_drp
wm_q_shared_lossless['cell_size'] = self.cell_size

lossy_queue = self.qos_params_bfn['lossy_queue_1']
lossy_queue['pkts_num_trig_egr_drp'] = pkts_num_trig_egr_drp - 1
lossy_queue['cell_size'] = self.cell_size

wm_shared_lossy = {}
wm_shared_lossy['pkts_num_trig_egr_drp'] = pkts_num_trig_egr_drp
wm_shared_lossy['cell_size'] = self.cell_size
wm_shared_lossy["pkts_num_margin"] = 3
self.qos_params_bfn['wm_pg_shared_lossy'].update(wm_shared_lossy)
self.qos_params_bfn['wm_q_shared_lossy'].update(wm_shared_lossy)

wm_buf_pool_lossless = self.qos_params_bfn['wm_buf_pool_lossless']
wm_buf_pool_lossless['pkts_num_trig_pfc'] = pkts_num_trig_pfc
wm_buf_pool_lossless['pkts_num_trig_ingr_drp'] = pkts_num_trig_ingr_drp
wm_buf_pool_lossless['cell_size'] = self.cell_size

wm_buf_pool_lossy = self.qos_params_bfn['wm_buf_pool_lossy']
wm_buf_pool_lossy['pkts_num_trig_egr_drp'] = pkts_num_trig_egr_drp
wm_buf_pool_lossy['cell_size'] = self.cell_size

for i in range(4):
self.qos_params_bfn['ecn_{}'.format(i+1)]['cell_size'] = self.cell_size

self.qos_params_bfn['shared-headroom-pool'] = self.sharedHeadroomPoolSize
34 changes: 34 additions & 0 deletions tests/qos/files/dynamic_buffer_param.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,39 @@
"x86_64-nvidia_sn5600-r0": "800000",
"x86_64-nvidia_sn5600_simx-r0": "800000"
}
},
"barefoot": {
"default_cable_length": ["5m", "40m", "300m"],
"testparam_cable_length": ["15m", "40m"],
"headroom-override": {
"add": {
"xon": "18432",
"xoff": "18432",
"size": "36864",
"dynamic_th": "1"
},
"set": {
"xon": "18432",
"xoff": "36864",
"size": "55296"
}
},
"lossless_pg": {
"headroom-override": {
"xon": "18432",
"xoff": "16384",
"size": "34816"
},
"non-default-dynamic_th": {
"dynamic_th": "7"
}
},
"lossy_pg": {
"default": "4096"
},
"shared-headroom-pool": {
"size": "3153920",
"private_pg_headroom": "70400"
}
}
}
121 changes: 121 additions & 0 deletions tests/qos/files/qos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2364,3 +2364,124 @@ qos_params:
lossless_weight: 30
hdrm_pool_wm_multiplier: 1
cell_size: 384
tf2:
topo-any:
profile:
pkts_num_leak_out: 0
xoff_1:
dscp: 3
ecn: 1
pg: 3
xoff_2:
dscp: 4
ecn: 1
pg: 4
wm_pg_headroom:
dscp: 3
ecn: 1
pg: 3
pkts_num_leak_out: 0
wm_q_shared_lossless:
dscp: 3
ecn: 1
queue: 3
pkts_num_leak_out: 0
pkts_num_fill_min: 0
packet_size: 64
hdrm_pool_size:
dscps: [3, 4]
ecn: 1
pgs: [3, 4]
pkts_num_trig_pfc: 0
pkts_num_leak_out: 0
pkts_num_fill_min: 0
packet_size: 64
xon_1:
dscp: 3
ecn: 1
pg: 3
pkts_num_leak_out: 0
xon_2:
dscp: 4
ecn: 1
pg: 4
pkts_num_trig_pfc: 90752
pkts_num_dismiss_pfc: 13
pkts_num_leak_out: 0
wm_pg_shared_lossless:
dscp: 3
ecn: 1
pg: 3
pkts_num_fill_min: 10
pkts_num_trig_pfc: 90752
packet_size: 64
cell_size: 176
pkts_num_margin: 10
wm_pg_shared_lossy:
dscp: 8
ecn: 1
pg: 0
pkts_num_fill_min: 0
packet_size: 64
cell_size: 176
pkts_num_margin: 10
wm_q_shared_lossy:
dscp: 8
ecn: 1
queue: 0
pkts_num_fill_min: 7
cell_size: 176
wm_q_shared_lossless:
dscp: 3
ecn: 1
queue: 3
pkts_num_leak_out: 0
pkts_num_fill_min: 0
cell_size: 176
wm_buf_pool_lossless:
dscp: 3
ecn: 1
pg: 3
queue: 3
pkts_num_fill_ingr_min: 7
pkts_num_trig_pfc: 90752
pkts_num_trig_ingr_drp: 91048
pkts_num_fill_egr_min: 8
cell_size: 176
wm_buf_pool_lossy:
dscp: 8
ecn: 1
pg: 0
queue: 0
pkts_num_fill_ingr_min: 0
pkts_num_trig_egr_drp: 16283
pkts_num_fill_egr_min: 7
cell_size: 176
lossy_queue_1:
dscp: 8
ecn: 1
pg: 0
pkts_num_trig_egr_drp: 16690
pkts_num_margin: 10
wrr:
ecn: 1
q0_num_of_pkts: 140
q1_num_of_pkts: 140
q2_num_of_pkts: 140
q3_num_of_pkts: 150
q4_num_of_pkts: 150
q5_num_of_pkts: 140
q6_num_of_pkts: 140
limit: 80
wrr_chg:
ecn: 1
q0_num_of_pkts: 80
q1_num_of_pkts: 80
q2_num_of_pkts: 80
q3_num_of_pkts: 300
q4_num_of_pkts: 300
q5_num_of_pkts: 80
q6_num_of_pkts: 80
limit: 80
lossy_weight: 8
lossless_weight: 30
Loading