Skip to content

Commit

Permalink
tests/eas: Add generic Energy-Model based tests
Browse files Browse the repository at this point in the history
These tests take an EnergyModel describing the platform, and a workload. The
workload is examined to find estimated "optimal" task placements, and
estimations of those task placements' energy efficiency. The workloads are run
on the target, and a trace is collected. This trace is processed to find the
task placement that was actually observed. Using the same metrics that were used
to decide on "optimal" behaviour, the observed behaviour is evaluated for energy
efficiency. If this energy efficiency is significantly worse than the estimated
"optimal" value then a failure is raised.

Excellent energy efficiency can be achieved by packing all tasks onto the least
capable CPU at the lowest clock frequency, but that's not likely to be
desirable. Energy efficiency is not the only criterion for good scheduler
behaviour, so another test is provided using RT-App's "slack" measurement to
assert that required throughput was provided to the workload.

Overall, this aims to allow the same tests to be run on any platform once it has
been described by an EnergyModel.

By making assertions about the estimated *efficiency* of the behaviour, rather
than the behaviour itself, the tests are made more flexible: a given workload
may be serviceable by two entirely different scheduling strategies where one is
only slightly more efficient than the other. In this case, the tests will
automatically allow either strategy to pass. The downside to this approach is
that when a test fails, it is not always obvious what scheduler behaviour was
expected or how the observed behaviour differed from this. It may be possible to
later add more user-visible representation of this information to aid failure
diagnoses.
  • Loading branch information
Brendan Jackman committed Dec 21, 2016
1 parent 8f0865f commit 37918fa
Show file tree
Hide file tree
Showing 3 changed files with 544 additions and 82 deletions.
101 changes: 101 additions & 0 deletions tests/eas/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2016, ARM Limited and contributors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from unittest import SkipTest

from bart.sched.SchedMultiAssert import SchedMultiAssert
from devlib.target import TargetError
from test import LisaTest

WORKLOAD_DURATION_S = 5
WORKLOAD_PERIOD_MS = 10
SWITCH_WINDOW_HALF = 0.5
SMALL_DCYCLE = 10
BIG_DCYCLE = 100
STEP_HIGH_DCYCLE = 50
STEP_LOW_DCYCLE = 10
EXPECTED_RESIDENCY_PCT = 85
OFFLOAD_EXPECTED_BUSY_TIME_PCT = 97
SET_IS_BIG_LITTLE = True
SET_INITIAL_TASK_UTIL = True
OFFLOAD_MIGRATION_MIGRATOR_DELAY = 1

energy_aware_conf = {
'tag' : 'energy_aware',
'flags' : 'ftrace',
'sched_features' : 'ENERGY_AWARE',
}

class EasTest(LisaTest):
"""
Base class for EAS tests
"""

test_conf = {
"ftrace" : {
"events" : [
"sched_overutilized",
"sched_energy_diff",
"sched_load_avg_task",
"sched_load_avg_cpu",
"sched_migrate_task",
"sched_switch",
"cpu_frequency"
],
},
"modules": ["cgroups"],
}

# Set to true to run a test only on heterogeneous systems
skip_on_smp = False

@classmethod
def setUpClass(cls, *args, **kwargs):
super(EasTest, cls)._init(*args, **kwargs)

@classmethod
def _getExperimentsConf(cls, test_env):
if cls.skip_on_smp and not test_env.nrg_model.is_heterogeneous:
raise SkipTest('Test not required on symmetric systems')
return super(EasTest, cls)._getExperimentsConf(test_env)

@classmethod
def _experimentsInit(cls, *args, **kwargs):
super(EasTest, cls)._experimentsInit(*args, **kwargs)

if SET_IS_BIG_LITTLE:
# This flag doesn't exist on mainline-integration kernels, so
# don't worry if the file isn't present (hence verify=False)
cls.target.write_value(
"/proc/sys/kernel/sched_is_big_little", 1, verify=False)

if SET_INITIAL_TASK_UTIL:
# This flag doesn't exist on all kernels, so don't worry if the file
# isn't present (hence verify=False)
cls.target.write_value(
"/proc/sys/kernel/sched_initial_task_util", 1024, verify=False)

def _do_test_first_cpu(self, experiment, tasks):
"""Test that all tasks start on a big CPU"""

sched_assert = self.get_multi_assert(experiment)

self.assertTrue(
sched_assert.assertFirstCpu(
self.te.nrg_model.biggest_cpus,
rank=len(tasks)),
msg="Not all the new generated tasks started on a big CPU")
92 changes: 10 additions & 82 deletions tests/eas/acceptance.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,88 +26,16 @@

from devlib.target import TargetError

from env import TestEnv
from test import LisaTest, experiment_test

# Global test configuration parameters
WORKLOAD_DURATION_S = 5
WORKLOAD_PERIOD_MS = 10
SWITCH_WINDOW_HALF = 0.5
SMALL_DCYCLE = 10
BIG_DCYCLE = 100
STEP_HIGH_DCYCLE = 50
STEP_LOW_DCYCLE = 10
EXPECTED_RESIDENCY_PCT = 85
OFFLOAD_EXPECTED_BUSY_TIME_PCT = 97
SET_IS_BIG_LITTLE = True
SET_INITIAL_TASK_UTIL = True
OFFLOAD_MIGRATION_MIGRATOR_DELAY = 1

energy_aware_conf = {
"tag" : "energy_aware",
"flags" : ["ftrace", "freeze_userspace"],
"sched_features" : "ENERGY_AWARE",
}

class EasTest(LisaTest):
"""
Base class for EAS tests
"""

test_conf = {
"ftrace" : {
"events" : [
"sched_overutilized",
"sched_energy_diff",
"sched_load_avg_task",
"sched_load_avg_cpu",
"sched_migrate_task",
"sched_switch",
"cpu_frequency"
],
},
"modules": ["cgroups"],
}

# Set to true to run a test only on heterogeneous systems
skip_on_smp = False

@classmethod
def setUpClass(cls, *args, **kwargs):
super(EasTest, cls)._init(*args, **kwargs)

@classmethod
def _getExperimentsConf(cls, test_env):
if cls.skip_on_smp and not test_env.nrg_model.is_heterogeneous:
raise SkipTest('Test not required on symmetric systems')
return super(EasTest, cls)._getExperimentsConf(test_env)

@classmethod
def _experimentsInit(cls, *args, **kwargs):
super(EasTest, cls)._experimentsInit(*args, **kwargs)

if SET_IS_BIG_LITTLE:
# This flag doesn't exist on mainline-integration kernels, so
# don't worry if the file isn't present (hence verify=False)
cls.target.write_value(
"/proc/sys/kernel/sched_is_big_little", 1, verify=False)

if SET_INITIAL_TASK_UTIL:
# This flag doesn't exist on all kernels, so don't worry if the file
# isn't present (hence verify=False)
cls.target.write_value(
"/proc/sys/kernel/sched_initial_task_util", 1024, verify=False)

def _do_test_first_cpu(self, experiment, tasks):
"""Test that all tasks start on a big CPU"""

sched_assert = self.get_multi_assert(experiment)

self.assertTrue(
sched_assert.assertFirstCpu(
self.te.nrg_model.biggest_cpus,
rank=len(tasks)),
msg="Not all the new generated tasks started on a big CPU")
from test import experiment_test
from . import (EasTest, energy_aware_conf,
WORKLOAD_DURATION_S,
WORKLOAD_PERIOD_MS,
SWITCH_WINDOW_HALF,
SMALL_DCYCLE,
BIG_DCYCLE,
EXPECTED_RESIDENCY_PCT,
OFFLOAD_EXPECTED_BUSY_TIME_PCT,
OFFLOAD_MIGRATION_MIGRATOR_DELAY)

class ForkMigration(EasTest):
"""
Expand Down

0 comments on commit 37918fa

Please sign in to comment.