From e4e2090454e3f79607127c118c73a0de4c8fbbef Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Mon, 9 Oct 2023 10:52:39 +0100 Subject: [PATCH 1/3] lisa.tests.staging.utilclamp: Choose uclamp so that freq is in the middle of a band FIX Factor in the schedutil capacity margin to ask for a util clamp that should map right in the middle of a frequency band, instead of middle + 25%. --- lisa/tests/staging/utilclamp.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lisa/tests/staging/utilclamp.py b/lisa/tests/staging/utilclamp.py index b3de5fce1..47cb5e9c9 100644 --- a/lisa/tests/staging/utilclamp.py +++ b/lisa/tests/staging/utilclamp.py @@ -134,6 +134,10 @@ class UtilClamp(RTATestBundle, TestBundle): def make_phase(band): uclamp = band_mid(band) + # We don't ask for the middle of the band, we ask for the util that + # will map to a frequency in the middle of the band when processed + # by schedutil + uclamp *= cls.CAPACITY_MARGIN util = uclamp / 2 name = f'uclamp-{uclamp}' return (name, (uclamp, util)) -- GitLab From 38428fb6dbeec3e6f67ef7892dd7d77804bc8e46 Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Mon, 9 Oct 2023 11:43:37 +0100 Subject: [PATCH 2/3] lisa.tests.staging.utilclamp: Avoid overlapping CPU capacities FIX Avoid choosing uclamp in CPU capacity ranges that are overlapping between CPUs. Instead, ignore all the capacities on faster CPUs that are lower than the max capa of any slower CPU. Also ensure that the capacity bands considered exist inside a given CPU and are not a band between the highest capacity of a CPU and the lowest capacity of another one. --- lisa/tests/staging/utilclamp.py | 79 ++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/lisa/tests/staging/utilclamp.py b/lisa/tests/staging/utilclamp.py index 47cb5e9c9..22ae75929 100644 --- a/lisa/tests/staging/utilclamp.py +++ b/lisa/tests/staging/utilclamp.py @@ -79,8 +79,9 @@ class UtilClamp(RTATestBundle, TestBundle): """ max_capacities = plat_info['cpu-capacities']['rtapp'] + capacity_classes = plat_info['capacity-classes'] - return { + capacities = { cpu: { freq: int(max_capacities[cpu] * freq / max(freqs)) for freq in freqs @@ -88,35 +89,59 @@ class UtilClamp(RTATestBundle, TestBundle): for cpu, freqs in plat_info['freqs'].items() } + + # Ensure there is no overlap between CPUs by ignoring all capacities + # that are lower than the max capacity of CPUs with lower max cap. For + # example, the capacities of a big CPU that will be considered will + # always be higher than the capacities of any LITTLE. + # + # This avoids choosing any uclamp value that could be placed on one CPU + # or another. + for cpu, max_cap in max_capacities.items(): + for _cpu, _max_cap in max_capacities.items(): + if _max_cap > max_cap: + capacities[_cpu] = { + freq: cap + for freq, cap in capacities[_cpu].items() + if cap >= max_cap + } + + return capacities + + @classmethod - def _collect_capacities_flatten(cls, plat_info): - capacities = [ - capa + def _collect_capacity_classes(cls, plat_info): + return sorted(set( + tuple(sorted(freq_capas.values())) for freq_capas in cls._collect_capacities(plat_info).values() - for capa in freq_capas.values() - ] - - # Remove the duplicates from the list - return sorted(set(capacities)) + )) @classmethod - def _get_bands(cls, capacities): - bands = list(zip(capacities, capacities[1:])) - - # Only keep a number of bands - nr_bands = cls.NR_PHASES - if len(bands) > nr_bands: - # Pick the bands covering the widest range of util, since they - # are easier to test - bands = sorted( - bands, - key=lambda band: band[1] - band[0], - reverse=True - ) - bands = bands[:nr_bands] - bands = sorted(bands, key=itemgetter(0)) + def _get_bands(cls, capacity_classes): + + def get_bands(capacities): + bands = list(zip(capacities, capacities[1:])) + + # Only keep a number of bands + nr_bands = cls.NR_PHASES + if len(bands) > nr_bands: + # Pick the bands covering the widest range of util, since they + # are easier to test + bands = sorted( + bands, + key=lambda band: band[1] - band[0], + reverse=True + ) + bands = bands[:nr_bands] + bands = sorted(bands, key=itemgetter(0)) - return bands + return bands + + return [ + band + for capacities in capacity_classes + for band in get_bands(capacities) + ] @classmethod def _get_phases(cls, plat_info): @@ -126,8 +151,8 @@ class UtilClamp(RTATestBundle, TestBundle): (uclamp_val, util) """ - capacities = cls._collect_capacities_flatten(plat_info) - bands = cls._get_bands(capacities) + capacity_classes = cls._collect_capacity_classes(plat_info) + bands = cls._get_bands(capacity_classes) def band_mid(band): return int((band[1] + band[0]) / 2) -- GitLab From 209853348a35e66f82c9dcb7a1989d2c5ec774bf Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Mon, 9 Oct 2023 12:25:41 +0100 Subject: [PATCH 3/3] lisa.tests.staging.utilclamp: Remove useless condition --- lisa/tests/staging/utilclamp.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lisa/tests/staging/utilclamp.py b/lisa/tests/staging/utilclamp.py index 22ae75929..33152243c 100644 --- a/lisa/tests/staging/utilclamp.py +++ b/lisa/tests/staging/utilclamp.py @@ -122,18 +122,15 @@ class UtilClamp(RTATestBundle, TestBundle): def get_bands(capacities): bands = list(zip(capacities, capacities[1:])) - # Only keep a number of bands - nr_bands = cls.NR_PHASES - if len(bands) > nr_bands: - # Pick the bands covering the widest range of util, since they - # are easier to test - bands = sorted( - bands, - key=lambda band: band[1] - band[0], - reverse=True - ) - bands = bands[:nr_bands] - bands = sorted(bands, key=itemgetter(0)) + # Pick the bands covering the widest range of util, since they + # are easier to test + bands = sorted( + bands, + key=lambda band: band[1] - band[0], + reverse=True + ) + bands = bands[:cls.NR_PHASES] + bands = sorted(bands, key=itemgetter(0)) return bands -- GitLab