cpu: make governors to be optional
Change-Id: Ifb7d001cfdb95b1b0aa29f45c0ef71c0673e1760 Closes-Bug: #2023018
This commit is contained in:
parent
3fab43786b
commit
2c4421568e
@ -772,6 +772,11 @@ while there could be other tools outside Nova to manage the governor, like
|
|||||||
tuned. That being said, we also provide a way to automatically change the
|
tuned. That being said, we also provide a way to automatically change the
|
||||||
governors on the fly, as explained below.
|
governors on the fly, as explained below.
|
||||||
|
|
||||||
|
.. important::
|
||||||
|
Some OS platforms don't support `cpufreq` resources in sysfs, so the
|
||||||
|
``governor`` strategy could be not available. Please verify if your OS
|
||||||
|
supports scaling govenors before modifying the configuration option.
|
||||||
|
|
||||||
If the strategy is set to ``governor``, a couple of config options are provided
|
If the strategy is set to ``governor``, a couple of config options are provided
|
||||||
to define which exact CPU govenor to use for each of the up and down states :
|
to define which exact CPU govenor to use for each of the up and down states :
|
||||||
|
|
||||||
|
19
nova/tests/fixtures/filesystem.py
vendored
19
nova/tests/fixtures/filesystem.py
vendored
@ -39,10 +39,14 @@ class TempFileSystemFixture(fixtures.Fixture):
|
|||||||
|
|
||||||
|
|
||||||
class SysFileSystemFixture(TempFileSystemFixture):
|
class SysFileSystemFixture(TempFileSystemFixture):
|
||||||
"""Creates a fake /sys filesystem"""
|
def __init__(self, cpus_supported=None, cpufreq_enabled=True):
|
||||||
|
"""Instantiates a fake sysfs.
|
||||||
|
|
||||||
def __init__(self, cpus_supported=None):
|
:param cpus_supported: number of devices/system/cpu (default: 10)
|
||||||
|
:param cpufreq_enabled: cpufreq subdir created (default: True)
|
||||||
|
"""
|
||||||
self.cpus_supported = cpus_supported or 10
|
self.cpus_supported = cpus_supported or 10
|
||||||
|
self.cpufreq_enabled = cpufreq_enabled
|
||||||
|
|
||||||
def _setUp(self):
|
def _setUp(self):
|
||||||
super()._setUp()
|
super()._setUp()
|
||||||
@ -73,9 +77,12 @@ class SysFileSystemFixture(TempFileSystemFixture):
|
|||||||
|
|
||||||
for cpu_nr in range(self.cpus_supported):
|
for cpu_nr in range(self.cpus_supported):
|
||||||
cpu_dir = os.path.join(self.cpu_path_mock % {'core': cpu_nr})
|
cpu_dir = os.path.join(self.cpu_path_mock % {'core': cpu_nr})
|
||||||
os.makedirs(os.path.join(cpu_dir, 'cpufreq'))
|
os.makedirs(cpu_dir)
|
||||||
filesystem.write_sys(
|
filesystem.write_sys(os.path.join(cpu_dir, 'online'), data='1')
|
||||||
os.path.join(cpu_dir, 'cpufreq/scaling_governor'),
|
if self.cpufreq_enabled:
|
||||||
data='powersave')
|
os.makedirs(os.path.join(cpu_dir, 'cpufreq'))
|
||||||
|
filesystem.write_sys(
|
||||||
|
os.path.join(cpu_dir, 'cpufreq/scaling_governor'),
|
||||||
|
data='powersave')
|
||||||
filesystem.write_sys(core.AVAILABLE_PATH,
|
filesystem.write_sys(core.AVAILABLE_PATH,
|
||||||
f'0-{self.cpus_supported - 1}')
|
f'0-{self.cpus_supported - 1}')
|
||||||
|
@ -221,6 +221,39 @@ class PowerManagementTestsGovernor(PowerManagementTestsBase):
|
|||||||
self.restart_compute_service, hostname='compute1')
|
self.restart_compute_service, hostname='compute1')
|
||||||
|
|
||||||
|
|
||||||
|
class PowerManagementTestsGovernorNotSupported(PowerManagementTestsBase):
|
||||||
|
"""Test suite for OS without governor support usage (same 10-core host)"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(PowerManagementTestsGovernorNotSupported, self).setUp()
|
||||||
|
|
||||||
|
self.useFixture(nova_fixtures.SysFileSystemFixture(
|
||||||
|
cpufreq_enabled=False))
|
||||||
|
|
||||||
|
# Definining the CPUs to be pinned.
|
||||||
|
self.flags(cpu_dedicated_set='1-9', cpu_shared_set=None,
|
||||||
|
group='compute')
|
||||||
|
self.flags(vcpu_pin_set=None)
|
||||||
|
self.flags(cpu_power_management=True, group='libvirt')
|
||||||
|
self.flags(cpu_power_management_strategy='cpu_state', group='libvirt')
|
||||||
|
|
||||||
|
self.flags(allow_resize_to_same_host=True)
|
||||||
|
self.host_info = fakelibvirt.HostInfo(cpu_nodes=1, cpu_sockets=1,
|
||||||
|
cpu_cores=5, cpu_threads=2)
|
||||||
|
|
||||||
|
def test_enabling_governor_strategy_fails(self):
|
||||||
|
self.flags(cpu_power_management_strategy='governor', group='libvirt')
|
||||||
|
self.assertRaises(exception.FileNotFound, self.start_compute,
|
||||||
|
host_info=self.host_info, hostname='compute1')
|
||||||
|
|
||||||
|
def test_enabling_cpu_state_strategy_works(self):
|
||||||
|
self.flags(cpu_power_management_strategy='cpu_state', group='libvirt')
|
||||||
|
self.compute1 = self.start_compute(host_info=self.host_info,
|
||||||
|
hostname='compute1')
|
||||||
|
cpu_dedicated_set = hardware.get_cpu_dedicated_set()
|
||||||
|
self._assert_cpu_set_state(cpu_dedicated_set, expected='offline')
|
||||||
|
|
||||||
|
|
||||||
class PowerManagementMixedInstances(PowerManagementTestsBase):
|
class PowerManagementMixedInstances(PowerManagementTestsBase):
|
||||||
"""Test suite for a single host with 6 dedicated cores, 3 shared and one
|
"""Test suite for a single host with 6 dedicated cores, 3 shared and one
|
||||||
OS-restricted.
|
OS-restricted.
|
||||||
|
@ -57,6 +57,12 @@ class TestAPI(test.NoDBTestCase):
|
|||||||
self.assertEqual('fake_governor', self.core_1.governor)
|
self.assertEqual('fake_governor', self.core_1.governor)
|
||||||
mock_get_governor.assert_called_once_with(self.core_1.ident)
|
mock_get_governor.assert_called_once_with(self.core_1.ident)
|
||||||
|
|
||||||
|
@mock.patch.object(core, 'get_governor')
|
||||||
|
def test_governor_optional(self, mock_get_governor):
|
||||||
|
mock_get_governor.side_effect = exception.FileNotFound(file_path='foo')
|
||||||
|
self.assertIsNone(self.core_1.governor)
|
||||||
|
mock_get_governor.assert_called_once_with(self.core_1.ident)
|
||||||
|
|
||||||
@mock.patch.object(core, 'set_governor')
|
@mock.patch.object(core, 'set_governor')
|
||||||
def test_set_governor_low(self, mock_set_governor):
|
def test_set_governor_low(self, mock_set_governor):
|
||||||
self.flags(cpu_power_governor_low='fake_low_gov', group='libvirt')
|
self.flags(cpu_power_governor_low='fake_low_gov', group='libvirt')
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
import typing as ty
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
@ -59,8 +60,13 @@ class Core:
|
|||||||
return str(self.ident)
|
return str(self.ident)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def governor(self) -> str:
|
def governor(self) -> ty.Optional[str]:
|
||||||
return core.get_governor(self.ident)
|
try:
|
||||||
|
return core.get_governor(self.ident)
|
||||||
|
# NOTE(sbauza): cpufreq/scaling_governor is not enabled for some OS
|
||||||
|
# platforms.
|
||||||
|
except exception.FileNotFound:
|
||||||
|
return None
|
||||||
|
|
||||||
def set_high_governor(self) -> None:
|
def set_high_governor(self) -> None:
|
||||||
core.set_governor(self.ident, CONF.libvirt.cpu_power_governor_high)
|
core.set_governor(self.ident, CONF.libvirt.cpu_power_governor_high)
|
||||||
|
9
releasenotes/notes/bug-2023018-0f93ca1f679ce259.yaml
Normal file
9
releasenotes/notes/bug-2023018-0f93ca1f679ce259.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Some OS platforms don't provide by default cpufreq resources in sysfs, so
|
||||||
|
they don't have CPU scaling governors. That's why we should let the governor
|
||||||
|
strategy to be optional for `CPU power management`_.
|
||||||
|
|
||||||
|
.. _CPU power management: https://docs.openstack.org/nova/latest/admin/cpu-topologies.html#configuring-cpu-power-management-for-dedicated-cores
|
||||||
|
|
Loading…
Reference in New Issue
Block a user