Skip to content

Commit 9fcbd5e

Browse files
authored
fix possible cpld race access issue (#15371)
Why I did it fix possible cpld race read issue between watchdog and reboot cause process How I did it Use fcntl.flock to limit parallel access to cpld sys file How to verify it It can be simulated and verified with following python script ``` python3 import fcntl import signal import threading exit_flag = False def get_cpld_reg_value(getreg_path, register): file = open(getreg_path, 'w+') # Acquire an exclusive lock on the file fcntl.flock(file, fcntl.LOCK_EX) try: file.write(register + '\n') file.flush() # Seek to the beginning of the file file.seek(0) # Read the content of the file result = file.readline().strip() finally: # Release the lock and close the file fcntl.flock(file, fcntl.LOCK_UN) file.close() return result def cpld_read(thread_num, cpld_reg, expect_val): while not exit_flag: val = get_cpld_reg_value("/sys/devices/platform/dx010_cpld/getreg", cpld_reg) #print(f"Thread {thread_num}: get cpld reg {cpld_reg}, value {val}") if val != expect_val: print(f"Thread {thread_num}: get cpld reg {cpld_reg}, value {val}, expect_val {expect_val}") def signal_handler(sig, frame): global exit_flag print("Ctrl+C detected. Quitting...") exit_flag = True if __name__ == '__main__': # Register the signal handler for Ctrl+C signal.signal(signal.SIGINT, signal_handler) t1 = threading.Thread(target=cpld_read, args=(1, '0x103', '0x11',)) t2 = threading.Thread(target=cpld_read, args=(2, '0x141', '0x00',)) t1.start() t2.start() t1.join() t2.join() ```
1 parent 8a6d452 commit 9fcbd5e

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,13 @@ def __get_bios_version(self):
5151
except Exception as e:
5252
return None
5353

54-
def get_register_value(self, register):
55-
# Retrieves the cpld register value
56-
with open(GETREG_PATH, 'w') as file:
57-
file.write(register + '\n')
58-
with open(GETREG_PATH, 'r') as file:
59-
raw_data = file.readline()
60-
return raw_data.strip()
61-
6254
def __get_cpld_version(self):
6355
# Retrieves the CPLD firmware version
6456
cpld_version = dict()
6557
for cpld_name in CPLD_ADDR_MAPPING:
6658
try:
6759
cpld_addr = CPLD_ADDR_MAPPING[cpld_name]
68-
cpld_version_raw = self.get_register_value(cpld_addr)
60+
cpld_version_raw = self._api_helper.get_cpld_reg_value(GETREG_PATH, cpld_addr)
6961
cpld_version_str = "{}.{}".format(int(cpld_version_raw[2], 16), int(
7062
cpld_version_raw[3], 16)) if cpld_version_raw is not None else 'None'
7163
cpld_version[cpld_name] = cpld_version_str

device/celestica/x86_64-cel_seastone-r0/sonic_platform/helper.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import fcntl
12
import os
23
import struct
34
import subprocess
@@ -74,9 +75,23 @@ def write_txt_file(self, file_path, value):
7475
return True
7576

7677
def get_cpld_reg_value(self, getreg_path, register):
77-
with open(getreg_path, 'w') as file:
78+
file = open(getreg_path, 'w+')
79+
# Acquire an exclusive lock on the file
80+
fcntl.flock(file, fcntl.LOCK_EX)
81+
82+
try:
7883
file.write(register + '\n')
79-
with open(getreg_path, 'r') as file:
80-
result = file.readline()
84+
file.flush()
85+
86+
# Seek to the beginning of the file
87+
file.seek(0)
88+
89+
# Read the content of the file
90+
result = file.readline().strip()
91+
finally:
92+
# Release the lock and close the file
93+
fcntl.flock(file, fcntl.LOCK_UN)
94+
file.close()
95+
8196
return result
8297

0 commit comments

Comments
 (0)