Skip to content

Commit 5ddb70c

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "libvirt: let CPUs be power managed"
2 parents 5c32d5e + 96f9518 commit 5ddb70c

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
@@ -9254,6 +9254,34 @@ def test_get_pcpu_available__cpu_dedicated_set_invalid(self,
92549254
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
92559255
self.assertRaises(exception.Invalid, drvr._get_pcpu_available)
92569256

9257+
@mock.patch('nova.virt.libvirt.host.Host.get_available_cpus',
9258+
return_value=set([0, 1, 2, 3]))
9259+
def test_get_pcpu_available_for_power_mgmt(self, get_available_cpus):
9260+
"""Test what happens when the '[compute] cpu_dedicated_set' config
9261+
option is set and power management is defined.
9262+
"""
9263+
self.flags(vcpu_pin_set=None)
9264+
self.flags(cpu_dedicated_set='2-3', cpu_shared_set=None,
9265+
group='compute')
9266+
self.flags(cpu_power_management=True, group='libvirt')
9267+
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9268+
pcpus = drvr._get_pcpu_available()
9269+
self.assertEqual(set([2, 3]), pcpus)
9270+
9271+
@mock.patch('nova.virt.libvirt.host.Host.get_available_cpus',
9272+
return_value=set([4, 5]))
9273+
def test_get_pcpu_available__cpu_dedicated_set_invalid_for_pm(self,
9274+
get_available_cpus):
9275+
"""Test what happens when the '[compute] cpu_dedicated_set' config
9276+
option is set but it's invalid with power management set.
9277+
"""
9278+
self.flags(vcpu_pin_set=None)
9279+
self.flags(cpu_dedicated_set='4-6', cpu_shared_set=None,
9280+
group='compute')
9281+
self.flags(cpu_power_management=True, group='libvirt')
9282+
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
9283+
self.assertRaises(exception.Invalid, drvr._get_pcpu_available)
9284+
92579285
@mock.patch('nova.virt.libvirt.host.Host.get_online_cpus',
92589286
return_value=set([0, 1, 2, 3]))
92599287
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
@@ -7750,15 +7750,18 @@ def _get_pcpu_available(self):
77507750
if not CONF.compute.cpu_dedicated_set:
77517751
return set()
77527752

7753-
online_cpus = self._host.get_online_cpus()
7753+
if CONF.libvirt.cpu_power_management:
7754+
available_cpus = self._host.get_available_cpus()
7755+
else:
7756+
available_cpus = self._host.get_online_cpus()
77547757
dedicated_cpus = hardware.get_cpu_dedicated_set()
77557758

7756-
if not dedicated_cpus.issubset(online_cpus):
7759+
if not dedicated_cpus.issubset(available_cpus):
77577760
msg = _("Invalid '[compute] cpu_dedicated_set' config: one or "
7758-
"more of the configured CPUs is not online. Online "
7759-
"cpuset(s): %(online)s, configured cpuset(s): %(req)s")
7761+
"more of the configured CPUs is not available. Available "
7762+
"cpuset(s): %(available)s, configured cpuset(s): %(req)s")
77607763
raise exception.Invalid(msg % {
7761-
'online': sorted(online_cpus),
7764+
'available': sorted(available_cpus),
77627765
'req': sorted(dedicated_cpus)})
77637766

77647767
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)