On 1/5/2026 8:09 AM, Daniel P. Berrangé wrote:
On Thu, Dec 18, 2025 at 06:19:23PM -0800, Nathan Chen via Devel wrote:
From: Nathan Chen<nathanc@nvidia.com>
Integrate and use the IOMMU_OPTION_RLIMIT_MODE ioctl to set per-process memory accounting for iommufd. This prevents ENOMEM errors from the default per-user memory accounting when multiple VMs under the libvirt-qemu user have their pinned memory summed and checked against a per-process RLIMIT_MEMLOCK limit.
Signed-off-by: Nathan Chen<nathanc@nvidia.com> --- po/POTFILES | 1 + src/libvirt_private.syms | 3 ++ src/qemu/qemu_process.c | 7 ++++ src/util/meson.build | 1 + src/util/viriommufd.c | 89 ++++++++++++++++++++++++++++++++++++++++ src/util/viriommufd.h | 23 +++++++++++ 6 files changed, 124 insertions(+) create mode 100644 src/util/viriommufd.c create mode 100644 src/util/viriommufd.h
diff --git a/po/POTFILES b/po/POTFILES index f0aad35c8c..c78d2b8000 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -303,6 +303,7 @@ src/util/virhostuptime.c src/util/viridentity.c src/util/virinhibitor.c src/util/virinitctl.c +src/util/viriommufd.c src/util/viriscsi.c src/util/virjson.c src/util/virlease.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ed2b0d381e..e2a7a16347 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2652,6 +2652,9 @@ virInhibitorRelease; virInitctlFifos; virInitctlSetRunLevel;
+# util/viriommufd.h +virIOMMUFDSetRLimitMode; + # util/viriscsi.h virISCSIConnectionLogin; virISCSIConnectionLogout; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 8863be2cb6..db56720f3d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -104,6 +104,7 @@ #include "backup_conf.h" #include "storage_file_probe.h" #include "virpci.h" +#include "viriommufd.h"
#include "logging/log_manager.h" #include "logging/log_protocol.h" @@ -10392,6 +10393,12 @@ qemuProcessOpenIommuFd(virDomainObj *vm) return -1; }
+ /* Set per-process memory accounting */ + if (virIOMMUFDSetRLimitMode(fd, true) < 0) { + VIR_FORCE_CLOSE(fd); + return -1; + } + VIR_DEBUG("Opened IOMMU FD %d for domain %s", fd, vm->def->name); return fd; } diff --git a/src/util/meson.build b/src/util/meson.build index 4950a795cc..9fb0aa0fe7 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -46,6 +46,7 @@ util_sources = [ 'viridentity.c', 'virinhibitor.c', 'virinitctl.c', + 'viriommufd.c', 'viriscsi.c', 'virjson.c', 'virkeycode.c', diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c new file mode 100644 index 0000000000..163ac632ba --- /dev/null +++ b/src/util/viriommufd.c @@ -0,0 +1,89 @@ +#include <config.h> + +#include "viriommufd.h" +#include "virlog.h" +#include "virerror.h" + +#include <sys/ioctl.h> +#include <linux/types.h> This breaks the build of libvirt on non-Linux platforms
$ meson build --cross-file=/usr/share/mingw/toolchain-mingw64.meson $ meson -C build src/util/libvirt_util.a.p/viriommufd.c.obj -c ../src/util/viriommufd.c ../src/util/viriommufd.c:7:10: fatal error: sys/ioctl.h: No such file or directory 7 | #include <sys/ioctl.h> | ^~~~~~~~~~~~~ compilation terminated.
Thanks for catching this, I will look into conditionally compiling viriommufd.c only on Linux. -Nathan