From f65d46723cd0e2d3a9b1f788b0ffa51e7fd04f8b Mon Sep 17 00:00:00 2001 From: John Kacur Date: Thu, 23 May 2019 17:54:20 +0200 Subject: [PATCH 1/2] rteval: Check whether a cpu is online before adding it to the list Check whether a cpu is online before adding it to the list If sys online files exist, use them to determine if a cpu is online This is done in two places, misc.py, and also in systopology which is getting the cpus from the numa node in /sys/devices, including offline cpus Signed-off-by: John Kacur --- rteval/misc.py | 19 ++++++++++++++++++- rteval/systopology.py | 29 ++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/rteval/misc.py b/rteval/misc.py index 7c9991483728..a43a8964e061 100644 --- a/rteval/misc.py +++ b/rteval/misc.py @@ -36,7 +36,24 @@ def expand_cpulist(cpulist): return [ str(i) for i in list(set(result)) ] def online_cpus(): - return [ str(c.replace('/sys/devices/system/cpu/cpu', '')) for c in glob.glob('/sys/devices/system/cpu/cpu[0-9]*') ] + online_cpus = [] + # Check for the online file with cpu1 since cpu0 can't always be offlined + if os.path.exists('/sys/devices/system/cpu/cpu1/online'): + for c in glob.glob('/sys/devices/system/cpu/cpu[0-9]*'): + num = str(c.replace('/sys/devices/system/cpu/cpu','')) + # On some machine you can't turn off cpu0 + if not os.path.exists(c + '/online') and num == "0": + online_cpus.append(num) + else: + with open(c + '/online') as f: + is_online = f.read().rstrip('\n') + if is_online == "1": + online_cpus.append(num) + else: # use the old heuristic + for c in glob.glob('/sys/devices/system/cpu/cpu[0-9]*'): + num = str(c.replace('/sys/devices/system/cpu/cpu','')) + online_cpus.append(num) + return online_cpus def invert_cpulist(cpulist): return [ c for c in online_cpus() if c not in cpulist] diff --git a/rteval/systopology.py b/rteval/systopology.py index 97a6037e83aa..07674658df8e 100644 --- a/rteval/systopology.py +++ b/rteval/systopology.py @@ -45,6 +45,7 @@ class CpuList(object): self.cpulist = cpulist elif type(cpulist) is str: self.cpulist = self.__expand_cpulist(cpulist) + self.cpulist = self.online_cpulist(self.cpulist) self.cpulist.sort() def __str__(self): @@ -56,6 +57,10 @@ class CpuList(object): def __len__(self): return len(self.cpulist) + def online_file_exists(self): + if os.path.exists('/sys/devices/system/cpu/cpu1/online'): + return True + return False # return the index of the last element of a sequence # that steps by one @@ -68,7 +73,6 @@ class CpuList(object): return idx return lim - 1 - # # collapse a list of cpu numbers into a string range # of cpus (e.g. 0-5, 7, 9) @@ -110,15 +114,30 @@ class CpuList(object): return self.cpulist # check whether cpu n is online - def isonline(self, n): + def is_online(self, n): if n not in self.cpulist: raise RuntimeError("invalid cpu number %d" % n) if n == 0: return True path = os.path.join(CpuList.cpupath,'cpu%d' % n) - if os.path.exists(path): - return sysread(path, "online") == 1 - return False + # Some hardware doesn't allow cpu0 to be turned off + if not os.path.exists(path + '/online') and n == 0: + return True + else: + return sysread(path, "online") == "1" + + # Given a cpulist, return a cpulist of online cpus + def online_cpulist(self, cpulist): + # This only works if the sys online files exist + if not self.online_file_exists(): + return cpulist + newlist = [] + for cpu in cpulist: + if not self.online_file_exists() and cpu == '0': + newlist.append(cpu) + elif self.is_online(int(cpu)): + newlist.append(cpu) + return newlist # # class to abstract access to NUMA nodes in /sys filesystem -- 2.20.1