Require a minimal pagesize for hugetlbfs backed guests. Fail guest initialization if hugetlbfs mount is configured with smaller page size. Signed-off-by: Marcelo Tosatti <mtosatti@xxxxxxxxxx> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fd02864..e28d182 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -632,6 +632,10 @@ <dt><code>hugepages</code></dt> <dd>This tells the hypervisor that the guest should have its memory allocated using hugepages instead of the normal native page size.</dd> + <dt><code>pagesize</code></dt> + <dd>This tells the hypervisor that the guest should refuse to start + in case of failure to allocate guest memory with hugepages equal + to or larger than the specified size</dd> <dt><code>nosharepages</code></dt> <dd>Instructs hypervisor to disable shared pages (memory merge, KSM) for this domain. <span class="since">Since 1.0.6</span></dd> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 28e24f9..babb745 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -11274,6 +11274,10 @@ virDomainDefParseXML(xmlDocPtr xml, &def->mem.swap_hard_limit, false) < 0) goto error; + if (virDomainParseMemory("./memoryBacking/hugepages/pagesize[1]", ctxt, + &def->mem.page_size, false) < 0) + goto error; + n = virXPathULong("string(./vcpu[1])", ctxt, &count); if (n == -2) { virReportError(VIR_ERR_XML_ERROR, "%s", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d8f2e49..03a900d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1984,6 +1984,7 @@ struct _virDomainDef { unsigned long long soft_limit; /* in kibibytes */ unsigned long long min_guarantee; /* in kibibytes */ unsigned long long swap_hard_limit; /* in kibibytes */ + unsigned long long page_size; /* in kibibytes */ } mem; unsigned short vcpus; unsigned short maxvcpus; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 8bcd98e..cd5e1c8 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3570,6 +3570,33 @@ cleanup: return ret; } +#ifdef __linux__ + +#include <sys/vfs.h> + +#define HUGETLBFS_MAGIC 0x958458f6 + +static long gethugepagesize(const char *path) +{ + struct statfs fs; + int ret; + + do { + ret = statfs(path, &fs); + } while (ret != 0 && errno == EINTR); + + if (ret != 0) { + perror(path); + return 0; + } + + if (fs.f_type != HUGETLBFS_MAGIC) + return 0; + + return fs.f_bsize; +} +#endif + int qemuProcessStart(virConnectPtr conn, virQEMUDriverPtr driver, @@ -3712,6 +3739,31 @@ int qemuProcessStart(virConnectPtr conn, "%s", _("Unable to set huge path in security driver")); goto cleanup; } + + if (vm->def->mem.page_size) { +#ifdef __linux__ + unsigned long hpagesize = gethugepagesize(cfg->hugepagePath); + + if (!hpagesize) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Unable to stat hugepage path")); + goto cleanup; + } + + hpagesize /= 1024; + + if (hpagesize < vm->def->mem.page_size) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Error: hugetlbfs page size=%ld < pagesize=%lld"), + hpagesize, vm->def->mem.page_size); + goto cleanup; + } +#else + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + "%s", _("pagesize option unsupported")); + goto cleanup; +#endif + } } /* Ensure no historical cgroup for this VM is lying around bogus -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list