plugin_cpu: added support for intel_pstate
The following intel_pstate parameters are now supported: min_perf_pct max_perf_pct no_turbo Resolves: rhbz#996722 Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
This commit is contained in:
parent
5d306833bd
commit
94e383a5ed
4 changed files with 57 additions and 9 deletions
|
|
@ -6,6 +6,7 @@
|
|||
force_latency=1
|
||||
governor=performance
|
||||
energy_perf_bias=performance
|
||||
min_perf_pct=100
|
||||
|
||||
[vm]
|
||||
transparent_hugepages=never
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
[cpu]
|
||||
governor=performance
|
||||
energy_perf_bias=performance
|
||||
min_perf_pct=100
|
||||
|
||||
[vm]
|
||||
transparent_hugepages=always
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import struct
|
|||
log = tuned.logs.get()
|
||||
|
||||
# TODO: force_latency -> command
|
||||
# intel_pstate
|
||||
|
||||
class CPULatencyPlugin(base.Plugin):
|
||||
"""
|
||||
|
|
@ -20,6 +21,11 @@ class CPULatencyPlugin(base.Plugin):
|
|||
|
||||
self._has_cpupower = True
|
||||
self._has_energy_perf_bias = True
|
||||
self._has_intel_pstate = False
|
||||
|
||||
self._min_perf_pct_save = None
|
||||
self._max_perf_pct_save = None
|
||||
self._no_turbo_save = None
|
||||
|
||||
def _init_devices(self):
|
||||
self._devices = set()
|
||||
|
|
@ -38,6 +44,9 @@ class CPULatencyPlugin(base.Plugin):
|
|||
"force_latency" : None,
|
||||
"governor" : None,
|
||||
"energy_perf_bias" : None,
|
||||
"min_perf_pct" : None,
|
||||
"max_perf_pct" : None,
|
||||
"no_turbo" : None,
|
||||
}
|
||||
|
||||
def _check_cpupower(self):
|
||||
|
|
@ -57,13 +66,18 @@ class CPULatencyPlugin(base.Plugin):
|
|||
else:
|
||||
log.warning("your CPU doesn't support MSR_IA32_ENERGY_PERF_BIAS, ignoring CPU energy performance bias")
|
||||
|
||||
def _check_intel_pstate(self):
|
||||
self._has_intel_pstate = os.path.exists("/sys/devices/system/cpu/intel_pstate")
|
||||
if self._has_intel_pstate:
|
||||
log.info("intel_pstate detected")
|
||||
|
||||
def _instance_init(self, instance):
|
||||
instance._has_static_tuning = True
|
||||
instance._has_dynamic_tuning = False
|
||||
|
||||
# only the first instance of the plugin can control the latency
|
||||
if self._instances.values()[0] == instance:
|
||||
instance._controls_latency = True
|
||||
instance._first_instance = True
|
||||
self._cpu_latency_fd = os.open("/dev/cpu_dma_latency", os.O_WRONLY)
|
||||
self._latency = None
|
||||
|
||||
|
|
@ -77,33 +91,52 @@ class CPULatencyPlugin(base.Plugin):
|
|||
self._check_cpupower()
|
||||
# Check for x86_energy_perf_policy, ignore if not available / supported
|
||||
self._check_energy_perf_bias()
|
||||
# Check for intel_pstate
|
||||
self._check_intel_pstate()
|
||||
else:
|
||||
instance._controls_latency = False
|
||||
instance._first_instance = False
|
||||
log.info("Latency settings from non-first CPU plugin instance '%s' will be ignored." % instance.name)
|
||||
|
||||
instance._first_device = list(instance.devices)[0]
|
||||
|
||||
def _instance_cleanup(self, instance):
|
||||
if instance._controls_latency:
|
||||
if instance._first_instance:
|
||||
os.close(self._cpu_latency_fd)
|
||||
if instance._load_monitor is not None:
|
||||
self._monitors_repository.delete(instance._load_monitor)
|
||||
|
||||
def _instance_apply_static(self, instance):
|
||||
if instance._first_instance and self._has_intel_pstate:
|
||||
self._min_perf_pct_save = self._get_intel_pstate_attr("min_perf_pct")
|
||||
self._max_perf_pct_save = self._get_intel_pstate_attr("max_perf_pct")
|
||||
self._no_turbo_save = self._get_intel_pstate_attr("no_turbo")
|
||||
|
||||
super(self.__class__, self)._instance_apply_static(instance)
|
||||
|
||||
if not instance._controls_latency:
|
||||
if not instance._first_instance:
|
||||
return
|
||||
|
||||
force_latency_value = instance.options["force_latency"]
|
||||
if force_latency_value is not None:
|
||||
self._set_latency(force_latency_value)
|
||||
if self._has_intel_pstate:
|
||||
self._set_intel_pstate_attr("min_perf_pct", instance.options["min_perf_pct"])
|
||||
self._set_intel_pstate_attr("max_perf_pct", instance.options["max_perf_pct"])
|
||||
self._set_intel_pstate_attr("no_turbo", instance.options["no_turbo"])
|
||||
|
||||
def _instance_unapply_static(self, instance):
|
||||
super(self.__class__, self)._instance_unapply_static(instance)
|
||||
|
||||
if instance._first_instance and self._has_intel_pstate:
|
||||
self._set_intel_pstate_attr("min_perf_pct", self._min_perf_pct_save)
|
||||
self._set_intel_pstate_attr("max_perf_pct", self._max_perf_pct_save)
|
||||
self._set_intel_pstate_attr("no_turbo", self._no_turbo_save)
|
||||
|
||||
def _instance_apply_dynamic(self, instance, device):
|
||||
self._instance_update_dynamic(instance, device)
|
||||
|
||||
def _instance_update_dynamic(self, instance, device):
|
||||
assert(instance._controls_latency)
|
||||
assert(instance._first_instance)
|
||||
if device != instance._first_device:
|
||||
return
|
||||
|
||||
|
|
@ -116,6 +149,13 @@ class CPULatencyPlugin(base.Plugin):
|
|||
def _instance_unapply_dynamic(self, instance, device):
|
||||
pass
|
||||
|
||||
def _get_intel_pstate_attr(self, attr):
|
||||
return tuned.utils.commands.read_file("/sys/devices/system/cpu/intel_pstate/%s" % attr, None)
|
||||
|
||||
def _set_intel_pstate_attr(self, attr, val):
|
||||
if val is not None:
|
||||
tuned.utils.commands.write_to_file("/sys/devices/system/cpu/intel_pstate/%s" % attr, val)
|
||||
|
||||
def _set_latency(self, latency):
|
||||
latency = int(latency)
|
||||
if self._latency != latency:
|
||||
|
|
@ -124,8 +164,14 @@ class CPULatencyPlugin(base.Plugin):
|
|||
os.write(self._cpu_latency_fd, latency_bin)
|
||||
self._latency = latency
|
||||
|
||||
def _get_available_governors(self, device):
|
||||
return tuned.utils.commands.read_file("/sys/devices/system/cpu/%s/cpufreq/scaling_available_governors" % device).split()
|
||||
|
||||
@command_set("governor", per_device=True)
|
||||
def _set_governor(self, governor, device):
|
||||
if governor not in self._get_available_governors(device):
|
||||
log.info("ignoring governor '%s' on cpu '%s', it is not supported" % (governor, device))
|
||||
return
|
||||
log.info("setting governor '%s' on cpu '%s'" % (governor, device))
|
||||
if self._has_cpupower:
|
||||
cpu_id = device.lstrip("cpu")
|
||||
|
|
@ -145,10 +191,10 @@ class CPULatencyPlugin(base.Plugin):
|
|||
continue
|
||||
l = line.split()
|
||||
if len(l) == 3:
|
||||
governor = l[2]
|
||||
governor = l[2].strip()
|
||||
break
|
||||
else:
|
||||
data = tuned.utils.commands.read_file("/sys/devices/system/cpu/%s/cpufreq/scaling_governor" % device)
|
||||
data = tuned.utils.commands.read_file("/sys/devices/system/cpu/%s/cpufreq/scaling_governor" % device).strip()
|
||||
if len(data) > 0:
|
||||
governor = data
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ def write_to_file(f, data):
|
|||
log.error("Writing to file %s error: %s" % (f, e))
|
||||
return rc
|
||||
|
||||
def read_file(f):
|
||||
old_value = ""
|
||||
def read_file(f, err_ret = ""):
|
||||
old_value = err_ret
|
||||
try:
|
||||
f = open(f, "r")
|
||||
old_value = f.read()
|
||||
|
|
|
|||
Loading…
Reference in a new issue