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, &current) < 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, &currentMemLock) < 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