From 10d00940e509d4b0f5dfa170b94acc719c026dd0 Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Tue, 26 Jul 2022 16:58:31 +0100 Subject: [PATCH] lisa.energy_model: Use LISA kernel module fallback FEATURE If the energy model is not exposed on the target in sysfs, load the lisa kernel module with the right feature enabled and retry. This feature will expose the EM as a folder hierarchy using in-kernel APIs --- lisa/energy_model.py | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/lisa/energy_model.py b/lisa/energy_model.py index 810d32ac4..b3bd2405c 100644 --- a/lisa/energy_model.py +++ b/lisa/energy_model.py @@ -20,6 +20,7 @@ from collections import namedtuple, OrderedDict from itertools import product import operator import re +from contextlib import nullcontext import pandas @@ -29,7 +30,7 @@ from devlib.exception import TargetStableError from lisa.utils import Loggable, Serializable, memoized, groupby, get_subclasses, deprecate, grouper from lisa.datautils import df_deduplicate from lisa.analysis.frequency import FrequencyAnalysis - +from lisa._kmod import LISAFtraceDynamicKmod def _read_multiple_oneline_files(target, glob_patterns): @@ -281,6 +282,11 @@ class PowerDomain(_CpuTree): self.idle_states = idle_states +class EnergyModelNotFoundError(TargetStableError): + def __init__(self): + super().__init__('Unable to probe for energy model on target.') + + class EnergyModel(Serializable, Loggable): """Represents hierarchical CPU topology with power and capacity data @@ -770,7 +776,7 @@ class EnergyModel(Serializable, Loggable): """ try: cls._find_subcls(target) - except TargetStableError: + except EnergyModelNotFoundError: return False else: return True @@ -786,7 +792,7 @@ class EnergyModel(Serializable, Loggable): if subcls.probe_target(target): return subcls - raise TargetStableError('Unable to probe for energy model on target.') + raise EnergyModelNotFoundError() @classmethod def from_target(cls, target): @@ -803,9 +809,24 @@ class EnergyModel(Serializable, Loggable): """ logger = cls.get_logger('from_target') - subcls = cls._find_subcls(target) - logger.info(f'Attempting to load EM using {subcls.__name__}') - em = subcls.from_target(target) + try: + subcls = cls._find_subcls(target) + except EnergyModelNotFoundError: + # If we could not find a suitable EM description in sysfs, load the + # LISA kernel module with the feature that will expose the EM as a + # directory tree and retry. + @contextmanager + def _cm(): + kmod = target.get_kmod(LISAFtraceDynamicKmod) + with kmod.run(kmod_params={'features': ['em_sysfs']}): + yield cls._find_subcls(target) + cm = _cm() + else: + cm = nullcontext(subcls) + + with cm as subcls: + logger.info(f'Attempting to load EM using {subcls.__name__}') + em = subcls.from_target(target) cpu_missing_idle_states = sorted( node.cpu -- GitLab