diff --git a/tuned/plugins/plugin_uncore.py b/tuned/plugins/plugin_uncore.py index 76af767d..0063aa73 100644 --- a/tuned/plugins/plugin_uncore.py +++ b/tuned/plugins/plugin_uncore.py @@ -75,11 +75,25 @@ def _set(self, dev_dir, file, value): return value return None + def _get_all(self, device): + try: + initial_max_freq_khz = self._get(device, "initial_max_freq_khz") + 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") + 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) + @classmethod def _get_config_options(cls): return { "max_freq_khz": None, "min_freq_khz": None, + + "max_freq_pct": None, + "min_freq_pct": None, } def _validate_value(self, device, min_or_max, value): @@ -89,14 +103,10 @@ def _validate_value(self, device, min_or_max, value): log.error("value '%s' is not integer" % value) return None - try: - initial_max_freq_khz = self._get(device, "initial_max_freq_khz") - 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") - except (OSError, IOError): - log.error("fail to read inital uncore frequency values") + values = self._get_all(device) + if not values: return None + (initial_max_freq_khz, initial_min_freq_khz, max_freq_khz, min_freq_khz) = values if min_or_max == IS_MAX: if freq_khz < min_freq_khz: @@ -121,6 +131,19 @@ def _validate_value(self, device, min_or_max, value): return freq_khz + def _validate_percent_value(self, value): + try: + pct = int(value) + except ValueError: + log.error("value '%s' is not integer" % value) + return None + + if pct < 0 or pct > 100: + log.error("percent value '%s' is not within [0..100] range" % value) + return None + + return pct + @command_set("max_freq_khz", per_device = True) def _set_max_freq_khz(self, value, device, sim, remove): max_freq_khz = self._validate_value(device, IS_MAX, value) @@ -172,3 +195,87 @@ def _get_min_freq_khz(self, device, ignore_missing=False): log.debug("%s: get min_freq_khz %d" % (device, min_freq_khz)) return min_freq_khz + + @command_set("max_freq_pct", per_device = True) + def _set_max_freq_pct(self, value, device, sim, remove): + pct = self._validate_percent_value(value) + if not pct: + return None + + values = self._get_all(device) + if not values: + return None + (initial_max_freq_khz, initial_min_freq_khz, _, _) = values + + khz = pct * (initial_max_freq_khz - initial_min_freq_khz) / 100 + max_freq_khz = khz + initial_min_freq_khz + + if self._validate_value(device, IS_MAX, max_freq_khz) != max_freq_khz: + return None + + if sim: + return pct + + if self._set(device, "max_freq_khz", max_freq_khz) != max_freq_khz: + return None + + log.debug("%s: set max_freq_pct %d" % (device, pct)) + return pct + + @command_get("max_freq_pct") + def _get_max_freq_pct(self, device, ignore_missing=False): + if ignore_missing and not os.path.isdir(SYSFS_DIR): + return None + + values = self._get_all(device) + if not values: + return None + (initial_max_freq_khz, initial_min_freq_khz, max_freq_khz, _) = values + + khz = max_freq_khz - initial_min_freq_khz + pct = 100 * khz / (initial_max_freq_khz - initial_min_freq_khz) + + log.debug("%s: get max_freq_pct %d" % (device, pct)) + return pct + + @command_set("min_freq_pct", per_device = True) + def _set_min_freq_pct(self, value, device, sim, remove): + pct = self._validate_percent_value(value) + if not pct: + return None + + values = self._get_all(device) + if not values: + return None + (initial_max_freq_khz, initial_min_freq_khz, _, _) = values + + khz = pct * (initial_max_freq_khz - initial_min_freq_khz) / 100 + min_freq_khz = khz + initial_min_freq_khz + + if self._validate_value(device, IS_MIN, min_freq_khz) != min_freq_khz: + return None + + if sim: + return pct + + if self._set(device, "min_freq_khz", min_freq_khz) != min_freq_khz: + return None + + log.debug("%s: set min_freq_pct %d" % (device, pct)) + return pct + + @command_get("min_freq_pct") + def _get_min_freq_pct(self, device, ignore_missing=False): + if ignore_missing and not os.path.isdir(SYSFS_DIR): + return None + + values = self._get_all(device) + if not values: + return None + (initial_max_freq_khz, initial_min_freq_khz, _, min_freq_khz) = values + + khz = min_freq_khz - initial_min_freq_khz + pct = 100 * khz / (initial_max_freq_khz - initial_min_freq_khz) + + log.debug("%s: get min_freq_pct %d" % (device, pct)) + return pct