qemu: Support per-process memory accounting for iommufd

Implement 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>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Nathan Chen authored and Pavel Hrdina committed 2026-02-02 14:12:34 +01:00
1 parent 1043e04e17
commit f91a07d0c8
6 files changed
+121

No files matched your search

+1
View File
@@ -732,6 +732,7 @@ headers = [
'ifaddrs.h',
'libtasn1.h',
'linux/kvm.h',
'linux/iommufd.h',
'mntent.h',
'net/ethernet.h',
'net/if.h',
+1
View File
@@ -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
+3
View File
@@ -2646,6 +2646,9 @@ virInhibitorRelease;
virInitctlFifos;
virInitctlSetRunLevel;
# util/viriommufd.h
virIOMMUFDSetRLimitMode;
# util/viriscsi.h
virISCSIConnectionLogin;
virISCSIConnectionLogout;
+1
View File
@@ -46,6 +46,7 @@ util_sources = [
'viridentity.c',
'virinhibitor.c',
'virinitctl.c',
'viriommufd.c',
'viriscsi.c',
'virjson.c',
'virkeycode.c',
+90
View File
@@ -0,0 +1,90 @@
#include <config.h>
#include "viriommufd.h"
#include "virlog.h"
#include "virerror.h"
#include "virfile.h"
#define VIR_FROM_THIS VIR_FROM_NONE
VIR_LOG_INIT("util.iommufd");
#ifdef __linux__
# include <sys/ioctl.h>
# include <linux/types.h>
# ifdef HAVE_LINUX_IOMMUFD_H
# include <linux/iommufd.h>
# endif
# ifndef IOMMU_OPTION
enum iommufd_option {
IOMMU_OPTION_RLIMIT_MODE = 0,
IOMMU_OPTION_HUGE_PAGES = 1,
};
enum iommufd_option_ops {
IOMMU_OPTION_OP_SET = 0,
IOMMU_OPTION_OP_GET = 1,
};
struct iommu_option {
__u32 size;
__u32 option_id;
__u16 op;
__u16 __reserved;
__u32 object_id;
__aligned_u64 val64;
};
# define IOMMUFD_TYPE (';')
# define IOMMUFD_CMD_OPTION 0x87
# define IOMMU_OPTION _IO(IOMMUFD_TYPE, IOMMUFD_CMD_OPTION)
# endif
/**
* virIOMMUFDSetRLimitMode:
* @fd: iommufd file descriptor
* @processAccounting: true for per-process, false for per-user
*
* Set RLIMIT_MEMLOCK accounting mode for the iommufd.
*
* Returns: 0 on success, -1 on error
*/
int
virIOMMUFDSetRLimitMode(int fd, bool processAccounting)
{
struct iommu_option option = {
.size = sizeof(struct iommu_option),
.option_id = IOMMU_OPTION_RLIMIT_MODE,
.op = IOMMU_OPTION_OP_SET,
.__reserved = 0,
.object_id = 0,
.val64 = processAccounting ? 1 : 0,
};
if (ioctl(fd, IOMMU_OPTION, &option) < 0) {
virReportSystemError(errno, "%s",
_("failed to set memory accounting for iommufd"));
return -1;
}
VIR_DEBUG("Set iommufd rlimit mode to %s-based accounting",
processAccounting ? "process" : "user");
return 0;
}
#else
int virIOMMUFDSetRLimitMode(int fd G_GNUC_UNUSED,
bool processAccounting G_GNUC_UNUSED)
{
virReportError(VIR_ERR_NO_SUPPORT, "%s",
_("IOMMUFD is not supported on this platform"));
return -1;
}
#endif
+25
View File
@@ -0,0 +1,25 @@
/*
* viriommufd.h: iommufd helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "internal.h"
#define VIR_IOMMU_DEV_PATH "/dev/iommu"
int virIOMMUFDSetRLimitMode(int fd, bool processAccounting);