Skip to content

Commit

Permalink
uncore: Allow to configure frequency limits using percent
Browse files Browse the repository at this point in the history
Using direct frequency values in only useful in specialistic profiles
where we know target platform. Add 'max_freq_pct' and 'min_freq_pct'
parameters that allow to specify limit of uncore frequency as percent of
hardware maximum/minimum frequency. Such parameters can be used in generic
profiles like 'balanced' in portable way, for example:

[uncore]
max_freq_pct=90

Signed-off-by: Stanislaw Gruszka <[email protected]>
  • Loading branch information
sgruszka committed Mar 14, 2024
1 parent 86ac977 commit dcc2640
Showing 1 changed file with 114 additions and 7 deletions.
121 changes: 114 additions & 7 deletions tuned/plugins/plugin_uncore.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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 values is None:
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:
Expand All @@ -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)
Expand Down Expand Up @@ -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 pct is None:
return None

values = self._get_all(device)
if values is None:
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 values is None:
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 pct is None:
return None

values = self._get_all(device)
if values is None:
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 values is None:
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

0 comments on commit dcc2640

Please sign in to comment.