1de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# Copyright 2017-2017 ARM Limited 2de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# 3de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# Licensed under the Apache License, Version 2.0 (the "License"); 4de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# you may not use this file except in compliance with the License. 5de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# You may obtain a copy of the License at 6de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# 7de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# http://www.apache.org/licenses/LICENSE-2.0 8de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# 9de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# Unless required by applicable law or agreed to in writing, software 10de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# distributed under the License is distributed on an "AS IS" BASIS, 11de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# See the License for the specific language governing permissions and 13de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# limitations under the License. 14de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman# 15de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 16de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackmanfrom bart.common.Utils import select_window 17de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 18de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackmanfrom test import LisaTest, experiment_test 19de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 20de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan JackmanWORKLOAD_DURATION_S = 5 21de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 220bf208ed092a93371533f1001f3694c0f56ea43bBrendan JackmanREQUIRED_CPU_ACTIVE_TIME_PCT = 95 23de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 24de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackmanclass HeavyLoadTest(LisaTest): 25de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman """ 26de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman Test an EAS system under heavy load 27de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 28de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman Runs N 100% RT-App threads where N is the number of CPUs, and checks that 29de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman those tasks were spread across all CPUs in the system by asserting that all 30de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman CPUs were fully utilized up until the first task completed. 31de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman """ 32de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 33de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman test_conf = { 34de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 'ftrace' : { 35de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 'events' : ['cpu_idle', 'sched_switch'], 36de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman }, 37de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 'modules' : ['cgroups'], # Required by freeze_userspace flag 38de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman } 39de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 40de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman experiments_conf = { 41de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "wloads" : { 42de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "n_heavy_tasks" : { 43de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "type" : "rt-app", 44de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "conf" : { 45de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "class" : "profile", 46de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "params" : { 47de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "wmig" : { 48de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "kind" : "Periodic", 49de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "params" : { 50de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "duty_cycle_pct": 100, 51de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "duration_s": WORKLOAD_DURATION_S, 52de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman }, 53de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman # Create one task for each cpu 54de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "tasks" : "cpus", 55de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman }, 56de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman }, 57de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman }, 58de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman }, 59de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman }, 60de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "confs" : [{ 61de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 'tag' : 'energy_aware', 62de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 'flags' : ['ftrace', 'freeze_userspace'], 63de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 'sched_features' : 'ENERGY_AWARE', 64de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman }] 65de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman } 66de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 67de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman @classmethod 68de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman def setUpClass(cls, *args, **kwargs): 6907c24985f8c4964a11483db44e383d0ddf602566Brendan Jackman super(HeavyLoadTest, cls).runExperiments(*args, **kwargs) 70de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 71de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman @experiment_test 72de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman def test_tasks_spread(self, experiment, tasks): 73de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman trace = self.get_trace(experiment) 74de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman start, _ = self.get_window(experiment) 75de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman end = min(self.get_end_times(experiment).values()) 76de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman duration = end - start 77de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 78de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman total_cpu_time = 0 79de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman active_proportions = [] 80de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman for cpu, _ in enumerate(self.target.core_names): 81de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman cpu_active = trace.getCPUActiveSignal(cpu) 82bb71199099bfa011bb026ccd7935246b2d0afed1Brendan Jackman if cpu_active is None: 83bb71199099bfa011bb026ccd7935246b2d0afed1Brendan Jackman raise RuntimeError( 84bb71199099bfa011bb026ccd7935246b2d0afed1Brendan Jackman "Couldn't get CPU-active signal. " 85bb71199099bfa011bb026ccd7935246b2d0afed1Brendan Jackman "Is the 'cpu_idle' ftrace event enabled in the kernel?") 86de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 87de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman # Add extra events to cpu_active signal so that it matches the 88de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman # window exactly 89de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman new_index = sorted(cpu_active.index.tolist() + [start, end]) 90de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman cpu_active = cpu_active.reindex(new_index, method='ffill') 91de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 92de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman active_time = trace.integrate_square_wave(cpu_active[start:end]) 93de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman active_proportions.append(active_time / duration) 94de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 95de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman if any(a < (REQUIRED_CPU_ACTIVE_TIME_PCT / 100.) 96de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman for a in active_proportions): 97de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 98de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman proportions_str = "" 99de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman for cpu, _ in enumerate(self.target.core_names): 100de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman proportions_str += " {:3d} {:5.1f}%\n".format( 101de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman cpu, active_proportions[cpu]*100) 102de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman 103de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman raise AssertionError( 104de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman "Some CPUs were less than {}% utilized\n" 105de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman " CPU active proportions:\n{}".format( 106de5e7f755d9df0946207c08a1740a9eca7a38da5Brendan Jackman REQUIRED_CPU_ACTIVE_TIME_PCT, proportions_str)) 107