libvirt: add classes for NUMA memory binding configuration

To allow specification of strict memory binding for NUMA
nodes, add support for libvirt's <numatune> XML element.

Related-bug: #1385308
Change-Id: I08f01a50b92ca648b803f94ef028bc2f10e6f6a8
This commit is contained in:
Daniel P. Berrange 2014-10-24 16:12:58 +01:00
parent e03525bf1a
commit 943f02f1a6
2 changed files with 143 additions and 0 deletions

View File

@ -1432,6 +1432,33 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
obj.memtune.swap_hard_limit = 1638
obj.memtune.min_guarantee = 2970
obj.numatune = config.LibvirtConfigGuestNUMATune()
numamemory = config.LibvirtConfigGuestNUMATuneMemory()
numamemory.mode = "preferred"
numamemory.nodeset = [0, 1, 2, 3, 8]
obj.numatune.memory = numamemory
numamemnode0 = config.LibvirtConfigGuestNUMATuneMemNode()
numamemnode0.cellid = 0
numamemnode0.mode = "preferred"
numamemnode0.nodeset = [0, 1]
numamemnode1 = config.LibvirtConfigGuestNUMATuneMemNode()
numamemnode1.cellid = 1
numamemnode1.mode = "preferred"
numamemnode1.nodeset = [2, 3]
numamemnode2 = config.LibvirtConfigGuestNUMATuneMemNode()
numamemnode2.cellid = 2
numamemnode2.mode = "preferred"
numamemnode2.nodeset = [8]
obj.numatune.memnodes.extend([numamemnode0,
numamemnode1,
numamemnode2])
obj.name = "demo"
obj.uuid = "b38a3f43-4be2-4046-897f-b67c2f5e0147"
obj.os_type = "linux"
@ -1468,6 +1495,12 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
<swap_hard_limit units="K">1638</swap_hard_limit>
<min_guarantee units="K">2970</min_guarantee>
</memtune>
<numatune>
<memory mode="preferred" nodeset="0-3,8"/>
<memnode cellid="0" mode="preferred" nodeset="0-1"/>
<memnode cellid="1" mode="preferred" nodeset="2-3"/>
<memnode cellid="2" mode="preferred" nodeset="8"/>
</numatune>
<vcpu cpuset="0-1,3-5">2</vcpu>
<sysinfo type='smbios'>
<bios>
@ -2138,6 +2171,55 @@ class LibvirtConfigGuestMemoryTuneTest(LibvirtConfigBaseTest):
</memtune>""")
class LibvirtConfigGuestNUMATuneTest(LibvirtConfigBaseTest):
def test_config_numa_tune_none(self):
obj = config.LibvirtConfigGuestNUMATune()
xml = obj.to_xml()
self.assertXmlEqual("<numatune/>", xml)
def test_config_numa_tune_memory(self):
obj = config.LibvirtConfigGuestNUMATune()
numamemory = config.LibvirtConfigGuestNUMATuneMemory()
numamemory.nodeset = [0, 1, 2, 3, 8]
obj.memory = numamemory
xml = obj.to_xml()
self.assertXmlEqual("""
<numatune>
<memory mode="strict" nodeset="0-3,8"/>
</numatune>""", xml)
def test_config_numa_tune_memnodes(self):
obj = config.LibvirtConfigGuestNUMATune()
numamemnode0 = config.LibvirtConfigGuestNUMATuneMemNode()
numamemnode0.cellid = 0
numamemnode0.nodeset = [0, 1]
numamemnode1 = config.LibvirtConfigGuestNUMATuneMemNode()
numamemnode1.cellid = 1
numamemnode1.nodeset = [2, 3]
numamemnode2 = config.LibvirtConfigGuestNUMATuneMemNode()
numamemnode2.cellid = 2
numamemnode2.nodeset = [8]
obj.memnodes.extend([numamemnode0,
numamemnode1,
numamemnode2])
xml = obj.to_xml()
self.assertXmlEqual("""
<numatune>
<memnode cellid="0" mode="strict" nodeset="0-1"/>
<memnode cellid="1" mode="strict" nodeset="2-3"/>
<memnode cellid="2" mode="strict" nodeset="8"/>
</numatune>""", xml)
class LibvirtConfigGuestMetadataNovaTest(LibvirtConfigBaseTest):
def test_config_metadata(self):

View File

@ -1597,6 +1597,64 @@ class LibvirtConfigGuestMemoryTune(LibvirtConfigObject):
return root
class LibvirtConfigGuestNUMATuneMemory(LibvirtConfigObject):
def __init__(self, **kwargs):
super(LibvirtConfigGuestNUMATuneMemory, self).__init__(
root_name="memory", **kwargs)
self.mode = "strict"
self.nodeset = []
def format_dom(self):
root = super(LibvirtConfigGuestNUMATuneMemory, self).format_dom()
root.set("mode", self.mode)
root.set("nodeset", hardware.format_cpu_spec(self.nodeset))
return root
class LibvirtConfigGuestNUMATuneMemNode(LibvirtConfigObject):
def __init__(self, **kwargs):
super(LibvirtConfigGuestNUMATuneMemNode, self).__init__(
root_name="memnode", **kwargs)
self.cellid = 0
self.mode = "strict"
self.nodeset = []
def format_dom(self):
root = super(LibvirtConfigGuestNUMATuneMemNode, self).format_dom()
root.set("cellid", str(self.cellid))
root.set("mode", self.mode)
root.set("nodeset", hardware.format_cpu_spec(self.nodeset))
return root
class LibvirtConfigGuestNUMATune(LibvirtConfigObject):
def __init__(self, **kwargs):
super(LibvirtConfigGuestNUMATune, self).__init__(
root_name="numatune", **kwargs)
self.memory = None
self.memnodes = []
def format_dom(self):
root = super(LibvirtConfigGuestNUMATune, self).format_dom()
if self.memory is not None:
root.append(self.memory.format_dom())
for node in self.memnodes:
root.append(node.format_dom())
return root
class LibvirtConfigGuest(LibvirtConfigObject):
def __init__(self, **kwargs):
@ -1609,6 +1667,7 @@ class LibvirtConfigGuest(LibvirtConfigObject):
self.memory = 500 * units.Mi
self.membacking = None
self.memtune = None
self.numatune = None
self.vcpus = 1
self.cpuset = None
self.cpu = None
@ -1640,6 +1699,8 @@ class LibvirtConfigGuest(LibvirtConfigObject):
root.append(self.membacking.format_dom())
if self.memtune is not None:
root.append(self.memtune.format_dom())
if self.numatune is not None:
root.append(self.numatune.format_dom())
if self.cpuset is not None:
vcpu = self._text_node("vcpu", self.vcpus)
vcpu.set("cpuset", hardware.format_cpu_spec(self.cpuset))