1ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# SPDX-License-Identifier: Apache-2.0 2ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# 3ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Copyright (C) 2015, ARM Limited and contributors. 4ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# 5ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Licensed under the Apache License, Version 2.0 (the "License"); you may 6ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# not use this file except in compliance with the License. 7ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# You may obtain a copy of the License at 8ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# 9ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# http://www.apache.org/licenses/LICENSE-2.0 10ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# 11ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Unless required by applicable law or agreed to in writing, software 12ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# See the License for the specific language governing permissions and 15ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# limitations under the License. 16ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# 17ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 18ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasifrom bart.common.Analyzer import Analyzer 19ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiimport collections 200328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackmanfrom collections import namedtuple 21ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiimport datetime 22ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiimport gzip 23ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiimport json 24ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiimport os 25ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiimport re 26ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiimport time 27ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiimport trappy 28204f03bccbd5482e459ceb46b397875956c63da5Chris Redpathfrom devlib import TargetError 29ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 30ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Configure logging 31ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiimport logging 32ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 33ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Add JSON parsing support 34ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasifrom conf import JsonConf 35ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 36ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiimport wlgen 37ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 389ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackmanfrom devlib import TargetError 399ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman 400328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan JackmanExperiment = namedtuple('Experiment', ['wload_name', 'wload', 410328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman 'conf', 'iteration', 'out_dir']) 420328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman 43ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasiclass Executor(): 447b764f318505bd13991b37d650cf3b512531a872Brendan Jackman """ 457b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Abstraction for running sets of experiments and gathering data from targets 467b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 477b764f318505bd13991b37d650cf3b512531a872Brendan Jackman An executor can be configured to run a set of workloads (wloads) in each 487b764f318505bd13991b37d650cf3b512531a872Brendan Jackman different target configuration of a specified set (confs). These wloads and 497b764f318505bd13991b37d650cf3b512531a872Brendan Jackman confs can be specified by the "experiments_conf" input dictionary. Each 507b764f318505bd13991b37d650cf3b512531a872Brendan Jackman (workload, conf, iteration) tuple is called an "experiment". 517b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 527b764f318505bd13991b37d650cf3b512531a872Brendan Jackman After the workloads have been run, the Executor object's `experiments` 537b764f318505bd13991b37d650cf3b512531a872Brendan Jackman attribute is a list of Experiment objects. The `out_dir` attribute of these 547b764f318505bd13991b37d650cf3b512531a872Brendan Jackman objects can be used to find the results of the experiment. This output 557b764f318505bd13991b37d650cf3b512531a872Brendan Jackman directory follows this format: 567b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 577b764f318505bd13991b37d650cf3b512531a872Brendan Jackman results/<test_id>/<wltype>:<conf>:<wload>/<run_id> 587b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 597b764f318505bd13991b37d650cf3b512531a872Brendan Jackman where: 607b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 617b764f318505bd13991b37d650cf3b512531a872Brendan Jackman test_id 627b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Is the "tid" defined by the experiments_conf, or a timestamp based 637b764f318505bd13991b37d650cf3b512531a872Brendan Jackman folder in case "tid" is not specified. 647b764f318505bd13991b37d650cf3b512531a872Brendan Jackman wltype 657b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Is the class of workload executed, e.g. rtapp or sched_perf. 667b764f318505bd13991b37d650cf3b512531a872Brendan Jackman conf 677b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Is the "tag" of one of the specified **confs**. 687b764f318505bd13991b37d650cf3b512531a872Brendan Jackman wload 697b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Is the identifier of one of the specified **wloads**. 707b764f318505bd13991b37d650cf3b512531a872Brendan Jackman run_id 717b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Is the progressive execution number from 1 up to the specified 727b764f318505bd13991b37d650cf3b512531a872Brendan Jackman **iterations**. 737b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 747b764f318505bd13991b37d650cf3b512531a872Brendan Jackman :param experiments_conf: Dict with experiment configuration. Keys are: 757b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 767b764f318505bd13991b37d650cf3b512531a872Brendan Jackman **confs** 777b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Mandatory. Platform configurations to be tested. List of dicts, 787b764f318505bd13991b37d650cf3b512531a872Brendan Jackman each with keys: 797b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 807b764f318505bd13991b37d650cf3b512531a872Brendan Jackman tag 817b764f318505bd13991b37d650cf3b512531a872Brendan Jackman String to identify this configuration. Required, may be empty. 827b764f318505bd13991b37d650cf3b512531a872Brendan Jackman flags 837b764f318505bd13991b37d650cf3b512531a872Brendan Jackman List of strings describing features required for this 847b764f318505bd13991b37d650cf3b512531a872Brendan Jackman conf. Available flags are: 857b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 867b764f318505bd13991b37d650cf3b512531a872Brendan Jackman "ftrace" 877b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Enable collecting ftrace during the experiment. 887b764f318505bd13991b37d650cf3b512531a872Brendan Jackman "freeze_userspace" 897b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Use the cgroups freezer to freeze as many userspace tasks as 907b764f318505bd13991b37d650cf3b512531a872Brendan Jackman possible during the experiment execution, in order to reduce 917b764f318505bd13991b37d650cf3b512531a872Brendan Jackman system noise. Some tasks cannot be frozen, such as those 927b764f318505bd13991b37d650cf3b512531a872Brendan Jackman required to maintain a connection to LISA. 937b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 947b764f318505bd13991b37d650cf3b512531a872Brendan Jackman sched_features 957b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Optional list of features to be written to 967b764f318505bd13991b37d650cf3b512531a872Brendan Jackman /sys/kernel/debug/sched_features. Prepend "NO\_" to a feature to 977b764f318505bd13991b37d650cf3b512531a872Brendan Jackman actively disable it. Requires ``CONFIG_SCHED_DEBUG`` in target 987b764f318505bd13991b37d650cf3b512531a872Brendan Jackman kernel. 997b764f318505bd13991b37d650cf3b512531a872Brendan Jackman cpufreq 1007b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Parameters to configure cpufreq via Devlib's cpufreq 1017b764f318505bd13991b37d650cf3b512531a872Brendan Jackman module. Dictionary with fields: 1027b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1037b764f318505bd13991b37d650cf3b512531a872Brendan Jackman .. TODO link to devlib cpufreq module docs (which don't exist) 1047b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1057b764f318505bd13991b37d650cf3b512531a872Brendan Jackman governor 1067b764f318505bd13991b37d650cf3b512531a872Brendan Jackman cpufreq governor to set (for all CPUs) before execution. The 1077b764f318505bd13991b37d650cf3b512531a872Brendan Jackman previous governor is not restored when execution is finished. 1087b764f318505bd13991b37d650cf3b512531a872Brendan Jackman governor_tunables 1097b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Dictionary of governor-specific tunables, expanded and passed as 1107b764f318505bd13991b37d650cf3b512531a872Brendan Jackman kwargs to the cpufreq module's ``set_governor_tunables`` method. 1117b764f318505bd13991b37d650cf3b512531a872Brendan Jackman freq 1127b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Requires "governor" to be "userspace". Dictionary mapping CPU 1137b764f318505bd13991b37d650cf3b512531a872Brendan Jackman numbers to frequencies. Exact frequencies should be available on 1147b764f318505bd13991b37d650cf3b512531a872Brendan Jackman those CPUs. It is not necessary to provide a frequency for every 1157b764f318505bd13991b37d650cf3b512531a872Brendan Jackman CPU - the frequency for unspecified CPUs is not affected. Note 1167b764f318505bd13991b37d650cf3b512531a872Brendan Jackman that cpufreq will transparrently set the frequencies of any 1177b764f318505bd13991b37d650cf3b512531a872Brendan Jackman other CPUs sharing a clock domain. 1187b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1197b764f318505bd13991b37d650cf3b512531a872Brendan Jackman cgroups 1207b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Optional cgroups configuration. To use this, ensure the 'cgroups' 1217b764f318505bd13991b37d650cf3b512531a872Brendan Jackman devlib module is enabled in your test_conf Contains fields: 1227b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1237b764f318505bd13991b37d650cf3b512531a872Brendan Jackman .. TODO reference test_conf 1247b764f318505bd13991b37d650cf3b512531a872Brendan Jackman .. TODO link to devlib cgroup module's docs (which don't exist) 1257b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1267b764f318505bd13991b37d650cf3b512531a872Brendan Jackman conf 1277b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Dict specifying the cgroup controllers, cgroups, and cgroup 1287b764f318505bd13991b37d650cf3b512531a872Brendan Jackman parameters to setup. If a controller listed here is not 1297b764f318505bd13991b37d650cf3b512531a872Brendan Jackman enabled in the target kernel, a message is logged and the 1307b764f318505bd13991b37d650cf3b512531a872Brendan Jackman configuration is **ignored**. Of the form: 1317b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1327b764f318505bd13991b37d650cf3b512531a872Brendan Jackman :: 1337b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1347b764f318505bd13991b37d650cf3b512531a872Brendan Jackman "<controller>" : { 1357b764f318505bd13991b37d650cf3b512531a872Brendan Jackman "<group1>" : { "<group_param" : <value> } 1367b764f318505bd13991b37d650cf3b512531a872Brendan Jackman "<group2>" : { "<group_param" : <value> } 1377b764f318505bd13991b37d650cf3b512531a872Brendan Jackman } 1387b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1397b764f318505bd13991b37d650cf3b512531a872Brendan Jackman These cgroups can then be used in the "cgroup" field of workload 1407b764f318505bd13991b37d650cf3b512531a872Brendan Jackman specifications. 1417b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1427b764f318505bd13991b37d650cf3b512531a872Brendan Jackman default 1437b764f318505bd13991b37d650cf3b512531a872Brendan Jackman The default cgroup to run workloads in, if no "cgroup" is 1447b764f318505bd13991b37d650cf3b512531a872Brendan Jackman specified. 1457b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1467b764f318505bd13991b37d650cf3b512531a872Brendan Jackman For example, to create a cpuset cgroup named "/big" which 1477b764f318505bd13991b37d650cf3b512531a872Brendan Jackman restricts constituent tasks to CPUs 1 and 2: 1487b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1497b764f318505bd13991b37d650cf3b512531a872Brendan Jackman :: 1507b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1517b764f318505bd13991b37d650cf3b512531a872Brendan Jackman "cgroups" : { 1527b764f318505bd13991b37d650cf3b512531a872Brendan Jackman "conf" : { 1537b764f318505bd13991b37d650cf3b512531a872Brendan Jackman "cpuset" : { 1547b764f318505bd13991b37d650cf3b512531a872Brendan Jackman "/big" : {"cpus" : "1-2"}, 1557b764f318505bd13991b37d650cf3b512531a872Brendan Jackman } 1567b764f318505bd13991b37d650cf3b512531a872Brendan Jackman }, 1577b764f318505bd13991b37d650cf3b512531a872Brendan Jackman "default" : "/", 1587b764f318505bd13991b37d650cf3b512531a872Brendan Jackman } 1597b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1607b764f318505bd13991b37d650cf3b512531a872Brendan Jackman **wloads** 1617b764f318505bd13991b37d650cf3b512531a872Brendan Jackman .. TODO document wloads field. 1627b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1637b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Mandatory. Workloads to run on each platform configuration 1647b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 1657b764f318505bd13991b37d650cf3b512531a872Brendan Jackman **iterations** 1667b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Number of iterations for each workload/conf combination. Default 1677b764f318505bd13991b37d650cf3b512531a872Brendan Jackman is 1. 1687b764f318505bd13991b37d650cf3b512531a872Brendan Jackman :type experiments_conf: dict 1697b764f318505bd13991b37d650cf3b512531a872Brendan Jackman """ 1707b764f318505bd13991b37d650cf3b512531a872Brendan Jackman 171cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman critical_tasks = { 172cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 'linux': ['init', 'systemd', 'sh', 'ssh'], 173cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 'android': [ 17441d37527c49ef0cba068ca5aafb6cd858bde7797Brendan Jackman 'sh', 'adbd', 175cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 'usb', 'transport', 176cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman # We don't actually need this task but on Google Pixel it apparently 177cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman # cannot be frozen, so the cgroup state gets stuck in FREEZING if we 178cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman # try to freeze it. 179cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 'thermal-engine' 180cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman ] 181cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman } 1827b764f318505bd13991b37d650cf3b512531a872Brendan Jackman """ 1837b764f318505bd13991b37d650cf3b512531a872Brendan Jackman Dictionary mapping OS name to list of task names that we can't afford to 1847b764f318505bd13991b37d650cf3b512531a872Brendan Jackman freeze when using freeeze_userspace. 1857b764f318505bd13991b37d650cf3b512531a872Brendan Jackman """ 186ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 1872bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman def __init__(self, test_env, experiments_conf): 188ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Initialize globals 189145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi self._default_cgroup = None 190ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self._cgroup = None 191ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 192c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi # Setup logging 193c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log = logging.getLogger('Executor') 194c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi 195ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Setup test configuration 1962bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman if isinstance(experiments_conf, dict): 197c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Loading custom (inline) test configuration') 1982bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman self._experiments_conf = experiments_conf 1992bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman elif isinstance(experiments_conf, str): 200c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Loading custom (file) test configuration') 2012bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman json_conf = JsonConf(experiments_conf) 2022bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman self._experiments_conf = json_conf.load() 203ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi else: 2042bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman raise ValueError( 2052bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman 'experiments_conf must be either a dictionary or a filepath') 206ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 207ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Check for mandatory configurations 2082bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman if not self._experiments_conf.get('confs', None): 209c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi raise ValueError('Configuration error: ' 210c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi 'missing "conf" definitions') 2112bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman if not self._experiments_conf.get('wloads', None): 212c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi raise ValueError('Configuration error: ' 213c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi 'missing "wloads" definitions') 214ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 215324d7fa43f58a074292caca4f08e76a17ea94e75Brendan Jackman self.te = test_env 216ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self.target = self.te.target 217ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 2182bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman self._iterations = self._experiments_conf.get('iterations', 1) 219ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Compute total number of experiments 220705db83c4e9ab166cc59b2d05bfb457cc6bb49baBrendan Jackman self._exp_count = self._iterations \ 2212bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman * len(self._experiments_conf['wloads']) \ 2222bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman * len(self._experiments_conf['confs']) 223ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 224c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._print_section('Experiments configuration') 225ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 226c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Configured to run:') 227ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 228c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(' %3d target configurations:', 229c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi len(self._experiments_conf['confs'])) 2302bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman target_confs = [conf['tag'] for conf in self._experiments_conf['confs']] 231ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi target_confs = ', '.join(target_confs) 232c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(' %s', target_confs) 233ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 234c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(' %3d workloads (%d iterations each)', 235c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi len(self._experiments_conf['wloads']), 236c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._iterations) 2372bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman wload_confs = ', '.join(self._experiments_conf['wloads']) 238c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(' %s', wload_confs) 239ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 240c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Total: %d experiments', self._exp_count) 241ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 242c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Results will be collected under:') 243c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(' %s', self.te.res_dir) 244ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 245ace366e609c242665f584a4b9a94e8232839ded3Brendan Jackman if any(wl['type'] == 'rt-app' 246ace366e609c242665f584a4b9a94e8232839ded3Brendan Jackman for wl in self._experiments_conf['wloads'].values()): 247ace366e609c242665f584a4b9a94e8232839ded3Brendan Jackman self._log.info('rt-app workloads found, installing tool on target') 248ace366e609c242665f584a4b9a94e8232839ded3Brendan Jackman self.te.install_tools(['rt-app']) 249ace366e609c242665f584a4b9a94e8232839ded3Brendan Jackman 250ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def run(self): 251c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._print_section('Experiments execution') 252ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 2530328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman self.experiments = [] 2540328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman 255ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Run all the configured experiments 256ca9d9295cb18dfb04e85c29a12b5f28e8d8cf511Brendan Jackman exp_idx = 0 2572bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman for tc in self._experiments_conf['confs']: 258ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # TARGET: configuration 259ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if not self._target_configure(tc): 260ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi continue 2612bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman for wl_idx in self._experiments_conf['wloads']: 262ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # TEST: configuration 2630328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman wload, test_dir = self._wload_init(tc, wl_idx) 264705db83c4e9ab166cc59b2d05bfb457cc6bb49baBrendan Jackman for itr_idx in range(1, self._iterations + 1): 2650328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman exp = Experiment( 2660328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman wload_name=wl_idx, 2670328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman wload=wload, 2680328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman conf=tc, 2690328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman iteration=itr_idx, 2700328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman out_dir=os.path.join(test_dir, str(itr_idx))) 2710328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman self.experiments.append(exp) 2720328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman 273ca9d9295cb18dfb04e85c29a12b5f28e8d8cf511Brendan Jackman # WORKLOAD: execution 274ca9d9295cb18dfb04e85c29a12b5f28e8d8cf511Brendan Jackman self._wload_run(exp_idx, exp) 275ca9d9295cb18dfb04e85c29a12b5f28e8d8cf511Brendan Jackman exp_idx += 1 2769ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman self._target_cleanup(tc) 2779ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman 278c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._print_section('Experiments execution completed') 279c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Results available in:') 280c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(' %s', self.te.res_dir) 281ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 282ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 283ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi################################################################################ 284ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Target Configuration 285ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi################################################################################ 286ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 287ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _cgroups_init(self, tc): 288145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi self._default_cgroup = None 289ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'cgroups' not in tc: 290ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return True 29156c6cd2564b37923e9cb7ee0df59b3135651ce13Patrick Bellasi if 'cgroups' not in self.target.modules: 29256c6cd2564b37923e9cb7ee0df59b3135651ce13Patrick Bellasi raise RuntimeError('CGroups module not available. Please ensure ' 29356c6cd2564b37923e9cb7ee0df59b3135651ce13Patrick Bellasi '"cgroups" is listed in your target/test modules') 294c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Initialize CGroups support...') 295ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi errors = False 296ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi for kind in tc['cgroups']['conf']: 297c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Setup [%s] CGroup controller...', kind) 298ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi controller = self.target.cgroups.controller(kind) 299ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if not controller: 300c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.warning('CGroups controller [%s] NOT available', 301c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi kind) 302ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi errors = True 303ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return not errors 304ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 305ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _setup_kernel(self, tc): 306ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Deploy kernel on the device 307ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self.te.install_kernel(tc, reboot=True) 308ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Setup the rootfs for the experiments 309ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self._setup_rootfs(tc) 310ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 311ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _setup_sched_features(self, tc): 312ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'sched_features' not in tc: 313c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.debug('Scheduler features configuration not provided') 314ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return 315ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi feats = tc['sched_features'].split(",") 316ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi for feat in feats: 317c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Set scheduler feature: %s', feat) 318750eb5a668cc85c89ec63e53614323dc3e9518f6Brendan Jackman self.target.execute('echo {} > /sys/kernel/debug/sched_features'.format(feat), 319750eb5a668cc85c89ec63e53614323dc3e9518f6Brendan Jackman as_root=True) 320ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 321ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _setup_rootfs(self, tc): 322ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Initialize CGroups if required 323ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self._cgroups_init(tc) 324ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Setup target folder for experiments execution 325ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self.te.run_dir = os.path.join( 326ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self.target.working_directory, TGT_RUN_DIR) 327ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Create run folder as tmpfs 328c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.debug('Setup RT-App run folder [%s]...', self.te.run_dir) 329ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self.target.execute('[ -d {0} ] || mkdir {0}'\ 3309ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman .format(self.te.run_dir)) 331ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self.target.execute( 332ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 'grep schedtest /proc/mounts || '\ 333ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi ' mount -t tmpfs -o size=1024m {} {}'\ 334ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi .format('schedtest', self.te.run_dir), 335ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi as_root=True) 3369ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman # tmpfs mounts have an SELinux context with "tmpfs" as the type (while 3379ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman # other files we create have "shell_data_file"). That prevents non-root 3389ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman # users from creating files in tmpfs mounts. For now, just put SELinux 3399ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman # in permissive mode to get around that. 3409ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman try: 3419ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman # First, save the old SELinux mode 3429ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman self._old_selinux_mode = self.target.execute('getenforce') 343c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.warning('Setting target SELinux in permissive mode') 3449ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman self.target.execute('setenforce 0', as_root=True) 34593bad43d607bd6c8c0c73b1745bdf2f989900583Brendan Jackman except TargetError: 34693bad43d607bd6c8c0c73b1745bdf2f989900583Brendan Jackman # Probably the target doesn't have SELinux, or there are no 34793bad43d607bd6c8c0c73b1745bdf2f989900583Brendan Jackman # contexts set up. No problem. 34893bad43d607bd6c8c0c73b1745bdf2f989900583Brendan Jackman self._log.warning("Couldn't set SELinux in permissive mode. " 34993bad43d607bd6c8c0c73b1745bdf2f989900583Brendan Jackman "This is probably fine.") 35093bad43d607bd6c8c0c73b1745bdf2f989900583Brendan Jackman self._old_selinux_mode = None 351ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 352ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _setup_cpufreq(self, tc): 353ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'cpufreq' not in tc: 354c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.warning('cpufreq governor not specified, ' 355c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi 'using currently configured governor') 356ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return 357ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 358ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi cpufreq = tc['cpufreq'] 359c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Configuring all CPUs to use [%s] cpufreq governor', 360c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi cpufreq['governor']) 361ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 3629883f9edb93e5f8e818992e21f2518340135aa8fJuri Lelli self.target.cpufreq.set_all_governors(cpufreq['governor']) 3639883f9edb93e5f8e818992e21f2518340135aa8fJuri Lelli 364d20484c2660546c38b1ae1ef441eda293aec84b2Brendan Jackman if 'freqs' in cpufreq: 365d20484c2660546c38b1ae1ef441eda293aec84b2Brendan Jackman if cpufreq['governor'] != 'userspace': 366d20484c2660546c38b1ae1ef441eda293aec84b2Brendan Jackman raise ValueError('Must use userspace governor to set CPU freqs') 367d20484c2660546c38b1ae1ef441eda293aec84b2Brendan Jackman self._log.info(r'%14s - CPU frequencies: %s', 368d20484c2660546c38b1ae1ef441eda293aec84b2Brendan Jackman 'CPUFreq', str(cpufreq['freqs'])) 369d20484c2660546c38b1ae1ef441eda293aec84b2Brendan Jackman for cpu, freq in cpufreq['freqs'].iteritems(): 370d20484c2660546c38b1ae1ef441eda293aec84b2Brendan Jackman self.target.cpufreq.set_frequency(cpu, freq) 371d20484c2660546c38b1ae1ef441eda293aec84b2Brendan Jackman 3729883f9edb93e5f8e818992e21f2518340135aa8fJuri Lelli if 'params' in cpufreq: 373c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('governor params: %s', str(cpufreq['params'])) 3749883f9edb93e5f8e818992e21f2518340135aa8fJuri Lelli for cpu in self.target.list_online_cpus(): 3759883f9edb93e5f8e818992e21f2518340135aa8fJuri Lelli self.target.cpufreq.set_governor_tunables( 3769883f9edb93e5f8e818992e21f2518340135aa8fJuri Lelli cpu, 3779883f9edb93e5f8e818992e21f2518340135aa8fJuri Lelli cpufreq['governor'], 3789883f9edb93e5f8e818992e21f2518340135aa8fJuri Lelli **cpufreq['params']) 379ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 380ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _setup_cgroups(self, tc): 381ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'cgroups' not in tc: 382ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return True 383ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Setup default CGroup to run tasks into 384ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'default' in tc['cgroups']: 385145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi self._default_cgroup = tc['cgroups']['default'] 386ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Configure each required controller 387ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'conf' not in tc['cgroups']: 388ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return True 389ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi errors = False 390ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi for kind in tc['cgroups']['conf']: 391ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi controller = self.target.cgroups.controller(kind) 392ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if not controller: 393c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.warning('Configuration error: ' 394c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi '[%s] contoller NOT supported', 395c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi kind) 396ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi errors = True 397ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi continue 398ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self._setup_controller(tc, controller) 399ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return not errors 400ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 401ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _setup_controller(self, tc, controller): 402ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi kind = controller.kind 403ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Configure each required groups for that controller 404ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi errors = False 405ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi for name in tc['cgroups']['conf'][controller.kind]: 406c9607f05deb81ce8be90a71adc9c71018f626028Patrick Bellasi if name[0] != '/': 407c9607f05deb81ce8be90a71adc9c71018f626028Patrick Bellasi raise ValueError('Wrong CGroup name [{}]. ' 408c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi 'CGroups names must start by "/".' 409c9607f05deb81ce8be90a71adc9c71018f626028Patrick Bellasi .format(name)) 410ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi group = controller.cgroup(name) 411ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if not group: 412c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.warning('Configuration error: ' 413c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi '[%s/%s] cgroup NOT available', 414c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi kind, name) 415ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi errors = True 416ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi continue 417ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self._setup_group(tc, group) 418ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return not errors 419ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 420ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _setup_group(self, tc, group): 421ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi kind = group.controller.kind 422ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi name = group.name 423ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Configure each required attribute 424ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi group.set(**tc['cgroups']['conf'][kind][name]) 425ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 426204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath def _setup_files(self, tc): 427204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath if 'files' not in tc: 428204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath self._log.debug('\'files\' Configuration block not provided') 429204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath return True 430204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath for name, value in tc['files'].iteritems(): 431204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath check = False 432204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath if name.startswith('!/'): 433204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath check = True 434204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath name = name[1:] 435204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath self._log.info('File Write(check=%s): \'%s\' -> \'%s\'', 436204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath check, value, name) 437204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath try: 438204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath self.target.write_value(name, value, True) 439204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath except TargetError: 440204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath self._log.info('File Write Failed: \'%s\' -> \'%s\'', 441204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath value, name) 442204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath if check: 443204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath raise 444204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath return False 445204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath 446ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _target_configure(self, tc): 447c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._print_header( 448c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi 'configuring target for [{}] experiments'\ 449ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi .format(tc['tag'])) 450ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self._setup_kernel(tc) 451ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self._setup_sched_features(tc) 452ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self._setup_cpufreq(tc) 453204f03bccbd5482e459ceb46b397875956c63da5Chris Redpath self._setup_files(tc) 454ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return self._setup_cgroups(tc) 455ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 456ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _target_conf_flag(self, tc, flag): 457ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'flags' not in tc: 458ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi has_flag = False 459ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi else: 460ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi has_flag = flag in tc['flags'] 461c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.debug('Check if target configuration [%s] has flag [%s]: %s', 462c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi tc['tag'], flag, has_flag) 463ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return has_flag 464ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 4659ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman def _target_cleanup(self, tc): 4669ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman if self._old_selinux_mode is not None: 467c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Restoring target SELinux mode: %s', 468c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._old_selinux_mode) 4699ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman self.target.execute('setenforce ' + self._old_selinux_mode, 4709ecfd1a4364b29b27dab6e766dee000820df8d48Brendan Jackman as_root=True) 471ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 472ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi################################################################################ 473ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Workload Setup and Execution 474ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi################################################################################ 475ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 476ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _wload_cpus(self, wl_idx, wlspec): 477ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if not 'cpus' in wlspec['conf']: 478ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return None 479ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi cpus = wlspec['conf']['cpus'] 480ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 481ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi if type(cpus) == list: 482ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi return cpus 483ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if type(cpus) == int: 484ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi return [cpus] 485ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi 486ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi # SMP target (or not bL module loaded) 487ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi if not hasattr(self.target, 'bl'): 488ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi if 'first' in cpus: 489ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi return [ self.target.list_online_cpus()[0] ] 490ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi if 'last' in cpus: 491ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi return [ self.target.list_online_cpus()[-1] ] 492ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi return self.target.list_online_cpus() 493ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi 494ea9ffe39f2296c9c1acd76ebede497a3a04a81e0Patrick Bellasi # big.LITTLE target 495ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if cpus.startswith('littles'): 496ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'first' in cpus: 497ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return [ self.target.bl.littles_online[0] ] 498ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'last' in cpus: 499ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return [ self.target.bl.littles_online[-1] ] 500ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return self.target.bl.littles_online 501ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if cpus.startswith('bigs'): 502ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'first' in cpus: 503ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return [ self.target.bl.bigs_online[0] ] 504ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'last' in cpus: 505ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return [ self.target.bl.bigs_online[-1] ] 506ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return self.target.bl.bigs_online 507c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi raise ValueError('unsupported [{}] "cpus" value for [{}] ' 508c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi 'workload specification' 509c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi .format(cpus, wl_idx)) 510ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 511ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _wload_task_idxs(self, wl_idx, tasks): 512ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if type(tasks) == int: 513ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return range(tasks) 514ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if tasks == 'cpus': 515ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return range(len(self.target.core_names)) 516ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if tasks == 'little': 517ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return range(len([t 518ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi for t in self.target.core_names 519ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if t == self.target.little_core])) 520ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if tasks == 'big': 521ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return range(len([t 522ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi for t in self.target.core_names 523ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if t == self.target.big_core])) 524c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi raise ValueError('unsupported "tasks" value for [{}] RT-App ' 525c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi 'workload specification' 526c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi .format(wl_idx)) 527ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 528ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _wload_rtapp(self, wl_idx, wlspec, cpus): 529ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi conf = wlspec['conf'] 530c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.debug('Configuring [%s] rt-app...', conf['class']) 531ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 532ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Setup a default "empty" task name prefix 533ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'prefix' not in conf: 534ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi conf['prefix'] = 'task_' 535ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 536ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Setup a default loadref CPU 537ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi loadref = None 538ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if 'loadref' in wlspec: 539ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi loadref = wlspec['loadref'] 540ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 541ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if conf['class'] == 'profile': 542ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi params = {} 543ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Load each task specification 54443a28826460dd192805df1d57128d34f19c3ef80Brendan Jackman for task_name, task in conf['params'].items(): 54569452dfb17022adbb7cd2a43d91ca2dcb625f645Patrick Bellasi if task['kind'] not in wlgen.__dict__: 546c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.error('RTA task of kind [%s] not supported', 547c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi task['kind']) 548c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi raise ValueError('unsupported "kind" value for task [{}] ' 549c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi 'in RT-App workload specification' 550c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi .format(task)) 55169452dfb17022adbb7cd2a43d91ca2dcb625f645Patrick Bellasi task_ctor = getattr(wlgen, task['kind']) 55243a28826460dd192805df1d57128d34f19c3ef80Brendan Jackman num_tasks = task.get('tasks', 1) 55343a28826460dd192805df1d57128d34f19c3ef80Brendan Jackman task_idxs = self._wload_task_idxs(wl_idx, num_tasks) 55443a28826460dd192805df1d57128d34f19c3ef80Brendan Jackman for idx in task_idxs: 555045fa0359157b4adf833e1c7a2c84663f89611cbPatrick Bellasi idx_name = "_{}".format(idx) if len(task_idxs) > 1 else "" 55643a28826460dd192805df1d57128d34f19c3ef80Brendan Jackman task_name_idx = conf['prefix'] + task_name + idx_name 55743a28826460dd192805df1d57128d34f19c3ef80Brendan Jackman params[task_name_idx] = task_ctor(**task['params']).get() 55843a28826460dd192805df1d57128d34f19c3ef80Brendan Jackman 559ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi rtapp = wlgen.RTA(self.target, 560ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi wl_idx, calibration = self.te.calibration()) 561ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi rtapp.conf(kind='profile', params=params, loadref=loadref, 562f936d35ffe082d612542763bc7faac47f3605421Brendan Jackman cpus=cpus, run_dir=self.te.run_dir, 5632b88eb10421ba7423c54682e0bd7769cf989ba70Brendan Jackman duration=conf.get('duration')) 564ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return rtapp 565ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 566ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if conf['class'] == 'periodic': 567ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi task_idxs = self._wload_task_idxs(wl_idx, conf['tasks']) 568ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi params = {} 569ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi for idx in task_idxs: 570ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi task = conf['prefix'] + str(idx) 5714e98ca3154a8bb198b57f520d16cc510ace3fe5bJuri Lelli params[task] = wlgen.Periodic(**conf['params']).get() 572ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi rtapp = wlgen.RTA(self.target, 573ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi wl_idx, calibration = self.te.calibration()) 574ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi rtapp.conf(kind='profile', params=params, loadref=loadref, 575f936d35ffe082d612542763bc7faac47f3605421Brendan Jackman cpus=cpus, run_dir=self.te.run_dir, 5762b88eb10421ba7423c54682e0bd7769cf989ba70Brendan Jackman duration=conf.get('duration')) 577ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return rtapp 578ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 579ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if conf['class'] == 'custom': 580ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi rtapp = wlgen.RTA(self.target, 581ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi wl_idx, calibration = self.te.calib) 582ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi rtapp.conf(kind='custom', 583ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi params=conf['json'], 584ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi duration=conf['duration'], 585ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi loadref=loadref, 586ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi cpus=cpus, run_dir=self.te.run_dir) 587ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return rtapp 588ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 589c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi raise ValueError('unsupported \'class\' value for [{}] ' 590c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi 'RT-App workload specification' 591c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi .format(wl_idx)) 592ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 593ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _wload_perf_bench(self, wl_idx, wlspec, cpus): 594ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi conf = wlspec['conf'] 595c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.debug('Configuring perf_message...') 596ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 597ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if conf['class'] == 'messaging': 598ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi perf_bench = wlgen.PerfMessaging(self.target, wl_idx) 599ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi perf_bench.conf(**conf['params']) 600ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return perf_bench 601ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 602ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if conf['class'] == 'pipe': 603ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi perf_bench = wlgen.PerfPipe(self.target, wl_idx) 604ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi perf_bench.conf(**conf['params']) 605ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return perf_bench 606ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 607c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi raise ValueError('unsupported "class" value for [{}] ' 608c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi 'perf bench workload specification' 609c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi .format(wl_idx)) 610ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 611ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _wload_conf(self, wl_idx, wlspec): 612ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 613ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # CPUS: setup execution on CPUs if required by configuration 614ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi cpus = self._wload_cpus(wl_idx, wlspec) 615ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 616145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi # CGroup: setup CGroups if requried by configuration 617145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi self._cgroup = self._default_cgroup 618145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi if 'cgroup' in wlspec: 619145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi if 'cgroups' not in self.target.modules: 620145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi raise RuntimeError('Target not supporting CGroups or CGroups ' 621145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi 'not configured for the current test configuration') 622145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi self._cgroup = wlspec['cgroup'] 623145b3cef7d5a6e509ec155216713e0545da65885Patrick Bellasi 624ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if wlspec['type'] == 'rt-app': 625ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return self._wload_rtapp(wl_idx, wlspec, cpus) 626ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if wlspec['type'] == 'perf_bench': 627ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi return self._wload_perf_bench(wl_idx, wlspec, cpus) 628ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 629ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 630c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi raise ValueError('unsupported "type" value for [{}] ' 631c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi 'workload specification' 632c25cc8d70f24e6263b2a6b61b430e3f5ca34ed55Patrick Bellasi .format(wl_idx)) 633ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 634ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi def _wload_init(self, tc, wl_idx): 635ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi tc_idx = tc['tag'] 636ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 637ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Configure the test workload 6382bafed53a78810119b683ee1e83eb7ec972b8a96Brendan Jackman wlspec = self._experiments_conf['wloads'][wl_idx] 639ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi wload = self._wload_conf(wl_idx, wlspec) 640ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 641ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Keep track of platform configuration 642d6ffaf98744ddbcac1ab58d7278ce8c6c34be88aBrendan Jackman test_dir = '{}/{}:{}:{}'\ 643ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi .format(self.te.res_dir, wload.wtype, tc_idx, wl_idx) 6440ec5fcf10e834fd1c5f6505430c81426f5b5188dBrendan Jackman os.makedirs(test_dir) 645d6ffaf98744ddbcac1ab58d7278ce8c6c34be88aBrendan Jackman self.te.platform_dump(test_dir) 646ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 647ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Keep track of kernel configuration and version 648ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi config = self.target.config 649d6ffaf98744ddbcac1ab58d7278ce8c6c34be88aBrendan Jackman with gzip.open(os.path.join(test_dir, 'kernel.config'), 'wb') as fh: 650ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi fh.write(config.text) 651ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi output = self.target.execute('{} uname -a'\ 652ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi .format(self.target.busybox)) 653d6ffaf98744ddbcac1ab58d7278ce8c6c34be88aBrendan Jackman with open(os.path.join(test_dir, 'kernel.version'), 'w') as fh: 654ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi fh.write(output) 655ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 656d6ffaf98744ddbcac1ab58d7278ce8c6c34be88aBrendan Jackman return wload, test_dir 657ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 6580328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman def _wload_run(self, exp_idx, experiment): 6590328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman tc = experiment.conf 6600328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman wload = experiment.wload 661ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi tc_idx = tc['tag'] 662ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 663c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._print_title('Experiment {}/{}, [{}:{}] {}/{}'\ 664ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi .format(exp_idx, self._exp_count, 6650328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman tc_idx, experiment.wload_name, 6660328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman experiment.iteration, self._iterations)) 667ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 668ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # Setup local results folder 669c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.debug('out_dir set to [%s]', experiment.out_dir) 6700328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman os.system('mkdir -p ' + experiment.out_dir) 671ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 672cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman # Freeze all userspace tasks that we don't need for running tests 673cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman need_thaw = False 674cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman if self._target_conf_flag(tc, 'freeze_userspace'): 675cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman need_thaw = self._freeze_userspace() 676cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 677ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # FTRACE: start (if a configuration has been provided) 678ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if self.te.ftrace and self._target_conf_flag(tc, 'ftrace'): 679c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.warning('FTrace events collection enabled') 680ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self.te.ftrace.start() 681ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 682ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # ENERGY: start sampling 683ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if self.te.emeter: 684ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self.te.emeter.reset() 685ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 686ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # WORKLOAD: Run the configured workload 6870328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman wload.run(out_dir=experiment.out_dir, cgroup=self._cgroup) 688ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 689ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # ENERGY: collect measurements 690ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if self.te.emeter: 6910328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman self.te.emeter.report(experiment.out_dir) 692ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 693ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi # FTRACE: stop and collect measurements 694ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi if self.te.ftrace and self._target_conf_flag(tc, 'ftrace'): 695ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi self.te.ftrace.stop() 6962a61af85fcc950272762319d91c0462eb78fe409Patrick Bellasi 6970328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman trace_file = experiment.out_dir + '/trace.dat' 6982a61af85fcc950272762319d91c0462eb78fe409Patrick Bellasi self.te.ftrace.get_trace(trace_file) 699c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Collected FTrace binary trace:') 700c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(' %s', 701c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi trace_file.replace(self.te.res_dir, '<res_dir>')) 7022a61af85fcc950272762319d91c0462eb78fe409Patrick Bellasi 7030328c6163c4c5f90ef2bfec1513ec1388ef6e232Brendan Jackman stats_file = experiment.out_dir + '/trace_stat.json' 7042a61af85fcc950272762319d91c0462eb78fe409Patrick Bellasi self.te.ftrace.get_stats(stats_file) 705c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('Collected FTrace function profiling:') 706c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(' %s', 707c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi stats_file.replace(self.te.res_dir, '<res_dir>')) 708ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 709cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman # Unfreeze the tasks we froze 710cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman if need_thaw: 711cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman self._thaw_userspace() 712cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 713c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._print_footer() 714293aba12c7b69a2e9ba7808e7869c4692725b559Patrick Bellasi 715cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman def _freeze_userspace(self): 716cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman if 'cgroups' not in self.target.modules: 717cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman raise RuntimeError( 718cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 'Failed to freeze userspace. Ensure "cgroups" module is listed ' 719cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 'among modules in target/test configuration') 720cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman controllers = [s.name for s in self.target.cgroups.list_subsystems()] 721cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman if 'freezer' not in controllers: 722cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman self._log.warning('No freezer cgroup controller on target. ' 723cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 'Not freezing userspace') 724cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman return False 725cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 726cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman exclude = self.critical_tasks[self.te.target.os] 727cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman self._log.info('Freezing all tasks except: %s', ','.join(exclude)) 728cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman self.te.target.cgroups.freeze(exclude) 729cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman return True 730cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 731cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 732cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman def _thaw_userspace(self): 733cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman self._log.info('Un-freezing userspace tasks') 734cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman self.te.target.cgroups.freeze(thaw=True) 735cd59861cead6ff46da93810531af786a9b68cf04Brendan Jackman 736ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi################################################################################ 737ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Utility Functions 738ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi################################################################################ 739ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 740c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi def _print_section(self, message): 741c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('') 742c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(FMT_SECTION) 743c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(message) 744c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(FMT_SECTION) 745ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 746c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi def _print_header(self, message): 747c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info('') 748c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(FMT_HEADER) 749c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(message) 750ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 751c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi def _print_title(self, message): 752c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(FMT_TITLE) 753c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(message) 754ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 755c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi def _print_footer(self, message=None): 756293aba12c7b69a2e9ba7808e7869c4692725b559Patrick Bellasi if message: 757c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(message) 758c278c2343c7f25083a80cb164b6bdc761d50050bPatrick Bellasi self._log.info(FMT_FOOTER) 759293aba12c7b69a2e9ba7808e7869c4692725b559Patrick Bellasi 760ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 761ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi################################################################################ 762ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Globals 763ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi################################################################################ 764ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 765ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Regular expression for comments 766ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick BellasiJSON_COMMENTS_RE = re.compile( 767ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi '(^)?[^\S\n]*/(?:\*(.*?)\*/[^\S\n]*|/[^\n]*)($)?', 768ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi re.DOTALL | re.MULTILINE 769ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi) 770ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 771ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Target specific paths 772ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick BellasiTGT_RUN_DIR = 'run_dir' 773ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 774ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# Logging formatters 775ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick BellasiFMT_SECTION = r'{:#<80}'.format('') 776ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick BellasiFMT_HEADER = r'{:=<80}'.format('') 777ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick BellasiFMT_TITLE = r'{:~<80}'.format('') 778293aba12c7b69a2e9ba7808e7869c4692725b559Patrick BellasiFMT_FOOTER = r'{:-<80}'.format('') 779ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi 780ce73ce0f78dec8da6daa7c1355b1da988f39790dPatrick Bellasi# vim :set tabstop=4 shiftwidth=4 expandtab 781