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

[Accton] Fix high CPU utilization caused by chassis.get_change_event() #8901

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
try:
from sonic_platform_base.chassis_base import ChassisBase
from .helper import APIHelper
from .event import SfpEvent
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

Expand All @@ -26,7 +27,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/diag/brightness"
SYSLED_MODES = {
"0" : "STATUS_LED_COLOR_OFF",
Expand All @@ -42,7 +43,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 = {}
Expand All @@ -59,6 +59,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):
Expand Down Expand Up @@ -176,6 +177,12 @@ def get_reboot_cause(self):

return ('REBOOT_CAUSE_NON_HARDWARE', sw_reboot_cause)

def get_change_event(self, timeout=0):
# SFP event
if not self.sfp_module_initialized:
self.__initialize_sfp()
return self._sfpevent.get_sfp_event(timeout)

def get_sfp(self, index):
"""
Retrieves sfp represented by (1-based) index <index>
Expand Down
62 changes: 62 additions & 0 deletions device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
try:
import time
from .helper import APIHelper
from sonic_py_common.logger import Logger
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 '''

def __init__(self, sfp_list):
self._api_helper = APIHelper()
self._sfp_list = sfp_list
self._logger = Logger()
self._sfp_change_event_data = {'present': 0}

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

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)):
if (bitmap & (1 << i)) == 0:
port_dict[i+1] = '0'
else:
port_dict[i+1] = '1'


# Update the cache dict
self._sfp_change_event_data['present'] = bitmap
return True, change_dict
else:
return True, change_dict
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ""


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,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_as4630_54te-r0"
HWSKU = "Accton-AS4630-54TE"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
try:
from sonic_platform_base.chassis_base import ChassisBase
from .helper import APIHelper
from .event import SfpEvent
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

Expand All @@ -28,7 +29,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):
Expand Down Expand Up @@ -59,6 +60,7 @@ def __initialize_sfp(self):
else:
sfp_module = Sfp(index, 'SFP')
self._sfp_list.append(sfp_module)
self._sfpevent = SfpEvent(self._sfp_list)
self.sfp_module_initialized = True

def __initialize_fan(self):
Expand Down Expand Up @@ -177,6 +179,12 @@ def get_reboot_cause(self):

return ('REBOOT_CAUSE_NON_HARDWARE', sw_reboot_cause)

def get_change_event(self, timeout=0):
# SFP event
if not self.sfp_module_initialized:
self.__initialize_sfp()
return self._sfpevent.get_sfp_event(timeout)

def get_sfp(self, index):
"""
Retrieves sfp represented by (1-based) index <index>
Expand Down
62 changes: 62 additions & 0 deletions device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
try:
import time
from .helper import APIHelper
from sonic_py_common.logger import Logger
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 '''

def __init__(self, sfp_list):
self._api_helper = APIHelper()
self._sfp_list = sfp_list
self._logger = Logger()
self._sfp_change_event_data = {'present': 0}

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

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)):
if (bitmap & (1 << i)) == 0:
port_dict[i+1] = '0'
else:
port_dict[i+1] = '1'


# Update the cache dict
self._sfp_change_event_data['present'] = bitmap
return True, change_dict
else:
return True, change_dict
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ""


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@

class Sfp(SfpBase):
"""Platform-specific Sfp class"""
HOST_CHK_CMD = "docker > /dev/null 2>&1"
HOST_CHK_CMD = "which systemctl > /dev/null 2>&1"
PLATFORM = "x86_64-accton_as9726_32d-r0"
HWSKU = "Accton-AS9726-32D"

Expand Down