Skip to content

Commit 45c1582

Browse files
[xcvrd] Optimize module initialization performance (#611)
1 parent bd83d52 commit 45c1582

File tree

3 files changed

+45
-48
lines changed

3 files changed

+45
-48
lines changed

sonic-xcvrd/tests/mock_swsscommon.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ def get(self, key):
3636
if key in self.mock_dict:
3737
return True, self.mock_dict[key]
3838
return False, None
39+
40+
def hget(self, key, field):
41+
if key in self.mock_dict:
42+
for fv in self.mock_dict[key]:
43+
if fv[0] == field:
44+
return True, fv[1]
45+
return False, None
3946

4047
def get_size(self):
4148
return (len(self.mock_dict))

sonic-xcvrd/tests/test_xcvrd.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -273,23 +273,24 @@ def test_CmisManagerTask_task_run_with_exception(self):
273273
@patch('xcvrd.xcvrd.get_cmis_application_desired', MagicMock(side_effect=KeyError))
274274
@patch('xcvrd.xcvrd.log_exception_traceback')
275275
@patch('xcvrd.xcvrd.XcvrTableHelper.get_status_sw_tbl')
276+
@patch('xcvrd.xcvrd.XcvrTableHelper.get_state_port_tbl')
276277
@patch('xcvrd.xcvrd.platform_chassis')
277-
def test_CmisManagerTask_get_xcvr_api_exception(self, mock_platform_chassis, mock_get_status_sw_tbl, mock_log_exception_traceback):
278+
def test_CmisManagerTask_get_xcvr_api_exception(self, mock_platform_chassis, mock_get_state_port_tbl, mock_get_status_sw_tbl, mock_log_exception_traceback):
278279
mock_get_status_sw_tbl = Table("STATE_DB", TRANSCEIVER_STATUS_SW_TABLE)
280+
mock_get_state_port_tbl.return_value = Table("APPL_DB", 'PORT_TABLE')
279281
mock_sfp = MagicMock()
280282
mock_sfp.get_presence.return_value = True
281283
mock_platform_chassis.get_sfp = MagicMock(return_value=mock_sfp)
282284
port_mapping = PortMapping()
283285
stop_event = threading.Event()
284286
task = CmisManagerTask(DEFAULT_NAMESPACE, port_mapping, stop_event)
285287
task.task_stopping_event.is_set = MagicMock(side_effect=[False, False, True])
286-
task.get_host_tx_status = MagicMock(return_value='true')
287-
task.get_port_admin_status = MagicMock(return_value='up')
288288
task.get_cfg_port_tbl = MagicMock()
289289
task.xcvr_table_helper = XcvrTableHelper(DEFAULT_NAMESPACE)
290290
task.xcvr_table_helper.get_status_sw_tbl.return_value = mock_get_status_sw_tbl
291291
port_change_event = PortChangeEvent('Ethernet0', 1, 0, PortChangeEvent.PORT_SET,
292-
{'speed':'400000', 'lanes':'1,2,3,4,5,6,7,8'})
292+
{'speed':'400000', 'lanes':'1,2,3,4,5,6,7,8',
293+
'admin_status':'up', 'host_tx_status':'true'})
293294

294295
# Case 1: get_xcvr_api() raises an exception
295296
task.on_port_update_event(port_change_event)
@@ -1079,14 +1080,13 @@ def test_del_port_sfp_dom_info_from_db(self):
10791080
del_port_sfp_dom_info_from_db(logical_port_name, port_mapping, [init_tbl, dom_tbl, dom_threshold_tbl, pm_tbl, firmware_info_tbl])
10801081
assert dom_tbl.get_size() == 0
10811082

1082-
@pytest.mark.parametrize("mock_found, mock_status_dict, expected_cmis_state", [
1083-
(True, {'cmis_state': CMIS_STATE_INSERTED}, CMIS_STATE_INSERTED),
1084-
(False, {}, CMIS_STATE_UNKNOWN),
1085-
(True, {'other_key': 'some_value'}, CMIS_STATE_UNKNOWN)
1083+
@pytest.mark.parametrize("mock_found, mock_state, expected_cmis_state", [
1084+
(True, CMIS_STATE_INSERTED, CMIS_STATE_INSERTED),
1085+
(False, None, CMIS_STATE_UNKNOWN)
10861086
])
1087-
def test_get_cmis_state_from_state_db(self, mock_found, mock_status_dict, expected_cmis_state):
1087+
def test_get_cmis_state_from_state_db(self, mock_found, mock_state, expected_cmis_state):
10881088
status_tbl = MagicMock()
1089-
status_tbl.get.return_value = (mock_found, mock_status_dict)
1089+
status_tbl.hget.return_value = (mock_found, mock_state)
10901090
assert get_cmis_state_from_state_db("Ethernet0", status_tbl) == expected_cmis_state
10911091

10921092
@patch('xcvrd.xcvrd_utilities.port_event_helper.PortMapping.logical_port_name_to_physical_port_list', MagicMock(return_value=[0]))
@@ -2264,7 +2264,7 @@ def test_CmisManagerTask_get_configured_freq(self, mock_table_helper):
22642264
stop_event = threading.Event()
22652265
task = CmisManagerTask(DEFAULT_NAMESPACE, port_mapping, stop_event)
22662266
cfg_port_tbl = MagicMock()
2267-
cfg_port_tbl.get = MagicMock(return_value=(True, (('laser_freq', 193100),)))
2267+
cfg_port_tbl.hget = MagicMock(return_value=(True, 193100))
22682268
mock_table_helper.get_cfg_port_tbl = MagicMock(return_value=cfg_port_tbl)
22692269
task.xcvr_table_helper = XcvrTableHelper(DEFAULT_NAMESPACE)
22702270
task.xcvr_table_helper.get_cfg_port_tbl = mock_table_helper.get_cfg_port_tbl
@@ -2276,7 +2276,7 @@ def test_CmisManagerTask_get_configured_tx_power_from_db(self, mock_table_helper
22762276
stop_event = threading.Event()
22772277
task = CmisManagerTask(DEFAULT_NAMESPACE, port_mapping, stop_event)
22782278
cfg_port_tbl = MagicMock()
2279-
cfg_port_tbl.get = MagicMock(return_value=(True, (('tx_power', -10),)))
2279+
cfg_port_tbl.hget = MagicMock(return_value=(True, -10))
22802280
mock_table_helper.get_cfg_port_tbl = MagicMock(return_value=cfg_port_tbl)
22812281
task.xcvr_table_helper = XcvrTableHelper(DEFAULT_NAMESPACE)
22822282
task.xcvr_table_helper.get_cfg_port_tbl = mock_table_helper.get_cfg_port_tbl

sonic-xcvrd/xcvrd/xcvrd.py

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,13 @@ def post_port_sfp_info_to_db(logical_port_name, port_mapping, table, transceiver
358358
ganged_member_num += 1
359359

360360
try:
361-
port_info_dict = _wrapper_get_transceiver_info(physical_port)
361+
if physical_port in transceiver_dict:
362+
port_info_dict = transceiver_dict[physical_port]
363+
else:
364+
port_info_dict = _wrapper_get_transceiver_info(physical_port)
365+
transceiver_dict[physical_port] = port_info_dict
362366
if port_info_dict is not None:
363367
is_replaceable = _wrapper_is_replaceable(physical_port)
364-
transceiver_dict[physical_port] = port_info_dict
365368
# if cmis is supported by the module
366369
if 'cmis_rev' in port_info_dict:
367370
fvs = swsscommon.FieldValuePairs(
@@ -437,11 +440,8 @@ def update_port_transceiver_status_table_sw(logical_port_name, status_sw_tbl, st
437440
status_sw_tbl.set(logical_port_name, fvs)
438441

439442
def get_cmis_state_from_state_db(lport, status_sw_tbl):
440-
found, transceiver_status_dict = status_sw_tbl.get(lport)
441-
if found and 'cmis_state' in dict(transceiver_status_dict):
442-
return dict(transceiver_status_dict)['cmis_state']
443-
else:
444-
return CMIS_STATE_UNKNOWN
443+
found, cmis_state = status_sw_tbl.hget(lport, 'cmis_state')
444+
return cmis_state if found else CMIS_STATE_UNKNOWN
445445

446446
# Delete port from SFP status table
447447

@@ -859,46 +859,31 @@ def get_configured_laser_freq_from_db(self, lport):
859859
"""
860860
Return the Tx power configured by user in CONFIG_DB's PORT table
861861
"""
862-
freq = 0
863862
port_tbl = self.xcvr_table_helper.get_cfg_port_tbl(self.get_asic_id(lport))
864863

865-
found, port_info = port_tbl.get(lport)
866-
if found and 'laser_freq' in dict(port_info):
867-
freq = dict(port_info)['laser_freq']
868-
return int(freq)
864+
found, laser_freq = port_tbl.hget(lport, 'laser_freq')
865+
return int(laser_freq) if found else 0
869866

870867
def get_configured_tx_power_from_db(self, lport):
871868
"""
872869
Return the Tx power configured by user in CONFIG_DB's PORT table
873870
"""
874-
power = 0
875871
port_tbl = self.xcvr_table_helper.get_cfg_port_tbl(self.get_asic_id(lport))
876872

877-
found, port_info = port_tbl.get(lport)
878-
if found and 'tx_power' in dict(port_info):
879-
power = dict(port_info)['tx_power']
880-
return float(power)
873+
found, power = port_tbl.hget(lport, 'tx_power')
874+
return float(power) if found else 0
881875

882876
def get_host_tx_status(self, lport):
883-
host_tx_ready = 'false'
884-
885877
state_port_tbl = self.xcvr_table_helper.get_state_port_tbl(self.get_asic_id(lport))
886878

887-
found, port_info = state_port_tbl.get(lport)
888-
if found and 'host_tx_ready' in dict(port_info):
889-
host_tx_ready = dict(port_info)['host_tx_ready']
890-
return host_tx_ready
879+
found, host_tx_ready = state_port_tbl.hget(lport, 'host_tx_ready')
880+
return host_tx_ready if found else 'false'
891881

892882
def get_port_admin_status(self, lport):
893-
admin_status = 'down'
894-
895883
cfg_port_tbl = self.xcvr_table_helper.get_cfg_port_tbl(self.get_asic_id(lport))
896884

897-
found, port_info = cfg_port_tbl.get(lport)
898-
if found:
899-
# Check admin_status too ...just in case
900-
admin_status = dict(port_info).get('admin_status', 'down')
901-
return admin_status
885+
found, admin_status = cfg_port_tbl.hget(lport, 'admin_status')
886+
return admin_status if found else 'down'
902887

903888
def configure_tx_output_power(self, api, lport, tx_power):
904889
min_p, max_p = api.get_supported_power_config()
@@ -1503,16 +1488,21 @@ def _post_port_sfp_info_and_dom_thr_to_db_once(self, port_mapping, xcvr_table_he
15031488
continue
15041489
rc = post_port_sfp_info_to_db(logical_port_name, port_mapping, xcvr_table_helper.get_intf_tbl(asic_index), transceiver_dict, stop_event)
15051490
if rc != SFP_EEPROM_NOT_READY:
1506-
self.dom_db_utils.post_port_dom_thresholds_to_db(logical_port_name)
1507-
# Read the VDM thresholds and post them to the DB
1508-
self.vdm_db_utils.post_port_vdm_thresholds_to_db(logical_port_name)
1509-
1510-
# Do not notify media settings during warm reboot to avoid dataplane traffic impact
15111491
if is_warm_start == False:
15121492
media_settings_parser.notify_media_setting(logical_port_name, transceiver_dict, xcvr_table_helper, port_mapping)
1513-
transceiver_dict.clear()
15141493
else:
15151494
retry_eeprom_set.add(logical_port_name)
1495+
1496+
dom_thresholds_cache = {}
1497+
vdm_thresholds_cache = {}
1498+
for logical_port_name in logical_port_list:
1499+
if stop_event.is_set():
1500+
break
1501+
1502+
if logical_port_name not in retry_eeprom_set:
1503+
self.dom_db_utils.post_port_dom_thresholds_to_db(logical_port_name, db_cache=dom_thresholds_cache)
1504+
# Read the VDM thresholds and post them to the DB
1505+
self.vdm_db_utils.post_port_vdm_thresholds_to_db(logical_port_name, db_cache=vdm_thresholds_cache)
15161506

15171507
return retry_eeprom_set
15181508

0 commit comments

Comments
 (0)