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

[Mellanox] wait SFP ready when receive an insert event with module host management mode enabled #233

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,8 @@ def get_change_event_for_module_host_management_mode(self, timeout):
if fd_type == 'hw_present':
# event could be EVENT_NOT_PRESENT or EVENT_PRESENT
event = sfp.EVENT_NOT_PRESENT if fd_value == 0 else sfp.EVENT_PRESENT
if fd_value == 1:
s.processing_insert_event = True
s.on_event(event)
elif fd_type == 'present':
if str(fd_value) == sfp.SFP_STATUS_ERROR:
Expand Down
8 changes: 7 additions & 1 deletion platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ def __init__(self, sfp_index, sfp_type=None, slot_id=0, linecard_port_count=0, l
self.state = STATE_DOWN
else:
self.state = STATE_FCP_DOWN
self.processing_insert_event = False

def __str__(self):
return f'SFP {self.sdk_index}'
Expand Down Expand Up @@ -1504,7 +1505,12 @@ def action_on_start(cls, sfp):
sfp.set_hw_reset(1)
sfp.on_event(EVENT_RESET)
else:
sfp.on_event(EVENT_POWER_ON)
if not sfp.processing_insert_event:
sfp.on_event(EVENT_POWER_ON)
else:
sfp.processing_insert_event = False
logger.log_info(f'SFP {sfp.sdk_index} is processing insert event and needs to wait module ready')
sfp.on_event(EVENT_RESET)

@classmethod
def action_fcp_on_start(cls, sfp):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ def schedule_wait(self, sfp_index):
"""
logger.log_debug(f'SFP {sfp_index} is scheduled for waiting reset done')
with self.lock:
if len(self._wait_dict) == 0:
is_empty = True
is_empty = len(self._wait_dict) == 0

# The item will be expired in 3 seconds
self._wait_dict[sfp_index] = time.time() + self.WAIT_TIME

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,16 @@ def test_get_change_event_legacy(self, mock_status, mock_time, mock_create_poll,
_, change_event = c.get_change_event(timeout)
assert 'sfp' in change_event and sfp_index in change_event['sfp'] and change_event['sfp'][sfp_index] == '2'
assert 'sfp_error' in change_event and sfp_index in change_event['sfp_error'] and change_event['sfp_error'][sfp_index] == 'some error'


@mock.patch('sonic_platform.wait_sfp_ready_task.WaitSfpReadyTask.get_ready_set')
@mock.patch('sonic_platform.sfp.SFP.get_fd')
@mock.patch('select.poll')
@mock.patch('time.time')
@mock.patch('sonic_platform.device_data.DeviceDataManager.is_module_host_management_mode', mock.MagicMock(return_value=True))
@mock.patch('sonic_platform.device_data.DeviceDataManager.get_sfp_count', mock.MagicMock(return_value=1))
@mock.patch('sonic_platform.chassis.extract_RJ45_ports_index', mock.MagicMock(return_value=[]))
@mock.patch('sonic_platform.module_host_mgmt_initializer.ModuleHostMgmtInitializer.initialize', mock.MagicMock())
def test_get_change_event_for_module_host_management_mode(self, mock_time, mock_create_poll, mock_get_fd):
def test_get_change_event_for_module_host_management_mode(self, mock_time, mock_create_poll, mock_get_fd, mock_ready):
"""Test steps:
1. Simulate polling with no event
2. Simulate polling the first dummy event. (SDK always return a event when first polling the fd even if there is no change)
Expand Down Expand Up @@ -163,6 +164,7 @@ def get_fd(fd_type):
s.determine_control_type = mock.MagicMock(return_value=sfp.SFP_FW_CONTROL)
s.set_control_type = mock.MagicMock()
mock_time.side_effect = [0, timeout]
mock_ready.return_value = set([0])
mock_hw_present_file.read.return_value = sfp.SFP_STATUS_INSERTED
_, change_event = c.get_change_event(timeout)
assert 'sfp' in change_event and sfp_index in change_event['sfp'] and change_event['sfp'][sfp_index] == sfp.SFP_STATUS_INSERTED
Expand All @@ -173,6 +175,7 @@ def get_fd(fd_type):
print(c.registered_fds)

# error event, expect returning error
mock_ready.return_value = []
mock_time.side_effect = [0, timeout]
mock_poll.poll.return_value = [(3, 10)]
mock_present_file.read.return_value = sfp.SFP_STATUS_ERROR
Expand All @@ -193,6 +196,7 @@ def get_fd(fd_type):

# plug in a software control cable, expect returning insert event
mock_time.side_effect = [0, timeout]
mock_ready.return_value = set([0])
mock_poll.poll.return_value = [(1, 10)]
mock_hw_present_file.read.return_value = sfp.SFP_STATUS_INSERTED
s.determine_control_type.return_value = sfp.SFP_SW_CONTROL
Expand Down