From 625dbac092e404f6ea20fc8988e7c3e319cc9533 Mon Sep 17 00:00:00 2001 From: Marc Bonnici <marc.bonnici@arm.com> Date: Thu, 29 Jun 2023 17:07:28 -0500 Subject: [PATCH] rt_config: Don't try to configure an offline cpu As per [1], any attempt to configure a core's frequency will fail if the first core of the associated frequency domain is offline. Remove the assumption that the first cpu should be used when committing the change to the device to resolve this. [1] https://github.com/ARM-software/workload-automation/issues/1217 --- wa/framework/target/runtime_config.py | 18 +++++++++++------- wa/utils/misc.py | 10 ++++++---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/wa/framework/target/runtime_config.py b/wa/framework/target/runtime_config.py index bbbccee3c..d140c46af 100644 --- a/wa/framework/target/runtime_config.py +++ b/wa/framework/target/runtime_config.py @@ -306,13 +306,17 @@ def set_governor_tunables(obj, value, core): @staticmethod def set_param(obj, value, core, parameter): - '''Method to store passed parameter if it is not already specified for that cpu''' - cpus = resolve_unique_domain_cpus(core, obj.target) - for cpu in cpus: - if parameter in obj.config[cpu]: - msg = 'Cannot set "{}" for core "{}"; Parameter for CPU{} has already been set' - raise ConfigError(msg.format(parameter, core, cpu)) - obj.config[cpu][parameter] = value + '''Method to store passed parameter if it is not already specified for that cpu frequency domain''' + resolved_cpus = resolve_unique_domain_cpus(core, obj.target) + for resovled in resolved_cpus: + # Check no other cpus in the same domain have already been set. + cpus = obj.target.cpufreq.get_related_cpus(resovled) + for cpu in cpus: + if cpu in obj.config and parameter in obj.config[cpu]: + msg = 'Cannot set "{}" for core "{}"; Parameter for CPU{} has already been set' + raise ConfigError(msg.format(parameter, core, cpu)) + # Once validated, store the ID of the first cpu resolved. + obj.config[resolved_cpus[0]][parameter] = value def __init__(self, target): self.config = defaultdict(dict) diff --git a/wa/utils/misc.py b/wa/utils/misc.py index beea6b104..ff63e22f1 100644 --- a/wa/utils/misc.py +++ b/wa/utils/misc.py @@ -623,17 +623,19 @@ def resolve_cpus(name, target): def resolve_unique_domain_cpus(name, target): """ Same as `resolve_cpus` above but only returns only the first cpu - in each of the different frequency domains. Requires cpufreq. + in each of the different frequency domains that are currently online. + Requires cpufreq. """ - cpus = resolve_cpus(name, target) + cpus = set(resolve_cpus(name, target)) if not target.has('cpufreq'): msg = 'Device does not appear to support cpufreq; ' \ 'Cannot obtain cpu domain information' raise TargetError(msg) + online_cpus = set(target.list_online_cpus()) unique_cpus = [] domain_cpus = [] - for cpu in cpus: + for cpu in cpus.intersection(online_cpus): if cpu not in domain_cpus: try: domain_cpus = target.cpufreq.get_related_cpus(cpu) @@ -641,7 +643,7 @@ def resolve_unique_domain_cpus(name, target): # Skip core if not online continue if domain_cpus[0] not in unique_cpus: - unique_cpus.append(domain_cpus[0]) + unique_cpus.append(cpu) return unique_cpus