1
0
mirror of https://github.com/ARM-software/devlib.git synced 2025-01-31 02:00:45 +00:00

modules/sched: Add awareness of new debug directory root

Scheduler debug information is being unified under /sys/kernel/debug/sched
for Linux v5.13. Plug in awareness for the new path while still trying the
old one(s) for backwards compatibility.
This commit is contained in:
Valentin Schneider 2021-05-07 11:22:34 +01:00 committed by Marc Bonnici
parent 3af3463c3c
commit 6249c06b44

View File

@ -21,7 +21,7 @@ from past.builtins import basestring
from devlib.module import Module from devlib.module import Module
from devlib.utils.misc import memoized from devlib.utils.misc import memoized
from devlib.utils.types import boolean from devlib.utils.types import boolean
from devlib.exception import TargetStableError
class SchedProcFSNode(object): class SchedProcFSNode(object):
""" """
@ -303,19 +303,33 @@ class SchedDomain(SchedProcFSNode):
self.flags = flags self.flags = flags
def _select_path(target, paths, name):
for p in paths:
if target.file_exists(p):
return p
raise TargetStableError('No {} found. Tried: {}'.format(name, ', '.join(paths)))
class SchedProcFSData(SchedProcFSNode): class SchedProcFSData(SchedProcFSNode):
""" """
Root class for creating & storing SchedProcFSNode instances Root class for creating & storing SchedProcFSNode instances
""" """
_read_depth = 6 _read_depth = 6
sched_domain_root = '/proc/sys/kernel/sched_domain'
@classmethod
def get_data_root(cls, target):
# Location differs depending on kernel version
paths = ['/sys/kernel/debug/sched/domains/', '/proc/sys/kernel/sched_domain']
return _select_path(target, paths, "sched_domain debug directory")
@staticmethod @staticmethod
def available(target): def available(target):
path = SchedProcFSData.sched_domain_root try:
cpus = target.list_directory(path) if target.file_exists(path) else [] path = SchedProcFSData.get_data_root(target)
except TargetStableError:
return False
cpus = target.list_directory(path)
if not cpus: if not cpus:
return False return False
@ -329,7 +343,7 @@ class SchedProcFSData(SchedProcFSNode):
def __init__(self, target, path=None): def __init__(self, target, path=None):
if path is None: if path is None:
path = self.sched_domain_root path = SchedProcFSData.get_data_root(target)
procfs = target.read_tree_values(path, depth=self._read_depth) procfs = target.read_tree_values(path, depth=self._read_depth)
super(SchedProcFSData, self).__init__(procfs) super(SchedProcFSData, self).__init__(procfs)
@ -362,6 +376,15 @@ class SchedModule(Module):
return schedproc or debug or dmips return schedproc or debug or dmips
def __init__(self, target):
super().__init__(target)
@classmethod
def get_sched_features_path(cls, target):
# Location differs depending on kernel version
paths = ['/sys/kernel/debug/sched/features', '/sys/kernel/debug/sched_features']
return _select_path(target, paths, "sched_features file")
def get_kernel_attributes(self, matching=None, check_exit_code=True): def get_kernel_attributes(self, matching=None, check_exit_code=True):
""" """
Get the value of scheduler attributes. Get the value of scheduler attributes.
@ -418,12 +441,12 @@ class SchedModule(Module):
def target_has_debug(cls, target): def target_has_debug(cls, target):
if target.config.get('SCHED_DEBUG') != 'y': if target.config.get('SCHED_DEBUG') != 'y':
return False return False
return target.file_exists('/sys/kernel/debug/sched_features')
@property try:
@memoized cls.get_sched_features_path(target)
def has_debug(self): return True
return self.target_has_debug(self.target) except TargetStableError:
return False
def get_features(self): def get_features(self):
""" """
@ -431,9 +454,7 @@ class SchedModule(Module):
:returns: a dictionary of features and their "is enabled" status :returns: a dictionary of features and their "is enabled" status
""" """
if not self.has_debug: feats = self.target.read_value(self.get_sched_features_path(self.target))
raise RuntimeError("sched_features not available")
feats = self.target.read_value('/sys/kernel/debug/sched_features')
features = {} features = {}
for feat in feats.split(): for feat in feats.split():
value = True value = True
@ -453,13 +474,11 @@ class SchedModule(Module):
:raise ValueError: if the specified enable value is not bool :raise ValueError: if the specified enable value is not bool
:raise RuntimeError: if the specified feature cannot be set :raise RuntimeError: if the specified feature cannot be set
""" """
if not self.has_debug:
raise RuntimeError("sched_features not available")
feature = feature.upper() feature = feature.upper()
feat_value = feature feat_value = feature
if not boolean(enable): if not boolean(enable):
feat_value = 'NO_' + feat_value feat_value = 'NO_' + feat_value
self.target.write_value('/sys/kernel/debug/sched_features', self.target.write_value(self.get_sched_features_path(self.target),
feat_value, verify=False) feat_value, verify=False)
if not verify: if not verify:
return return
@ -471,10 +490,10 @@ class SchedModule(Module):
def get_cpu_sd_info(self, cpu): def get_cpu_sd_info(self, cpu):
""" """
:returns: An object view of /proc/sys/kernel/sched_domain/cpu<cpu>/* :returns: An object view of the sched_domain debug directory of 'cpu'
""" """
path = self.target.path.join( path = self.target.path.join(
SchedProcFSData.sched_domain_root, SchedProcFSData.get_data_root(self.target),
"cpu{}".format(cpu) "cpu{}".format(cpu)
) )
@ -482,7 +501,7 @@ class SchedModule(Module):
def get_sd_info(self): def get_sd_info(self):
""" """
:returns: An object view of /proc/sys/kernel/sched_domain/* :returns: An object view of the entire sched_domain debug directory
""" """
return SchedProcFSData(self.target) return SchedProcFSData(self.target)