From f07748ba950179e68df4996a62964ece61c6676f Mon Sep 17 00:00:00 2001 From: Sean Wu Date: Tue, 5 Oct 2021 06:34:01 +0000 Subject: [PATCH 1/2] Fix get_change_event behavior * correct the wait and timeout mechanism for better CPU usage. * Models: AS7726-32X, AS5835-54X Signed-off-by: Sean Wu --- .../sonic_platform/chassis.py | 7 +-- .../sonic_platform/event.py | 45 +++++++++++-------- .../sonic_platform/chassis.py | 7 +-- .../sonic_platform/event.py | 45 +++++++++++-------- 4 files changed, 56 insertions(+), 48 deletions(-) diff --git a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/chassis.py index 92ef83d84552..c49cd425a108 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/chassis.py @@ -45,7 +45,6 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) self._api_helper = APIHelper() - self._api_helper = APIHelper() self.is_host = self._api_helper.is_host() self.config_data = {} @@ -62,6 +61,7 @@ def __initialize_sfp(self): for index in range(0, PORT_END): sfp = Sfp(index) self._sfp_list.append(sfp) + self._sfpevent = SfpEvent(self._sfp_list) self.sfp_module_initialized = True def __initialize_fan(self): @@ -193,10 +193,7 @@ def get_change_event(self, timeout=0): # SFP event if not self.sfp_module_initialized: self.__initialize_sfp() - - status, sfp_event = SfpEvent(self._sfp_list).get_sfp_event(timeout) - - return status, sfp_event + return self._sfpevent.get_sfp_event(timeout) def get_sfp(self, index): """ diff --git a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/event.py b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/event.py index d77ee8c29dc5..eb845c7e4aad 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/event.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/event.py @@ -5,6 +5,7 @@ except ImportError as e: raise ImportError(repr(e) + " - required module not found") +POLL_INTERVAL_IN_SEC = 1 class SfpEvent: ''' Listen to insert/remove sfp events ''' @@ -13,30 +14,38 @@ def __init__(self, sfp_list): self._api_helper = APIHelper() self._sfp_list = sfp_list self._logger = Logger() + self._sfp_change_event_data = {'present': 0} - sfp_change_event_data = {'valid': 0, 'last': 0, 'present': 0} - def get_sfp_event(self, timeout=2000): - now = time.time() - port_dict = {} - change_dict = {} - change_dict['sfp'] = port_dict - - if timeout < 1000: - timeout = 1000 - timeout = timeout / float(1000) # Convert to secs - - if now < (self.sfp_change_event_data['last'] + timeout) and self.sfp_change_event_data['valid']: - return True, change_dict - + def get_presence_bitmap(self): bitmap = 0 for sfp in self._sfp_list: modpres = sfp.get_presence() i=sfp.port_num-1 if modpres: bitmap = bitmap | (1 << i) + return bitmap - changed_ports = self.sfp_change_event_data['present'] ^ bitmap - if changed_ports: + def get_sfp_event(self, timeout=2000): + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + + if timeout < 1000: + cd_ms = 1000 + else: + cd_ms = timeout + + while cd_ms > 0: + bitmap = self.get_presence_bitmap() + changed_ports = self._sfp_change_event_data['present'] ^ bitmap + if changed_ports != 0: + break + time.sleep(POLL_INTERVAL_IN_SEC) + # timeout=0 means wait for event forever + if timeout != 0: + cd_ms = cd_ms - POLL_INTERVAL_IN_SEC * 1000 + + if changed_ports != 0: for sfp in self._sfp_list: i=sfp.port_num-1 if (changed_ports & (1 << i)): @@ -47,9 +56,7 @@ def get_sfp_event(self, timeout=2000): # Update the cache dict - self.sfp_change_event_data['present'] = bitmap - self.sfp_change_event_data['last'] = now - self.sfp_change_event_data['valid'] = 1 + self._sfp_change_event_data['present'] = bitmap return True, change_dict else: return True, change_dict diff --git a/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/chassis.py index 01d552382dc1..2d45976ed9fa 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/chassis.py @@ -35,7 +35,6 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) self._api_helper = APIHelper() - self._api_helper = APIHelper() self.is_host = self._api_helper.is_host() self.config_data = {} @@ -52,6 +51,7 @@ def __initialize_sfp(self): for index in range(0, NUM_PORT): sfp = Sfp(index) self._sfp_list.append(sfp) + self._sfpevent = SfpEvent(self._sfp_list) self.sfp_module_initialized = True def __initialize_fan(self): @@ -183,10 +183,7 @@ def get_change_event(self, timeout=0): # SFP event if not self.sfp_module_initialized: self.__initialize_sfp() - - status, sfp_event = SfpEvent(self._sfp_list).get_sfp_event(timeout) - - return status, sfp_event + return self._sfpevent.get_sfp_event(timeout) def get_sfp(self, index): """ diff --git a/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/event.py b/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/event.py index d77ee8c29dc5..eb845c7e4aad 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/event.py +++ b/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/event.py @@ -5,6 +5,7 @@ except ImportError as e: raise ImportError(repr(e) + " - required module not found") +POLL_INTERVAL_IN_SEC = 1 class SfpEvent: ''' Listen to insert/remove sfp events ''' @@ -13,30 +14,38 @@ def __init__(self, sfp_list): self._api_helper = APIHelper() self._sfp_list = sfp_list self._logger = Logger() + self._sfp_change_event_data = {'present': 0} - sfp_change_event_data = {'valid': 0, 'last': 0, 'present': 0} - def get_sfp_event(self, timeout=2000): - now = time.time() - port_dict = {} - change_dict = {} - change_dict['sfp'] = port_dict - - if timeout < 1000: - timeout = 1000 - timeout = timeout / float(1000) # Convert to secs - - if now < (self.sfp_change_event_data['last'] + timeout) and self.sfp_change_event_data['valid']: - return True, change_dict - + def get_presence_bitmap(self): bitmap = 0 for sfp in self._sfp_list: modpres = sfp.get_presence() i=sfp.port_num-1 if modpres: bitmap = bitmap | (1 << i) + return bitmap - changed_ports = self.sfp_change_event_data['present'] ^ bitmap - if changed_ports: + def get_sfp_event(self, timeout=2000): + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + + if timeout < 1000: + cd_ms = 1000 + else: + cd_ms = timeout + + while cd_ms > 0: + bitmap = self.get_presence_bitmap() + changed_ports = self._sfp_change_event_data['present'] ^ bitmap + if changed_ports != 0: + break + time.sleep(POLL_INTERVAL_IN_SEC) + # timeout=0 means wait for event forever + if timeout != 0: + cd_ms = cd_ms - POLL_INTERVAL_IN_SEC * 1000 + + if changed_ports != 0: for sfp in self._sfp_list: i=sfp.port_num-1 if (changed_ports & (1 << i)): @@ -47,9 +56,7 @@ def get_sfp_event(self, timeout=2000): # Update the cache dict - self.sfp_change_event_data['present'] = bitmap - self.sfp_change_event_data['last'] = now - self.sfp_change_event_data['valid'] = 1 + self._sfp_change_event_data['present'] = bitmap return True, change_dict else: return True, change_dict From b000cc3c6f6804e24d302538ad64dd2a53bee3dc Mon Sep 17 00:00:00 2001 From: Sean Wu Date: Wed, 6 Oct 2021 01:49:37 +0000 Subject: [PATCH 2/2] Fix is_host() API might make OS stuck * The original design will use 'docker' to check operating environment. But that command might get stuck occasionally when it is called in the context of 'determine-reboot-cause.service'. It is suspetced the reason why it gets stucked is related to the service status of 'containerd'. * Change to use 'which systemctl' to check operation environment. When systemctl exists, returns 0. (In Host os env) When it does not exist, returns 1. (In docker os env) Signed-off-by: Sean Wu --- .../x86_64-accton_as5835_54x-r0/sonic_platform/chassis.py | 2 +- .../accton/x86_64-accton_as5835_54x-r0/sonic_platform/helper.py | 2 +- device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/sfp.py | 2 +- .../x86_64-accton_as7726_32x-r0/sonic_platform/chassis.py | 2 +- .../accton/x86_64-accton_as7726_32x-r0/sonic_platform/helper.py | 2 +- device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/sfp.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/chassis.py index c49cd425a108..8966b2e2e5fa 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/chassis.py @@ -28,7 +28,7 @@ PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" REBOOT_CAUSE_FILE = "reboot-cause.txt" PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" -HOST_CHK_CMD = "docker > /dev/null 2>&1" +HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" SYSLED_FNODE= "/sys/class/leds/as5835_54x_led::diag/brightness" SYSLED_MODES = { diff --git a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/helper.py b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/helper.py index b124ca29f0df..90436db1525e 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/helper.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/helper.py @@ -4,7 +4,7 @@ from mmap import * from sonic_py_common import device_info -HOST_CHK_CMD = "docker > /dev/null 2>&1" +HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" EMPTY_STRING = "" diff --git a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/sfp.py index 145f67e2111e..a5f7771f0af5 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/sfp.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/sfp.py @@ -131,7 +131,7 @@ class Sfp(SfpBase): # Path to sysfs PLATFORM_ROOT_PATH = "/usr/share/sonic/device" PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" - HOST_CHK_CMD = "docker > /dev/null 2>&1" + HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" PLATFORM = "x86_64-accton_as5835_54x-r0" HWSKU = "Accton-AS5835-54X" diff --git a/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/chassis.py index 2d45976ed9fa..c1f902042d16 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/chassis.py @@ -26,7 +26,7 @@ PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" REBOOT_CAUSE_FILE = "reboot-cause.txt" PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" -HOST_CHK_CMD = "docker > /dev/null 2>&1" +HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" class Chassis(ChassisBase): diff --git a/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/helper.py b/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/helper.py index 4cd60ac90611..b9429919a197 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/helper.py +++ b/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/helper.py @@ -4,7 +4,7 @@ from mmap import * from sonic_py_common import device_info -HOST_CHK_CMD = "docker > /dev/null 2>&1" +HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" EMPTY_STRING = "" diff --git a/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/sfp.py index fdd11be0f253..4034ddb5dd86 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/sfp.py +++ b/device/accton/x86_64-accton_as7726_32x-r0/sonic_platform/sfp.py @@ -124,7 +124,7 @@ class Sfp(SfpBase): # Path to sysfs PLATFORM_ROOT_PATH = "/usr/share/sonic/device" PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" - HOST_CHK_CMD = "docker > /dev/null 2>&1" + HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" PLATFORM = "x86_64-accton_as7726_32x-r0" HWSKU = "Accton-AS7726-32X"