1
0
Fork 0

functions: added CPU list to hex mask and vice versa conversions

Added following functions:

cpulist2hex - converts CPU list to hexadecimal mask, takes arbitrary number of
              arguments, each argument can also contain "compact values",
              e.g.: "${f:cpulist2hex:0-3,4:5-6}".

hex2cpulist - converts hexadecimal mask to CPU list, takes one argument,
              the hexadecimal mask.

cpus_online - checks whether CPUs from the list (which is formatted the same
              way as with cpulist2hex) are online, returns only those which
              are online.

Example:

[variables]
cpus = ${f:hex2cpulist:0x0000001f}
online = ${f:cpus_online:${cpus}}

Related: rhbz#1225135

Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
This commit is contained in:
Jaroslav Škarvada 2015-06-05 18:55:56 +02:00
parent 8968280a4f
commit a6f4fca71d
8 changed files with 120 additions and 8 deletions

View file

@ -75,8 +75,7 @@ class CPULatencyPlugin(base.Plugin):
def _is_cpu_online(self, device):
sd = str(device)
# CPU0 is always online
return sd == "cpu0" or self._cmd.read_file("/sys/devices/system/cpu/%s/online" % sd).strip() == "1"
return self._cmd.is_cpu_online(str(device).replace("cpu", ""))
def _instance_init(self, instance):
instance._has_static_tuning = True

View file

@ -0,0 +1,19 @@
import os
import tuned.logs
import base
from tuned.utils.commands import commands
log = tuned.logs.get()
class cpulist2hex(base.Function):
"""
Conversion function: converts CPU list to hexadecimal CPU mask
"""
def __init__(self):
# arbitrary number of arguments
super(self.__class__, self).__init__("cpulist2hex", 0)
def execute(self, args):
if not super(self.__class__, self).execute(args):
return None
return self._cmd.cpulist2hex(",".join(args))

View file

@ -0,0 +1,21 @@
import os
import tuned.logs
import base
from tuned.utils.commands import commands
log = tuned.logs.get()
class cpus_online(base.Function):
"""
Checks whether CPUs from list are online, returns list containing
only online CPUs
"""
def __init__(self):
# arbitrary number of arguments
super(self.__class__, self).__init__("cpus_online", 0)
def execute(self, args):
if not super(self.__class__, self).execute(args):
return None
cpus = ",".join(args)
return ",".join(filter(lambda cpu: self._cmd.is_cpu_online(cpu), cpus.split(",")))

View file

@ -0,0 +1,19 @@
import os
import tuned.logs
import base
from tuned.utils.commands import commands
log = tuned.logs.get()
class hex2cpulist(base.Function):
"""
Conversion function: converts hexadecimal CPU mask to CPU list
"""
def __init__(self):
# one argument
super(self.__class__, self).__init__("hex2cpulist", 1)
def execute(self, args):
if not super(self.__class__, self).execute(args):
return None
return ",".join(self._cmd.hex2cpulist(args[0]))

View file

@ -8,7 +8,7 @@ class kb2s(base.Function):
Conversion function: kbytes to sectors
"""
def __init__(self):
# 1 argument
# one argument
super(self.__class__, self).__init__("kb2s", 1)
def execute(self, args):

View file

@ -8,7 +8,7 @@ class s2kb(base.Function):
Conversion function: sectors to kbytes
"""
def __init__(self):
# 1 argument
# one argument
super(self.__class__, self).__init__("s2kb", 1)
def execute(self, args):

View file

@ -43,6 +43,6 @@ class Functions():
def expand(self, s):
if s is None:
return s
r = re.compile(r'(?<!\\)\${f:([\w:\\]+)}')
r = re.compile(r'(?<!\\)\${f:([^}]+)}')
# expand functions and convert all \${f:*} to ${f:*} (unescape)
return re.sub(r'\\(\${f:[\w:\\]+})', r'\1', r.sub(self.sub_func, s))
return re.sub(r'\\(\${f:[^}]+})', r'\1', r.sub(self.sub_func, s))

View file

@ -59,14 +59,15 @@ class commands:
self._error("Writing to file %s error: %s" % (f, e))
return rc
def read_file(self, f, err_ret = ""):
def read_file(self, f, err_ret = "", no_error = False):
old_value = err_ret
try:
f = open(f, "r")
old_value = f.read()
f.close()
except (OSError,IOError) as e:
self._error("Reading %s error: %s" % (f, e))
if not no_error:
self._error("Reading %s error: %s" % (f, e))
return old_value
def replace_in_file(self, f, pattern, repl):
@ -110,6 +111,59 @@ class commands:
return options.split()[0]
return options
# Checks whether CPU is online
def is_cpu_online(self, cpu):
scpu = str(cpu)
# CPU0 is always online
return cpu == "0" or self.read_file("/sys/devices/system/cpu/cpu%s/online" % scpu, no_error = True).strip() == "1"
# Converts hexadecimal CPU mask to CPU list
def hex2cpulist(self, mask):
if mask is None:
return None
cpu = 0
cpus = []
try:
m = int(mask, 16)
except ValueError:
log.error("invalid hexadecimal mask '%s'" % str(mask))
return []
while m > 0:
if m & 1:
cpus.append(str(cpu))
m >>= 1
cpu += 1
return cpus
# Unpacks CPU list, i.e. 1-3 will be converted to 1, 2, 3
def unpack_cpulist(self, l):
rl = []
if l is None:
return l
ll = str(l).split(",")
for v in ll:
vl = v.split("-")
try:
if len(vl) > 1:
rl += range(int(vl[0]), int(vl[1]) + 1)
else:
rl.append(int(vl[0]))
except ValueError:
return None
return sorted(list(set(rl)))
# Converts CPU list to hexadecimal CPU mask
def cpulist2hex(self, l):
if l is None:
return None
m = 0
ul = self.unpack_cpulist(l)
if ul is None:
return None
for v in self.unpack_cpulist(l):
m |= pow(2, v)
return "0x%08x" % m
def recommend_profile(self):
profile = consts.DEFAULT_PROFILE
for f in consts.LOAD_DIRECTORIES: