From f66da7db3171be8cef2fc6e6cefe2c84aaa32e1e Mon Sep 17 00:00:00 2001 From: Chris Redpath Date: Mon, 12 Jun 2017 14:33:14 +0100 Subject: [PATCH 1/2] testenv: Move freeze/thaw_userspace methods to TestEnv from Executor It would be useful to be able to call freeze methods without needing a test class based upon Executor. Move the required methods and data. Signed-off-by: Chris Redpath --- libs/utils/env.py | 42 ++++++++++++++++++++++++++++++++++++++++++ libs/utils/executor.py | 40 ++-------------------------------------- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/libs/utils/env.py b/libs/utils/env.py index 2857f35a2..7891094cb 100644 --- a/libs/utils/env.py +++ b/libs/utils/env.py @@ -151,6 +151,22 @@ class TestEnv(ShareState): :type force_new: bool """ + critical_tasks = { + 'linux': ['init', 'systemd', 'sh', 'ssh'], + 'android': [ + 'sh', 'adbd', + 'usb', 'transport', + # We don't actually need this task but on Google Pixel it apparently + # cannot be frozen, so the cgroup state gets stuck in FREEZING if we + # try to freeze it. + 'thermal-engine' + ] + } + """ + Dictionary mapping OS name to list of task names that we can't afford to + freeze when using freeeze_userspace. + """ + _initialized = False def __init__(self, target_conf=None, test_conf=None, wipe=True, @@ -1008,6 +1024,32 @@ class TestEnv(ShareState): def _feature(self, feature): return feature in self.conf['__features__'] + def freeze_userspace(self): + self.need_thaw = False + if 'cgroups' not in self.target.modules: + raise RuntimeError( + 'Failed to freeze userspace. Ensure "cgroups" module is listed ' + 'among modules in target/test configuration') + controllers = [s.name for s in self.target.cgroups.list_subsystems()] + if 'freezer' not in controllers: + self._log.warning('No freezer cgroup controller on target. ' + 'Not freezing userspace') + return False + + exclude = self.critical_tasks[self.target.os] + self._log.info('Freezing all tasks except: %s', ','.join(exclude)) + self.target.cgroups.freeze(exclude) + self.need_thaw = True + return True + + def thaw_userspace(self): + if self.need_thaw: + self._log.info('Un-freezing userspace tasks') + self.target.cgroups.freeze(thaw=True) + else: + self._log.error('Trying to un-freeze tasks without first freezing. ' + 'Not unfreezing userspace') + IFCFG_BCAST_RE = re.compile( r'Bcast:(.*) ' ) diff --git a/libs/utils/executor.py b/libs/utils/executor.py index 7c7060b22..dd67305cb 100644 --- a/libs/utils/executor.py +++ b/libs/utils/executor.py @@ -168,21 +168,6 @@ class Executor(): :type experiments_conf: dict """ - critical_tasks = { - 'linux': ['init', 'systemd', 'sh', 'ssh'], - 'android': [ - 'sh', 'adbd', - 'usb', 'transport', - # We don't actually need this task but on Google Pixel it apparently - # cannot be frozen, so the cgroup state gets stuck in FREEZING if we - # try to freeze it. - 'thermal-engine' - ] - } - """ - Dictionary mapping OS name to list of task names that we can't afford to - freeze when using freeeze_userspace. - """ def __init__(self, test_env, experiments_conf): # Initialize globals @@ -672,7 +657,7 @@ class Executor(): # Freeze all userspace tasks that we don't need for running tests need_thaw = False if self._target_conf_flag(tc, 'freeze_userspace'): - need_thaw = self._freeze_userspace() + need_thaw = self.te.freeze_userspace() # FTRACE: start (if a configuration has been provided) if self.te.ftrace and self._target_conf_flag(tc, 'ftrace'): @@ -708,31 +693,10 @@ class Executor(): # Unfreeze the tasks we froze if need_thaw: - self._thaw_userspace() + self.te.thaw_userspace() self._print_footer() - def _freeze_userspace(self): - if 'cgroups' not in self.target.modules: - raise RuntimeError( - 'Failed to freeze userspace. Ensure "cgroups" module is listed ' - 'among modules in target/test configuration') - controllers = [s.name for s in self.target.cgroups.list_subsystems()] - if 'freezer' not in controllers: - self._log.warning('No freezer cgroup controller on target. ' - 'Not freezing userspace') - return False - - exclude = self.critical_tasks[self.te.target.os] - self._log.info('Freezing all tasks except: %s', ','.join(exclude)) - self.te.target.cgroups.freeze(exclude) - return True - - - def _thaw_userspace(self): - self._log.info('Un-freezing userspace tasks') - self.te.target.cgroups.freeze(thaw=True) - ################################################################################ # Utility Functions ################################################################################ -- GitLab From e4a2476103a3054c42957280997ff3519f02aa96 Mon Sep 17 00:00:00 2001 From: Chris Redpath Date: Mon, 12 Jun 2017 14:45:41 +0100 Subject: [PATCH 2/2] tests/eas/capacity_capping: add support for freezing userspace tasks A high level of tasks running during this test can cause significant disturbance as this test ensures that during a simulated thermal capping event less than 1% of the time is spent running tasks on the cpus which have been capped. In the case that the uncapped cpus are very busy, it is still reasonable to put the test tasks on the capped cpus which counts as a failure but is probably the correct schedule. Now that we have moved freezing into TestEnv, we can make direct use of it. Signed-off-by: Chris Redpath --- tests/eas/capacity_capping.config | 5 +++-- tests/eas/capacity_capping.py | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/eas/capacity_capping.config b/tests/eas/capacity_capping.config index d2515deb6..15bb4506a 100644 --- a/tests/eas/capacity_capping.config +++ b/tests/eas/capacity_capping.config @@ -5,11 +5,12 @@ "MIGRATION_WINDOW": 0.75, "EXPECTED_BUSY_TIME_PCT": 99, "TEST_CONF": { - "modules": ["bl", "cpufreq"], + "modules": ["bl", "cpufreq", "cgroups" ], "tools": ["rt-app"], "ftrace" : { "events" : ["sched_switch"], "buffsize" : 10240 - } + }, + "flags" : [ "ftrace" ] } } diff --git a/tests/eas/capacity_capping.py b/tests/eas/capacity_capping.py index 3f828e3a5..fd6b60fd3 100644 --- a/tests/eas/capacity_capping.py +++ b/tests/eas/capacity_capping.py @@ -83,6 +83,7 @@ class CapacityCappingTest(unittest.TestCase): """ + @classmethod def setUpClass(cls): cls.params = {} @@ -126,6 +127,7 @@ class CapacityCappingTest(unittest.TestCase): wload.conf(kind="profile", params=cls.params) phase_duration = WORKLOAD_DURATION_S / 3. + cls.env.freeze_userspace() cls.env.ftrace.start() wload.run(out_dir=cls.env.res_dir, background=True) @@ -150,6 +152,7 @@ class CapacityCappingTest(unittest.TestCase): cls.env.ftrace.stop() cls.env.ftrace.get_trace(cls.trace_file) + cls.env.thaw_userspace() def check_residencies(self, cpus, cpus_name, window, phase_description): """Helper function to check the residencies of all busy threads on a -- GitLab