From 5628de537ab42697c9510986c037cde3b42360e5 Mon Sep 17 00:00:00 2001 From: padmanarayana Date: Fri, 18 Jan 2019 01:57:06 -0800 Subject: [PATCH] [devices]: Make the get_transceiver_change_event's epoll blocking S6100/Z9100 (#2459) --- .../plugins/sfputil.py | 52 ++++++++++++++---- .../plugins/sfputil.py | 53 +++++++++++++++---- 2 files changed, 83 insertions(+), 22 deletions(-) diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/sfputil.py b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/sfputil.py index 04723b109a55..ff4426ba10c2 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/sfputil.py @@ -236,11 +236,6 @@ def __init__(self): self.port_to_eeprom_mapping[port_num] =\ "No IOM" - self.oir_fd = open(self.OIR_FD_PATH, "r") - self.epoll = select.epoll() - if self.oir_fd != -1: - self.epoll.register(self.oir_fd.fileno(), select.EPOLLIN) - SfpUtilBase.__init__(self) def __del__(self): @@ -582,13 +577,40 @@ def get_transceiver_change_event(self, timeout=0): port_dict = {} try: # We get notified when there is an SCI interrupt from GPIO SUS6 + # Open the sysfs file and register the epoll object + self.oir_fd = open(self.OIR_FD_PATH, "r") + if self.oir_fd != -1: + # Do a dummy read before epoll register + self.oir_fd.read() + self.epoll = select.epoll() + self.epoll.register(self.oir_fd.fileno(), + select.EPOLLIN & select.EPOLLET) + else: + print("get_transceiver_change_event : unable to create fd") + return False, {} + # Check for missed interrupts by invoking self.check_interrupts - # it will update the port_dict. - # Then poll for new xcvr insertion/removal and - # call self.check_interrupts again and return - retval, is_port_dict_updated = self.check_interrupts(port_dict) - if ((retval == 0) and (is_port_dict_updated is True)): - return True, port_dict + # which will update the port_dict. + while True: + interrupt_count_start = self.get_register(self.OIR_FD_PATH) + + retval, is_port_dict_updated = \ + self.check_interrupts(port_dict) + if ((retval == 0) and (is_port_dict_updated is True)): + return True, port_dict + + interrupt_count_end = self.get_register(self.OIR_FD_PATH) + + if (interrupt_count_start == 'ERR' or + interrupt_count_end == 'ERR'): + print("get_transceiver_change_event : \ + unable to retrive interrupt count") + break + + # check_interrupts() itself may take upto 100s of msecs. + # We detect a missed interrupt based on the count + if interrupt_count_start == interrupt_count_end: + break # Block until an xcvr is inserted or removed with timeout = -1 events = self.epoll.poll( @@ -599,9 +621,17 @@ def get_transceiver_change_event(self, timeout=0): self.check_interrupts(port_dict) if (retval != 0): return False, {} + return True, port_dict except: return False, {} + finally: + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + self.oir_fd = -1 + self.epoll = -1 return False, {} diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py index b31a44ca1539..4cccfbb291f4 100644 --- a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/sfputil.py @@ -119,11 +119,6 @@ def __init__(self): self.port_to_i2c_mapping[x][0], self.port_to_i2c_mapping[x][1]) - self.oir_fd = open(self.OIR_FD_PATH, "r") - self.epoll = select.epoll() - if self.oir_fd != -1: - self.epoll.register(self.oir_fd.fileno(), select.EPOLLIN) - SfpUtilBase.__init__(self) def __del__(self): @@ -428,13 +423,40 @@ def get_transceiver_change_event(self, timeout=0): port_dict = {} try: # We get notified when there is an SCI interrupt from GPIO SUS6 + # Open the sysfs file and register the epoll object + self.oir_fd = open(self.OIR_FD_PATH, "r") + if self.oir_fd != -1: + # Do a dummy read before epoll register + self.oir_fd.read() + self.epoll = select.epoll() + self.epoll.register(self.oir_fd.fileno(), + select.EPOLLIN & select.EPOLLET) + else: + print("get_transceiver_change_event : unable to create fd") + return False, {} + # Check for missed interrupts by invoking self.check_interrupts - # it will update the port_dict. - # Then poll for new xcvr insertion/removal and - # call self.check_interrupts again and return - retval, is_port_dict_updated = self.check_interrupts(port_dict) - if ((retval == 0) and (is_port_dict_updated is True)): - return True, port_dict + # which will update the port_dict. + while True: + interrupt_count_start = self.get_register(self.OIR_FD_PATH) + + retval, is_port_dict_updated = \ + self.check_interrupts(port_dict) + if ((retval == 0) and (is_port_dict_updated is True)): + return True, port_dict + + interrupt_count_end = self.get_register(self.OIR_FD_PATH) + + if (interrupt_count_start == 'ERR' or + interrupt_count_end == 'ERR'): + print("get_transceiver_change_event : \ + unable to retrive interrupt count") + break + + # check_interrupts() itself may take upto 100s of msecs. + # We detect a missed interrupt based on the count + if interrupt_count_start == interrupt_count_end: + break # Block until an xcvr is inserted or removed with timeout = -1 events = self.epoll.poll( @@ -445,8 +467,17 @@ def get_transceiver_change_event(self, timeout=0): self.check_interrupts(port_dict) if (retval != 0): return False, {} + return True, port_dict except: return False, {} + finally: + if self.oir_fd != -1: + self.epoll.unregister(self.oir_fd.fileno()) + self.epoll.close() + self.oir_fd.close() + self.oir_fd = -1 + self.epoll = -1 + return False, {}