Skip to content

Commit 96f9518

Browse files
sbauzaSeanMooney
andcommitted
libvirt: let CPUs be power managed
Before going further, we need to somehow return the list of CPUs even offline if they are power managed by Nova. Co-Authored-By: Sean Mooney <[email protected]> Partially-Implements: blueprint libvirt-cpu-state-mgmt Change-Id: I5dca10acde0eff554ed139587aefaf2f5fad2ca5
1 parent ddf96bc commit 96f9518

File tree

5 files changed

+53
-5
lines changed

5 files changed

+53
-5
lines changed

nova/conf/libvirt.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,9 @@
14791479
]
14801480

14811481
libvirt_cpu_mgmt_opts = [
1482+
cfg.BoolOpt('cpu_power_management',
1483+
default=False,
1484+
help='Use libvirt to manage CPU cores performance.'),
14821485
cfg.StrOpt('cpu_power_governor_low',
14831486
default='powersave',
14841487
help='Governor to use in order '

nova/tests/unit/virt/libvirt/test_driver.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9190,6 +9190,34 @@ def test_get_pcpu_available__cpu_dedicated_set_invalid(self,
91909190
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
91919191
self.assertRaises(exception.Invalid, drvr._get_pcpu_available)
91929192

9193+
@mock.patch('nova.virt.libvirt.host.Host.get_available_cpus',
9194+
return_value=set([0, 1, 2, 3]))
9195+
def test_get_pcpu_available_for_power_mgmt(self, get_available_cpus):
9196+
"""Test what happens when the '[compute] cpu_dedicated_set' config
9197+
option is set and power management is defined.
9198+
"""
9199+
self.flags(vcpu_pin_set=None)
9200+
self.flags(cpu_dedicated_set='2-3', cpu_shared_set=None,
9201+
group='compute')
9202+
self.flags(cpu_power_management=True, group='libvirt')
9203+
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9204+
pcpus = drvr._get_pcpu_available()
9205+
self.assertEqual(set([2, 3]), pcpus)
9206+
9207+
@mock.patch('nova.virt.libvirt.host.Host.get_available_cpus',
9208+
return_value=set([4, 5]))
9209+
def test_get_pcpu_available__cpu_dedicated_set_invalid_for_pm(self,
9210+
get_available_cpus):
9211+
"""Test what happens when the '[compute] cpu_dedicated_set' config
9212+
option is set but it's invalid with power management set.
9213+
"""
9214+
self.flags(vcpu_pin_set=None)
9215+
self.flags(cpu_dedicated_set='4-6', cpu_shared_set=None,
9216+
group='compute')
9217+
self.flags(cpu_power_management=True, group='libvirt')
9218+
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9219+
self.assertRaises(exception.Invalid, drvr._get_pcpu_available)
9220+
91939221
@mock.patch('nova.virt.libvirt.host.Host.get_online_cpus',
91949222
return_value=set([0, 1, 2, 3]))
91959223
def test_get_vcpu_available(self, get_online_cpus):

nova/tests/unit/virt/libvirt/test_host.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,12 @@ def test_get_cpu_stats(self):
10521052
'iowait': 6121490000000},
10531053
stats)
10541054

1055+
@mock.patch.object(fakelibvirt.virConnect, "getCPUMap")
1056+
def test_get_available_cpus(self, mock_map):
1057+
mock_map.return_value = (4, [True, True, False, False], None)
1058+
result = self.host.get_available_cpus()
1059+
self.assertEqual(result, {0, 1, 2, 3})
1060+
10551061
@mock.patch.object(fakelibvirt.virConnect, "defineXML")
10561062
def test_write_instance_config(self, mock_defineXML):
10571063
fake_dom_xml = """

nova/virt/libvirt/driver.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7745,15 +7745,18 @@ def _get_pcpu_available(self):
77457745
if not CONF.compute.cpu_dedicated_set:
77467746
return set()
77477747

7748-
online_cpus = self._host.get_online_cpus()
7748+
if CONF.libvirt.cpu_power_management:
7749+
available_cpus = self._host.get_available_cpus()
7750+
else:
7751+
available_cpus = self._host.get_online_cpus()
77497752
dedicated_cpus = hardware.get_cpu_dedicated_set()
77507753

7751-
if not dedicated_cpus.issubset(online_cpus):
7754+
if not dedicated_cpus.issubset(available_cpus):
77527755
msg = _("Invalid '[compute] cpu_dedicated_set' config: one or "
7753-
"more of the configured CPUs is not online. Online "
7754-
"cpuset(s): %(online)s, configured cpuset(s): %(req)s")
7756+
"more of the configured CPUs is not available. Available "
7757+
"cpuset(s): %(available)s, configured cpuset(s): %(req)s")
77557758
raise exception.Invalid(msg % {
7756-
'online': sorted(online_cpus),
7759+
'available': sorted(available_cpus),
77577760
'req': sorted(dedicated_cpus)})
77587761

77597762
return dedicated_cpus

nova/virt/libvirt/host.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,14 @@ def list_instance_domains(self, only_running=True):
740740

741741
return doms
742742

743+
def get_available_cpus(self):
744+
"""Get the set of CPUs that exist on the host.
745+
746+
:returns: set of CPUs, raises libvirtError on error
747+
"""
748+
cpus, cpu_map, online = self.get_connection().getCPUMap()
749+
return {cpu for cpu in range(cpus)}
750+
743751
def get_online_cpus(self):
744752
"""Get the set of CPUs that are online on the host
745753

0 commit comments

Comments
 (0)