uncore: Allow to configure uncore ELC control
The Efficiency Latency Control (ELC) feature improves performance per watt. With this feature hardware power management algorithms optimize trade-off between latency and power consumption. Add additional configuration for uncore plugin to include attributes to configure ELC. Refer to Intel White Paper Link: Linux kernel documentation: https://docs.kernel.org/admin-guide/pm/intel_uncore_frequency_scaling.html Example configuration: [uncore_all] type=uncore elc_floor_freq_khz=2400000 elc_high_threshold_enable=1 elc_high_threshold_percent=95 elc_low_threshold_percent=10
This commit is contained in:
parent
c07833ba62
commit
a4f0364f4c
1 changed files with 138 additions and 3 deletions
|
|
@ -38,6 +38,17 @@ class UncorePlugin(hotplug.Plugin):
|
|||
on the Intel system to 90% of the allowable range. Except uncore10 which
|
||||
maximum frequency limit will be set to 4 GHz.
|
||||
====
|
||||
|
||||
The Efficiency Latency Control (ELC) Interface
|
||||
|
||||
Options [option]`elc_floor_freq_khz`, [option]`elc_low_threshold_percent`
|
||||
[option]`elc_high_threshold_percent` and [option]`elc_high_threshold_enable`
|
||||
correspond to `sysfs` files exposed by Intel uncore frequency driver.
|
||||
The scope of control is same as max_freq_khz and max_freq_khz settings as described
|
||||
above.
|
||||
Refer to https://docs.kernel.org/admin-guide/pm/intel_uncore_frequency_scaling.html
|
||||
for detail.
|
||||
|
||||
"""
|
||||
|
||||
def _init_devices(self):
|
||||
|
|
@ -88,16 +99,27 @@ class UncorePlugin(hotplug.Plugin):
|
|||
initial_min_freq_khz = self._get(device, "initial_min_freq_khz")
|
||||
max_freq_khz = self._get(device, "max_freq_khz")
|
||||
min_freq_khz = self._get(device, "min_freq_khz")
|
||||
elc_floor_freq_khz = self._get(device, "elc_floor_freq_khz")
|
||||
elc_high_threshold_enable = self._get(device, "elc_high_threshold_enable")
|
||||
elc_high_threshold_percent = self._get(device, "elc_high_threshold_percent")
|
||||
elc_low_threshold_percent = self._get(device, "elc_low_threshold_percent")
|
||||
|
||||
except (OSError, IOError):
|
||||
log.error("fail to read uncore frequency values")
|
||||
return None
|
||||
return (initial_max_freq_khz, initial_min_freq_khz, max_freq_khz, min_freq_khz)
|
||||
return (initial_max_freq_khz, initial_min_freq_khz, max_freq_khz, min_freq_khz,
|
||||
elc_floor_freq_khz, elc_high_threshold_enable, elc_high_threshold_percent,
|
||||
elc_low_threshold_percent)
|
||||
|
||||
@classmethod
|
||||
def _get_config_options(cls):
|
||||
return {
|
||||
"max_freq_khz": None,
|
||||
"min_freq_khz": None,
|
||||
"elc_floor_freq_khz": None,
|
||||
"elc_high_threshold_enable": None,
|
||||
"elc_high_threshold_percent": None,
|
||||
"elc_low_threshold_percent": None,
|
||||
}
|
||||
|
||||
def _validate_khz_value(self, device, min_or_max, value):
|
||||
|
|
@ -110,7 +132,10 @@ class UncorePlugin(hotplug.Plugin):
|
|||
values = self._get_all(device)
|
||||
if values is None:
|
||||
return None
|
||||
(initial_max_freq_khz, initial_min_freq_khz, max_freq_khz, min_freq_khz) = values
|
||||
|
||||
(initial_max_freq_khz, initial_min_freq_khz, max_freq_khz, min_freq_khz,
|
||||
elc_floor_freq_khz, elc_high_threshold_enable, elc_high_threshold_percent,
|
||||
elc_low_threshold_percent) = values
|
||||
|
||||
if min_or_max == IS_MAX:
|
||||
if freq_khz < min_freq_khz:
|
||||
|
|
@ -157,7 +182,7 @@ class UncorePlugin(hotplug.Plugin):
|
|||
values = self._get_all(device)
|
||||
if values is None:
|
||||
return None
|
||||
(initial_max_freq_khz, initial_min_freq_khz, _, _) = values
|
||||
(initial_max_freq_khz, initial_min_freq_khz, *_) = values
|
||||
|
||||
khz = initial_min_freq_khz + int(pct * (initial_max_freq_khz - initial_min_freq_khz) / 100)
|
||||
else:
|
||||
|
|
@ -216,3 +241,113 @@ class UncorePlugin(hotplug.Plugin):
|
|||
|
||||
log.debug("%s: get min_freq_khz %d" % (device, min_freq_khz))
|
||||
return min_freq_khz
|
||||
|
||||
@command_get("elc_floor_freq_khz")
|
||||
def _get_elc_floor_freq_khz(self, device, instance, ignore_missing=False):
|
||||
if ignore_missing and not os.path.isdir(SYSFS_DIR):
|
||||
return None
|
||||
|
||||
try:
|
||||
elc_floor_freq_khz = self._get(device, "elc_floor_freq_khz")
|
||||
except (OSError, IOError):
|
||||
log.error("fail to read elc floor uncore frequency values")
|
||||
return None
|
||||
|
||||
log.debug("%s: get elc_floor_freq_khz %d" % (device, elc_floor_freq_khz))
|
||||
return elc_floor_freq_khz
|
||||
|
||||
@command_set("elc_floor_freq_khz", per_device = True)
|
||||
def _set_elc_floor_freq_khz(self, value, device, instance, sim, remove):
|
||||
elc_floor_freq_khz = self._validate_value(device, IS_MAX, value)
|
||||
if elc_floor_freq_khz is None:
|
||||
return None
|
||||
|
||||
if sim:
|
||||
return elc_floor_freq_khz
|
||||
|
||||
log.debug("%s: set elc_floor_freq_khz %d" % (device, elc_floor_freq_khz))
|
||||
return self._set(device, "elc_floor_freq_khz", elc_floor_freq_khz)
|
||||
|
||||
@command_set("elc_high_threshold_percent", per_device = True)
|
||||
def _set_elc_high_threshold_percent(self, value, device, instance, sim, remove):
|
||||
pct = self._validate_percent_value(value.rstrip("%"))
|
||||
if pct is None:
|
||||
return None
|
||||
|
||||
if sim:
|
||||
return pct
|
||||
|
||||
log.debug("%s: set elc_high_threshold_percent %d" % (device, pct))
|
||||
return self._set(device, "elc_high_threshold_percent", pct)
|
||||
|
||||
@command_get("elc_high_threshold_percent")
|
||||
def _get_elc_high_threshold_percent(self, device, instance, ignore_missing=False):
|
||||
if ignore_missing and not os.path.isdir(SYSFS_DIR):
|
||||
return None
|
||||
|
||||
try:
|
||||
elc_high_threshold_percent = self._get(device, "elc_high_threshold_percent")
|
||||
except (OSError, IOError):
|
||||
log.error("fail to read uncore elc threshold")
|
||||
return None
|
||||
|
||||
log.debug("%s: get elc_high_threshold_percent %d" % (device, elc_high_threshold_percent))
|
||||
return elc_high_threshold_percent
|
||||
|
||||
@command_set("elc_low_threshold_percent", per_device = True)
|
||||
def _set_elc_low_threshold_percent(self, value, device, instance, sim, remove):
|
||||
pct = self._validate_percent_value(value.rstrip("%"))
|
||||
if pct is None:
|
||||
return None
|
||||
|
||||
if sim:
|
||||
return pct
|
||||
|
||||
log.debug("%s: set elc_low_threshold_percent %d" % (device, pct))
|
||||
return self._set(device, "elc_low_threshold_percent", pct)
|
||||
|
||||
@command_get("elc_low_threshold_percent")
|
||||
def _get_elc_low_threshold_percent(self, device, instance, ignore_missing=False):
|
||||
if ignore_missing and not os.path.isdir(SYSFS_DIR):
|
||||
return None
|
||||
|
||||
try:
|
||||
elc_low_threshold_percent = self._get(device, "elc_low_threshold_percent")
|
||||
except (OSError, IOError):
|
||||
log.error("fail to read uncore elc threshold")
|
||||
return None
|
||||
|
||||
log.debug("%s: get elc_low_threshold_percent %d" % (device, elc_low_threshold_percent))
|
||||
return elc_low_threshold_percent
|
||||
|
||||
@command_set("elc_high_threshold_enable", per_device = True)
|
||||
def _set_elc_high_threshold_enable(self, value, device, instance, sim, remove):
|
||||
try:
|
||||
enable = int(value)
|
||||
except ValueError:
|
||||
log.error("value '%s' is not integer" % value)
|
||||
return None
|
||||
|
||||
if enable != 0 and enable != 1:
|
||||
log.error("Invalid Enable value '%s' is not within [0..1] range" % value)
|
||||
return None
|
||||
|
||||
if sim:
|
||||
return enable
|
||||
|
||||
log.debug("%s: set elc_high_threshold_enable %d" % (device, enable))
|
||||
return self._set(device, "elc_high_threshold_enable", enable)
|
||||
|
||||
@command_get("elc_high_threshold_enable")
|
||||
def _get_elc_high_threshold_enable(self, device, instance, ignore_missing=False):
|
||||
if ignore_missing and not os.path.isdir(SYSFS_DIR):
|
||||
return None
|
||||
|
||||
try:
|
||||
elc_high_threshold_enable = self._get(device, "elc_high_threshold_enable")
|
||||
except (OSError, IOError):
|
||||
log.error("fatuned/plugins/plugin_uncore.pyil to read uncore elc enable")
|
||||
return None
|
||||
|
||||
log.debug("%s: get elc_low_threshold_percent %d" % (device, elc_high_threshold_enable))
|
||||
return elc_high_threshold_enable
|
||||
|
|
|
|||
Loading…
Reference in a new issue