From afbe1d4c565c2f00a80cbc0849fb9e346dedbcbc Mon Sep 17 00:00:00 2001 From: Andrea Bolognani Date: Thu, 10 Dec 2015 19:13:58 +0100 Subject: [PATCH] qemu: Allow qemuDomainAdjustMaxMemLock() to restore previous value When the function changes the memory lock limit for the first time, it will retrieve the current value and store it inside the virDomainObj for the domain. When the function is called again, if memory locking is no longer needed, it will be able to restore the memory locking limit to its original value. --- src/conf/domain_conf.h | 3 +++ src/qemu/qemu_domain.c | 21 +++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index cec681a788..952d3ccbf7 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2420,6 +2420,9 @@ struct _virDomainObj { void (*privateDataFreeFunc)(void *); int taint; + + unsigned long long original_memlock; /* Original RLIMIT_MEMLOCK, zero if no + * restore will be required later */ }; typedef bool (*virDomainObjListACLFilter)(virConnectPtr conn, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4b796ab60e..1e1e57f7fc 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4125,7 +4125,10 @@ qemuDomainRequiresMlock(virDomainDefPtr def) * Adjust the memory locking limit for the QEMU process associated to @vm, in * order to comply with VFIO or architecture requirements. * - * The limit will not be changed unless doing so is needed. + * The limit will not be changed unless doing so is needed; the first time + * the limit is changed, the original (default) limit is stored in @vm and + * that value will be restored if qemuDomainAdjustMaxMemLock() is called once + * memory locking is no longer required. * * Returns: 0 on success, <0 on failure */ @@ -4135,8 +4138,22 @@ qemuDomainAdjustMaxMemLock(virDomainObjPtr vm) unsigned long long bytes = 0; int ret = -1; - if (qemuDomainRequiresMlock(vm->def)) + if (qemuDomainRequiresMlock(vm->def)) { + /* If this is the first time adjusting the limit, save the current + * value so that we can restore it once memory locking is no longer + * required. Failing to obtain the current limit is not a critical + * failure, it just means we'll be unable to lower it later */ + if (!vm->original_memlock) { + if (virProcessGetMaxMemLock(vm->pid, &(vm->original_memlock)) < 0) + vm->original_memlock = 0; + } bytes = qemuDomainGetMlockLimitBytes(vm->def); + } else { + /* Once memory locking is no longer required, we can restore the + * original, usually very low, limit */ + bytes = vm->original_memlock; + vm->original_memlock = 0; + } /* Trying to set the memory locking limit to zero is a no-op */ if (virProcessSetMaxMemLock(vm->pid, bytes) < 0)