From 6fdee073cd7bc98c7684304ce491fe5a6c006c07 Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Wed, 18 Sep 2024 13:15:52 +0200 Subject: [PATCH] Hack: libvirt: Support maxphysaddr. This is a hacky version of libvirt: Support maxphysaddr, which does it properly over flavor and images, but needs also a trait upgrade. Do not port it to later versions, it is implemented correctly by I98968f6ef1621c9fb4f682c119038e26d62ce381. With Libvirt v8.7.0+, the sub-element of the element specifies the number of vCPU physical address bits [1]. [1] https://libvirt.org/news.html#v8-7-0-2022-09-01 Change-Id: If89f71511c050a494657614b789adcdb80297725 --- nova/conf/workarounds.py | 7 +++++- nova/virt/libvirt/config.py | 43 +++++++++++++++++++++++++++++++++++++ nova/virt/libvirt/driver.py | 17 +++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/nova/conf/workarounds.py b/nova/conf/workarounds.py index 56220a172f9..042bcfaedf6 100644 --- a/nova/conf/workarounds.py +++ b/nova/conf/workarounds.py @@ -413,7 +413,12 @@ This will skip the CPU comparison call at the startup of Compute service and lets libvirt handle it. """), - + cfg.BoolOpt('libvirt_use_host_maxphysaddr', + default=False, + help=""" +This is a hack: Pass simply the maxphysaddr from the host to the VM. +This is to be replaced by the proper libvirt-maxphysaddr-support +"""), ] diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py index 6dbb753eec6..41badef1e96 100644 --- a/nova/virt/libvirt/config.py +++ b/nova/virt/libvirt/config.py @@ -755,6 +755,36 @@ def __hash__(self): return hash(self.name) +class LibvirtConfigCPUMaxPhysAddr(LibvirtConfigObject): + + def __init__(self, **kwargs): + super(LibvirtConfigCPUMaxPhysAddr, self).__init__( + root_name='maxphysaddr', **kwargs) + + self.mode = None + self.bits = None + + def parse_dom(self, xmldoc): + super(LibvirtConfigCPUMaxPhysAddr, self).parse_dom(xmldoc) + + self.mode = xmldoc.get("mode") + self.bits = int(xmldoc.get("bits")) + + def format_dom(self): + m = super(LibvirtConfigCPUMaxPhysAddr, self).format_dom() + + m.set("mode", self.mode) + + if self.bits: + m.set("bits", str(self.bits)) + + return m + + +class LibvirtConfigGuestCPUMaxPhysAddr(LibvirtConfigCPUMaxPhysAddr): + pass + + class LibvirtConfigCPU(LibvirtConfigObject): def __init__(self, **kwargs): @@ -769,6 +799,8 @@ def __init__(self, **kwargs): self.cores = None self.threads = None + self.maxphysaddr = None + self.features = set() def parse_dom(self, xmldoc): @@ -785,6 +817,9 @@ def parse_dom(self, xmldoc): self.sockets = int(c.get("sockets")) self.cores = int(c.get("cores")) self.threads = int(c.get("threads")) + elif c.tag == "maxphysaddr": + self.maxphysaddr = LibvirtConfigCPUMaxPhysAddr() + self.maxphysaddr.parse_dom(c) elif c.tag == "feature": f = LibvirtConfigCPUFeature() f.parse_dom(c) @@ -810,6 +845,9 @@ def format_dom(self): top.set("threads", str(self.threads)) cpu.append(top) + if self.maxphysaddr is not None: + cpu.append(self.maxphysaddr.format_dom()) + # sorting the features to allow more predictable tests for f in sorted(self.features, key=lambda x: x.name): cpu.append(f.format_dom()) @@ -904,6 +942,7 @@ def __init__(self, **kwargs): self.mode = None self.match = "exact" self.numa = None + self.maxphysaddr = None def parse_dom(self, xmldoc): super(LibvirtConfigGuestCPU, self).parse_dom(xmldoc) @@ -914,6 +953,10 @@ def parse_dom(self, xmldoc): numa = LibvirtConfigGuestCPUNUMA() numa.parse_dom(child) self.numa = numa + elif child.tag == "maxphysaddr": + m = LibvirtConfigGuestCPUMaxPhysAddr() + m.parse_dom(child) + self.maxphysaddr = m def format_dom(self): cpu = super(LibvirtConfigGuestCPU, self).format_dom() diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 0c58755e103..85a4b463ed2 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -5263,6 +5263,17 @@ def _get_guest_cpu_config(self, flavor, image_meta, cpu.threads = topology.threads cpu.numa = guest_cpu_numa_config + if not CONF.workarounds.libvirt_use_host_maxphysaddr: + return cpu + + caps = self._host.get_capabilities() + if not caps.host.cpu.maxphysaddr: + return cpu + + cpu.maxphysaddr = vconfig.LibvirtConfigGuestCPUMaxPhysAddr() + cpu.maxphysaddr.mode = caps.host.cpu.maxphysaddr.mode + cpu.maxphysaddr.bits = caps.host.cpu.maxphysaddr.bits + return cpu def _get_guest_disk_config( @@ -7828,6 +7839,12 @@ def _get_cpu_info(self): topology['threads'] = caps.host.cpu.threads cpu_info['topology'] = topology + if caps.host.cpu.maxphysaddr: + maxphysaddr = dict() + maxphysaddr["mode"] = caps.host.cpu.maxphysaddr.mode + maxphysaddr["bits"] = caps.host.cpu.maxphysaddr.bits + cpu_info["maxphysaddr"] = maxphysaddr + features = set() for f in caps.host.cpu.features: features.add(f.name)