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<[email protected]>

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<[email protected]>
---
  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

Reply via email to