diff options
Diffstat (limited to 'nova/virt/libvirt/cpu/api.py')
-rw-r--r-- | nova/virt/libvirt/cpu/api.py | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/nova/virt/libvirt/cpu/api.py b/nova/virt/libvirt/cpu/api.py index e0b0a277d1..1c17458d6b 100644 --- a/nova/virt/libvirt/cpu/api.py +++ b/nova/virt/libvirt/cpu/api.py @@ -15,6 +15,10 @@ from dataclasses import dataclass from oslo_log import log as logging import nova.conf +from nova import exception +from nova.i18n import _ +from nova import objects +from nova.virt import hardware from nova.virt.libvirt.cpu import core LOG = logging.getLogger(__name__) @@ -51,6 +55,9 @@ class Core: def __eq__(self, other): return self.ident == other.ident + def __str__(self): + return str(self.ident) + @property def governor(self) -> str: return core.get_governor(self.ident) @@ -60,3 +67,91 @@ class Core: def set_low_governor(self) -> None: core.set_governor(self.ident, CONF.libvirt.cpu_power_governor_low) + + +def power_up(instance: objects.Instance) -> None: + if not CONF.libvirt.cpu_power_management: + return + if instance.numa_topology is None: + return + + cpu_dedicated_set = hardware.get_cpu_dedicated_set() or set() + pcpus = instance.numa_topology.cpu_pinning + powered_up = set() + for pcpu in pcpus: + if pcpu in cpu_dedicated_set: + pcpu = Core(pcpu) + if CONF.libvirt.cpu_power_management_strategy == 'cpu_state': + pcpu.online = True + else: + pcpu.set_high_governor() + powered_up.add(str(pcpu)) + LOG.debug("Cores powered up : %s", powered_up) + + +def power_down(instance: objects.Instance) -> None: + if not CONF.libvirt.cpu_power_management: + return + if instance.numa_topology is None: + return + + cpu_dedicated_set = hardware.get_cpu_dedicated_set() or set() + pcpus = instance.numa_topology.cpu_pinning + powered_down = set() + for pcpu in pcpus: + if pcpu in cpu_dedicated_set: + pcpu = Core(pcpu) + if CONF.libvirt.cpu_power_management_strategy == 'cpu_state': + pcpu.online = False + else: + pcpu.set_low_governor() + powered_down.add(str(pcpu)) + LOG.debug("Cores powered down : %s", powered_down) + + +def power_down_all_dedicated_cpus() -> None: + if not CONF.libvirt.cpu_power_management: + return + if (CONF.libvirt.cpu_power_management and + not CONF.compute.cpu_dedicated_set + ): + msg = _("'[compute]/cpu_dedicated_set' is mandatory to be set if " + "'[libvirt]/cpu_power_management' is set." + "Please provide the CPUs that can be pinned or don't use the " + "power management if you only use shared CPUs.") + raise exception.InvalidConfiguration(msg) + + cpu_dedicated_set = hardware.get_cpu_dedicated_set() or set() + for pcpu in cpu_dedicated_set: + pcpu = Core(pcpu) + if CONF.libvirt.cpu_power_management_strategy == 'cpu_state': + pcpu.online = False + else: + pcpu.set_low_governor() + LOG.debug("Cores powered down : %s", cpu_dedicated_set) + + +def validate_all_dedicated_cpus() -> None: + if not CONF.libvirt.cpu_power_management: + return + cpu_dedicated_set = hardware.get_cpu_dedicated_set() or set() + governors = set() + cpu_states = set() + for pcpu in cpu_dedicated_set: + pcpu = Core(pcpu) + # we need to collect the governors strategy and the CPU states + governors.add(pcpu.governor) + cpu_states.add(pcpu.online) + if CONF.libvirt.cpu_power_management_strategy == 'cpu_state': + # all the cores need to have the same governor strategy + if len(governors) > 1: + msg = _("All the cores need to have the same governor strategy" + "before modifying the CPU states. You can reboot the " + "compute node if you prefer.") + raise exception.InvalidConfiguration(msg) + elif CONF.libvirt.cpu_power_management_strategy == 'governor': + # all the cores need to be online + if False in cpu_states: + msg = _("All the cores need to be online before modifying the " + "governor strategy.") + raise exception.InvalidConfiguration(msg) |