|
|
11fcb6 |
From 7f5b89a15bfcd964c7f2b6ccbf3c03fd867f93b5 Mon Sep 17 00:00:00 2001
|
|
|
11fcb6 |
Message-Id: <7f5b89a15bfcd964c7f2b6ccbf3c03fd867f93b5@dist-git>
|
|
|
11fcb6 |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
11fcb6 |
Date: Wed, 22 Jun 2022 15:21:30 +0200
|
|
|
11fcb6 |
Subject: [PATCH] qemu: Add qemuDomainSetMaxMemLock helper
|
|
|
11fcb6 |
MIME-Version: 1.0
|
|
|
11fcb6 |
Content-Type: text/plain; charset=UTF-8
|
|
|
11fcb6 |
Content-Transfer-Encoding: 8bit
|
|
|
11fcb6 |
|
|
|
11fcb6 |
qemuDomainAdjustMaxMemLock combined computing the desired limit with
|
|
|
11fcb6 |
applying it. This patch separates the code to apply a memory locking
|
|
|
11fcb6 |
limit to a new qemuDomainSetMaxMemLock helper for better reusability.
|
|
|
11fcb6 |
|
|
|
11fcb6 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
11fcb6 |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
11fcb6 |
(cherry picked from commit dff51c7f5760ded8235076f55d082fe4363f2f78)
|
|
|
11fcb6 |
|
|
|
11fcb6 |
https://bugzilla.redhat.com/show_bug.cgi?id=2117272
|
|
|
11fcb6 |
|
|
|
11fcb6 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
11fcb6 |
---
|
|
|
11fcb6 |
src/qemu/qemu_domain.c | 95 ++++++++++++++++++++++++++----------------
|
|
|
11fcb6 |
src/qemu/qemu_domain.h | 3 ++
|
|
|
11fcb6 |
2 files changed, 61 insertions(+), 37 deletions(-)
|
|
|
11fcb6 |
|
|
|
11fcb6 |
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|
|
11fcb6 |
index ee7d310903..a81789f194 100644
|
|
|
11fcb6 |
--- a/src/qemu/qemu_domain.c
|
|
|
11fcb6 |
+++ b/src/qemu/qemu_domain.c
|
|
|
11fcb6 |
@@ -9261,6 +9261,61 @@ qemuDomainGetMemLockLimitBytes(virDomainDef *def,
|
|
|
11fcb6 |
}
|
|
|
11fcb6 |
|
|
|
11fcb6 |
|
|
|
11fcb6 |
+/**
|
|
|
11fcb6 |
+ * qemuDomainSetMaxMemLock:
|
|
|
11fcb6 |
+ * @vm: domain
|
|
|
11fcb6 |
+ * @limit: the desired memory locking limit
|
|
|
11fcb6 |
+ * @origPtr: where to store (or load from) the original value of the limit
|
|
|
11fcb6 |
+ *
|
|
|
11fcb6 |
+ * Set the memory locking limit for @vm unless it's already big enough. If
|
|
|
11fcb6 |
+ * @origPtr is non-NULL, the original value of the limit will be store there
|
|
|
11fcb6 |
+ * and can be restored by calling this function with @limit == 0.
|
|
|
11fcb6 |
+ *
|
|
|
11fcb6 |
+ * Returns: 0 on success, -1 otherwise.
|
|
|
11fcb6 |
+ */
|
|
|
11fcb6 |
+int
|
|
|
11fcb6 |
+qemuDomainSetMaxMemLock(virDomainObj *vm,
|
|
|
11fcb6 |
+ unsigned long long limit,
|
|
|
11fcb6 |
+ unsigned long long *origPtr)
|
|
|
11fcb6 |
+{
|
|
|
11fcb6 |
+ unsigned long long current = 0;
|
|
|
11fcb6 |
+
|
|
|
11fcb6 |
+ if (virProcessGetMaxMemLock(vm->pid, ¤t) < 0)
|
|
|
11fcb6 |
+ return -1;
|
|
|
11fcb6 |
+
|
|
|
11fcb6 |
+ if (limit > 0) {
|
|
|
11fcb6 |
+ VIR_DEBUG("Requested memory lock limit: %llu", limit);
|
|
|
11fcb6 |
+ /* If the limit is already high enough, we can assume
|
|
|
11fcb6 |
+ * that some external process is taking care of managing
|
|
|
11fcb6 |
+ * process limits and we shouldn't do anything ourselves:
|
|
|
11fcb6 |
+ * we're probably running in a containerized environment
|
|
|
11fcb6 |
+ * where we don't have enough privilege anyway */
|
|
|
11fcb6 |
+ if (current >= limit) {
|
|
|
11fcb6 |
+ VIR_DEBUG("Current limit %llu is big enough", current);
|
|
|
11fcb6 |
+ return 0;
|
|
|
11fcb6 |
+ }
|
|
|
11fcb6 |
+
|
|
|
11fcb6 |
+ /* If this is the first time adjusting the limit, save the current
|
|
|
11fcb6 |
+ * value so that we can restore it once memory locking is no longer
|
|
|
11fcb6 |
+ * required */
|
|
|
11fcb6 |
+ if (origPtr && *origPtr == 0)
|
|
|
11fcb6 |
+ *origPtr = current;
|
|
|
11fcb6 |
+ } else {
|
|
|
11fcb6 |
+ /* Once memory locking is no longer required, we can restore the
|
|
|
11fcb6 |
+ * original, usually very low, limit. But only if we actually stored
|
|
|
11fcb6 |
+ * the original limit before. */
|
|
|
11fcb6 |
+ if (!origPtr || *origPtr == 0)
|
|
|
11fcb6 |
+ return 0;
|
|
|
11fcb6 |
+
|
|
|
11fcb6 |
+ limit = *origPtr;
|
|
|
11fcb6 |
+ *origPtr = 0;
|
|
|
11fcb6 |
+ VIR_DEBUG("Resetting memory lock limit back to %llu", limit);
|
|
|
11fcb6 |
+ }
|
|
|
11fcb6 |
+
|
|
|
11fcb6 |
+ return virProcessSetMaxMemLock(vm->pid, limit);
|
|
|
11fcb6 |
+}
|
|
|
11fcb6 |
+
|
|
|
11fcb6 |
+
|
|
|
11fcb6 |
/**
|
|
|
11fcb6 |
* qemuDomainAdjustMaxMemLock:
|
|
|
11fcb6 |
* @vm: domain
|
|
|
11fcb6 |
@@ -9282,43 +9337,9 @@ int
|
|
|
11fcb6 |
qemuDomainAdjustMaxMemLock(virDomainObj *vm,
|
|
|
11fcb6 |
bool forceVFIO)
|
|
|
11fcb6 |
{
|
|
|
11fcb6 |
- qemuDomainObjPrivate *priv = vm->privateData;
|
|
|
11fcb6 |
- unsigned long long currentMemLock = 0;
|
|
|
11fcb6 |
- unsigned long long desiredMemLock = 0;
|
|
|
11fcb6 |
-
|
|
|
11fcb6 |
- desiredMemLock = qemuDomainGetMemLockLimitBytes(vm->def, forceVFIO);
|
|
|
11fcb6 |
- if (virProcessGetMaxMemLock(vm->pid, ¤tMemLock) < 0)
|
|
|
11fcb6 |
- return -1;
|
|
|
11fcb6 |
-
|
|
|
11fcb6 |
- if (desiredMemLock > 0) {
|
|
|
11fcb6 |
- if (currentMemLock < desiredMemLock) {
|
|
|
11fcb6 |
- /* If this is the first time adjusting the limit, save the current
|
|
|
11fcb6 |
- * value so that we can restore it once memory locking is no longer
|
|
|
11fcb6 |
- * required */
|
|
|
11fcb6 |
- if (priv->originalMemlock == 0) {
|
|
|
11fcb6 |
- priv->originalMemlock = currentMemLock;
|
|
|
11fcb6 |
- }
|
|
|
11fcb6 |
- } else {
|
|
|
11fcb6 |
- /* If the limit is already high enough, we can assume
|
|
|
11fcb6 |
- * that some external process is taking care of managing
|
|
|
11fcb6 |
- * process limits and we shouldn't do anything ourselves:
|
|
|
11fcb6 |
- * we're probably running in a containerized environment
|
|
|
11fcb6 |
- * where we don't have enough privilege anyway */
|
|
|
11fcb6 |
- desiredMemLock = 0;
|
|
|
11fcb6 |
- }
|
|
|
11fcb6 |
- } else {
|
|
|
11fcb6 |
- /* Once memory locking is no longer required, we can restore the
|
|
|
11fcb6 |
- * original, usually very low, limit */
|
|
|
11fcb6 |
- desiredMemLock = priv->originalMemlock;
|
|
|
11fcb6 |
- priv->originalMemlock = 0;
|
|
|
11fcb6 |
- }
|
|
|
11fcb6 |
-
|
|
|
11fcb6 |
- if (desiredMemLock > 0 &&
|
|
|
11fcb6 |
- virProcessSetMaxMemLock(vm->pid, desiredMemLock) < 0) {
|
|
|
11fcb6 |
- return -1;
|
|
|
11fcb6 |
- }
|
|
|
11fcb6 |
-
|
|
|
11fcb6 |
- return 0;
|
|
|
11fcb6 |
+ return qemuDomainSetMaxMemLock(vm,
|
|
|
11fcb6 |
+ qemuDomainGetMemLockLimitBytes(vm->def, forceVFIO),
|
|
|
11fcb6 |
+ &QEMU_DOMAIN_PRIVATE(vm)->originalMemlock);
|
|
|
11fcb6 |
}
|
|
|
11fcb6 |
|
|
|
11fcb6 |
|
|
|
11fcb6 |
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
|
|
|
11fcb6 |
index e9497d20de..6d1d23439a 100644
|
|
|
11fcb6 |
--- a/src/qemu/qemu_domain.h
|
|
|
11fcb6 |
+++ b/src/qemu/qemu_domain.h
|
|
|
11fcb6 |
@@ -789,6 +789,9 @@ int qemuDomainAdjustMaxMemLock(virDomainObj *vm,
|
|
|
11fcb6 |
bool forceVFIO);
|
|
|
11fcb6 |
int qemuDomainAdjustMaxMemLockHostdev(virDomainObj *vm,
|
|
|
11fcb6 |
virDomainHostdevDef *hostdev);
|
|
|
11fcb6 |
+int qemuDomainSetMaxMemLock(virDomainObj *vm,
|
|
|
11fcb6 |
+ unsigned long long limit,
|
|
|
11fcb6 |
+ unsigned long long *origPtr);
|
|
|
11fcb6 |
|
|
|
11fcb6 |
int qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
|
|
|
11fcb6 |
const virDomainMemoryDef *mem);
|
|
|
11fcb6 |
--
|
|
|
11fcb6 |
2.35.1
|
|
|
11fcb6 |
|