From 8e2d2a718e0d5c3011c1342df20f063d2a7b91b3 Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Tue, 16 May 2023 16:01:27 +0200 Subject: [PATCH] libvirt-9.3.0-2.el9 - qemu_domin: Account for NVMe disks when calculating memlock limit on hotplug (rhbz#2014030) Resolves: rhbz#2014030 --- ...calculating-memlock-limit-on-hotplug.patch | 134 ++++++++++++++++++ libvirt.spec | 7 +- 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 libvirt-qemu_domin-Account-for-NVMe-disks-when-calculating-memlock-limit-on-hotplug.patch diff --git a/libvirt-qemu_domin-Account-for-NVMe-disks-when-calculating-memlock-limit-on-hotplug.patch b/libvirt-qemu_domin-Account-for-NVMe-disks-when-calculating-memlock-limit-on-hotplug.patch new file mode 100644 index 0000000..ce3fd32 --- /dev/null +++ b/libvirt-qemu_domin-Account-for-NVMe-disks-when-calculating-memlock-limit-on-hotplug.patch @@ -0,0 +1,134 @@ +From d6fb700653000794c898517db6953b90b580af09 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Tue, 9 May 2023 13:19:12 +0300 +Subject: [PATCH] qemu_domin: Account for NVMe disks when calculating memlock + limit on hotplug + +During hotplug of a NVMe disk we need to adjust the memlock +limit. The computation of the limit is handled by +qemuDomainGetMemLockLimitBytes() which looks at given domain +definition and accounts for various device types (as different +types require different amounts). But during disk hotplug the +disk is not added to domain definition until the very last +moment. Therefore, qemuDomainGetMemLockLimitBytes() has this +@forceVFIO argument which tells it to assume VFIO even if there +are no signs of VFIO in domain definition. And this kind of +works, until the amount needed for NVMe disks changed (in +v9.3.0-rc1~52). What's missing in the commit is making @forceVFIO +behave the same as if there was an NVMe disk present in the +domain definition. + +But, we can do even better - just mimic whatever we're doing for +hostdevs. IOW - introduce qemuDomainAdjustMaxMemLockNVMe() that +behaves the same as qemuDomainAdjustMaxMemLockHostdev(). + +There are subtle differences though: + +1) qemuDomainAdjustMaxMemLockHostdev() can afford placing hostdev + right at the end of vm->def->hostdevs, because the array was + already reallocated (at the beginning of + qemuDomainAttachHostPCIDevice()). But + qemuDomainAdjustMaxMemLockNVMe() doesn't have that luxury. + +2) qemuDomainAdjustMaxMemLockHostdev() places a + virDomainHostdevDef pointer into domain definition, while + qemuDomainStorageSourceAccessModifyNVMe() (which calls + qemuDomainAdjustMaxMemLock()) sees a virStorageSource pointer + but domain definition contains virDomainDiskDef. But that's + okay, we can create a dummy disk definition and append it into + the domain definition. + +After this, qemuDomainAdjustMaxMemLock() can be called with +@forceVFIO = false, as the disk is now part of domain definition +(when computing the new limit). + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2014030#c28 +Signed-off-by: Michal Privoznik +Reviewed-by: Martin Kletzander +(cherry picked from commit c925bb927327c6f23864348286d931a25fbd13a3) + +https://bugzilla.redhat.com/show_bug.cgi?id=2014030 + +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_domain.c | 35 ++++++++++++++++++++++++++++++++++- + src/qemu/qemu_domain.h | 3 +++ + 2 files changed, 37 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index d556e2186c..b5b4184782 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -8026,7 +8026,7 @@ qemuDomainStorageSourceAccessModifyNVMe(virQEMUDriver *driver, + goto revoke; + } + +- if (qemuDomainAdjustMaxMemLock(vm, true) < 0) ++ if (qemuDomainAdjustMaxMemLockNVMe(vm, src) < 0) + goto revoke; + + revoke_maxmemlock = true; +@@ -9779,6 +9779,39 @@ qemuDomainAdjustMaxMemLockHostdev(virDomainObj *vm, + } + + ++/** ++ * qemuDomainAdjustMaxMemLockNVMe: ++ * @vm: domain object ++ * @src: disk source ++ * ++ * Temporarily add the disk source to the domain definition, ++ * adjust the max memlock based in this new definition and ++ * restore the original definition. ++ * ++ * Returns: 0 on success, ++ * -1 on failure. ++ */ ++int ++qemuDomainAdjustMaxMemLockNVMe(virDomainObj *vm, ++ virStorageSource *src) ++{ ++ g_autofree virDomainDiskDef *disk = NULL; ++ int ret = 0; ++ ++ disk = g_new0(virDomainDiskDef, 1); ++ disk->src = src; ++ ++ VIR_APPEND_ELEMENT_COPY(vm->def->disks, vm->def->ndisks, disk); ++ ++ if (qemuDomainAdjustMaxMemLock(vm, false) < 0) ++ ret = -1; ++ ++ VIR_DELETE_ELEMENT_INPLACE(vm->def->disks, vm->def->ndisks - 1, vm->def->ndisks); ++ ++ return ret; ++} ++ ++ + /** + * qemuDomainHasVcpuPids: + * @vm: Domain object +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index eaa75de3e5..ee2ddda079 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -41,6 +41,7 @@ + #include "virdomainmomentobjlist.h" + #include "virenum.h" + #include "vireventthread.h" ++#include "storage_source_conf.h" + + #define QEMU_DOMAIN_FORMAT_LIVE_FLAGS \ + (VIR_DOMAIN_XML_SECURE) +@@ -859,6 +860,8 @@ int qemuDomainAdjustMaxMemLock(virDomainObj *vm, + bool forceVFIO); + int qemuDomainAdjustMaxMemLockHostdev(virDomainObj *vm, + virDomainHostdevDef *hostdev); ++int qemuDomainAdjustMaxMemLockNVMe(virDomainObj *vm, ++ virStorageSource *src); + int qemuDomainSetMaxMemLock(virDomainObj *vm, + unsigned long long limit, + unsigned long long *origPtr); +-- +2.40.1 diff --git a/libvirt.spec b/libvirt.spec index 0151100..83e14aa 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -229,7 +229,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 9.3.0 -Release: 1%{?dist}%{?extra_release} +Release: 2%{?dist}%{?extra_release} License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1 URL: https://libvirt.org/ @@ -238,6 +238,8 @@ URL: https://libvirt.org/ %endif Source: https://download.libvirt.org/%{?mainturl}libvirt-%{version}.tar.xz Source1: symlinks +Patch1: libvirt-qemu_domin-Account-for-NVMe-disks-when-calculating-memlock-limit-on-hotplug.patch + Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2472,6 +2474,9 @@ exit 0 %endif %changelog +* Tue May 16 2023 Jiri Denemark - 9.3.0-2 +- qemu_domin: Account for NVMe disks when calculating memlock limit on hotplug (rhbz#2014030) + * Fri May 5 2023 Jiri Denemark - 9.3.0-1 - Rebased to libvirt-9.3.0 (rhbz#2175785) - The rebase also fixes the following bugs: