11import math
2+ import yaml
3+ import os
4+
5+ MELLANOX_QOS_CONFIG_FILE = os .path .join (os .path .dirname (os .path .abspath (__file__ )), "special_qos_config.yml" )
26
37
48class QosParamMellanox (object ):
@@ -65,6 +69,7 @@ def run(self):
6569 """
6670 self .collect_qos_configurations ()
6771 self .calculate_parameters ()
72+ self .update_special_qos_config ()
6873 return self .qos_params_mlnx
6974
7075 def collect_qos_configurations (self ):
@@ -81,6 +86,10 @@ def collect_qos_configurations(self):
8186 headroom = xon + xoff
8287 ingress_lossless_size = int (
8388 math .ceil (float (self .ingressLosslessProfile ['static_th' ]) / self .cell_size )) - xon
89+ if self .asic_type == "spc4" :
90+ pg_q_alpha = self .ingressLosslessProfile ['pg_q_alpha' ]
91+ port_alpha = self .ingressLosslessProfile ['port_alpha' ]
92+ pool_size = int (math .ceil (float (self .ingressLosslessProfile ['pool_size' ]) / self .cell_size ))
8493 else :
8594 headroom = size
8695 ingress_lossless_size = int (
@@ -89,6 +98,8 @@ def collect_qos_configurations(self):
8998
9099 egress_lossy_size = int (math .ceil (float (self .egressLossyProfile ['static_th' ]) / self .cell_size ))
91100
101+ ingess_lossy_size = int (math .ceil (float (self .ingressLossyProfile ['static_th' ]) / self .cell_size ))
102+
92103 pkts_num_trig_pfc = ingress_lossless_size + xon + hysteresis
93104 pkts_num_trig_ingr_drp = ingress_lossless_size + headroom
94105 if self .sharedHeadroomPoolSize :
@@ -98,7 +109,8 @@ def collect_qos_configurations(self):
98109 else :
99110 pkts_num_trig_ingr_drp -= self .headroom_overhead
100111 pkts_num_dismiss_pfc = ingress_lossless_size + 1
101- pkts_num_trig_egr_drp = egress_lossy_size + 1
112+ pkts_num_trig_egr_drp = egress_lossy_size + 1 if egress_lossy_size <= ingess_lossy_size \
113+ else ingess_lossy_size + 1
102114
103115 if self .sharedHeadroomPoolSize :
104116 src_testPortIds = self .dutConfig ['testPortIds' ][self .src_dut_index ][self .src_asic_index ]
@@ -109,11 +121,25 @@ def collect_qos_configurations(self):
109121 occupancy_per_port = ingress_lossless_size
110122 self .qos_parameters ['dst_port_id' ] = dst_testPortIds [0 ]
111123 pgs_per_port = 2 if not self .dualTor else 4
112- for i in range (1 , ingress_ports_num_shp ):
113- for j in range (pgs_per_port ):
114- pkts_num_trig_pfc_shp .append (occupancy_per_port + xon + hysteresis )
115- occupancy_per_port /= 2
116- ingress_ports_list_shp .append (src_testPortIds [i ])
124+ occupied_buffer = 0
125+ if self .asic_type == "spc4" :
126+ for i in range (1 , ingress_ports_num_shp ):
127+ for j in range (pgs_per_port ):
128+ pg_occupancy = int (math .ceil (
129+ (pg_q_alpha * port_alpha * (pool_size - occupied_buffer ) - pg_q_alpha * occupied_buffer )/ (
130+ 1 + pg_q_alpha * port_alpha + pg_q_alpha )))
131+ pkts_num_trig_pfc_shp .append (pg_occupancy + xon + hysteresis )
132+ occupied_buffer += pg_occupancy
133+ # For a new port it should be treated as a smaller pool with the occupancy being 0
134+ pool_size -= occupied_buffer
135+ occupied_buffer = 0
136+ ingress_ports_list_shp .append (src_testPortIds [i ])
137+ else :
138+ for i in range (1 , ingress_ports_num_shp ):
139+ for j in range (pgs_per_port ):
140+ pkts_num_trig_pfc_shp .append (occupancy_per_port + xon + hysteresis )
141+ occupancy_per_port //= 2
142+ ingress_ports_list_shp .append (src_testPortIds [i ])
117143 self .qos_parameters ['pkts_num_trig_pfc_shp' ] = pkts_num_trig_pfc_shp
118144 self .qos_parameters ['src_port_ids' ] = ingress_ports_list_shp
119145 self .qos_parameters ['pkts_num_hdrm_full' ] = xoff - 2
@@ -176,6 +202,7 @@ def calculate_parameters(self):
176202 xon ['pkts_num_hysteresis' ] = pkts_num_hysteresis + 16
177203 xon ['pkts_num_margin' ] = 3
178204 xon ['cell_size' ] = self .cell_size
205+
179206 self .qos_params_mlnx ['xon_1' ].update (xon )
180207 self .qos_params_mlnx ['xon_2' ].update (xon )
181208 self .qos_params_mlnx ['xon_3' ].update (xon )
@@ -201,15 +228,11 @@ def calculate_parameters(self):
201228 lossy_queue = self .qos_params_mlnx ['lossy_queue_1' ]
202229 lossy_queue ['pkts_num_trig_egr_drp' ] = pkts_num_trig_egr_drp - 1
203230 lossy_queue ['cell_size' ] = self .cell_size
204- if self .asic_type == "spc4" :
205- lossy_queue ['packet_size' ] = 600
206231
207232 wm_shared_lossy = {}
208233 wm_shared_lossy ['pkts_num_trig_egr_drp' ] = pkts_num_trig_egr_drp
209234 wm_shared_lossy ['cell_size' ] = self .cell_size
210- wm_shared_lossy ["pkts_num_margin" ] = 3
211- if self .asic_type == "spc4" :
212- wm_shared_lossy ["packet_size" ] = 600
235+ wm_shared_lossy ["pkts_num_margin" ] = 4
213236 self .qos_params_mlnx ['wm_pg_shared_lossy' ].update (wm_shared_lossy )
214237 wm_shared_lossy ["pkts_num_margin" ] = 8
215238 self .qos_params_mlnx ['wm_q_shared_lossy' ].update (wm_shared_lossy )
@@ -228,3 +251,33 @@ def calculate_parameters(self):
228251
229252 self .qos_params_mlnx ['shared-headroom-pool' ] = self .sharedHeadroomPoolSize
230253 self .qos_params_mlnx ['pkts_num_private_headrooom' ] = self .asic_param_dic [self .asic_type ]['private_headroom' ]
254+
255+ def update_special_qos_config (self ):
256+ """
257+ Update qos parameters based on the file of special_qos_config.yml
258+ The format of qos_special_config.yml is same to qos.yml,
259+ and it just list the parameter with different value for the specified asic_type
260+ """
261+ with open (MELLANOX_QOS_CONFIG_FILE ) as file :
262+ special_qos_config_data = yaml .load (file , Loader = yaml .FullLoader )
263+
264+ def update_dict_value (speical_qos_config_dict , qos_params_dict ):
265+ if speical_qos_config_dict :
266+ for key , value in speical_qos_config_dict .items ():
267+ if isinstance (value , dict ):
268+ update_dict_value (value , qos_params_dict [key ])
269+ else :
270+ qos_params_dict [key ] = value
271+
272+ special_qos_config = special_qos_config_data .get ("qos_params" ).get (self .asic_type , {})
273+ if special_qos_config :
274+ for qos_config_key , qos_config_value in special_qos_config .items ():
275+ qos_params_dict = self .qos_params_mlnx [self .speed_cable_len ] if qos_config_key == 'profile' \
276+ else self .qos_params_mlnx [qos_config_key ]
277+
278+ for sub_qos_config_key , sub_qos_config_value in qos_config_value .items ():
279+ if isinstance (sub_qos_config_value , dict ):
280+ if sub_qos_config_key in qos_params_dict :
281+ update_dict_value (sub_qos_config_value , qos_params_dict [sub_qos_config_key ])
282+ else :
283+ qos_params_dict [sub_qos_config_key ] = sub_qos_config_value
0 commit comments