Pablo Greco 40546a
From 05610561d752380d3f75780056fea927d723b53b Mon Sep 17 00:00:00 2001
Pablo Greco 40546a
Message-Id: <05610561d752380d3f75780056fea927d723b53b@dist-git>
Pablo Greco 40546a
From: Pavel Hrdina <phrdina@redhat.com>
Pablo Greco 40546a
Date: Mon, 1 Jul 2019 17:07:47 +0200
Pablo Greco 40546a
Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)CpuCfsPeriod
Pablo Greco 40546a
MIME-Version: 1.0
Pablo Greco 40546a
Content-Type: text/plain; charset=UTF-8
Pablo Greco 40546a
Content-Transfer-Encoding: 8bit
Pablo Greco 40546a
Pablo Greco 40546a
In order to set CPU cfs period using cgroup v2 'cpu.max' interface
Pablo Greco 40546a
we need to load the current value of CPU cfs quota first because
Pablo Greco 40546a
format of 'cpu.max' interface is '$quota $period' and in order to
Pablo Greco 40546a
change 'period' we need to write 'quota' as well.  Writing only one
Pablo Greco 40546a
number changes only 'quota'.
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Pablo Greco 40546a
(cherry picked from commit 832422457214421211304bfb0c92b00546dcec53)
Pablo Greco 40546a
Pablo Greco 40546a
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Pablo Greco 40546a
Message-Id: <21d457977390fd50b26a2ea5f7f904946578accb.1561993100.git.phrdina@redhat.com>
Pablo Greco 40546a
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Pablo Greco 40546a
---
Pablo Greco 40546a
 src/util/vircgroupv2.c | 68 ++++++++++++++++++++++++++++++++++++++++++
Pablo Greco 40546a
 1 file changed, 68 insertions(+)
Pablo Greco 40546a
Pablo Greco 40546a
diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
Pablo Greco 40546a
index cb9dd3d8e8..876785e4e1 100644
Pablo Greco 40546a
--- a/src/util/vircgroupv2.c
Pablo Greco 40546a
+++ b/src/util/vircgroupv2.c
Pablo Greco 40546a
@@ -1325,6 +1325,72 @@ virCgroupV2GetCpuShares(virCgroupPtr group,
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
+static int
Pablo Greco 40546a
+virCgroupV2SetCpuCfsPeriod(virCgroupPtr group,
Pablo Greco 40546a
+                           unsigned long long cfs_period)
Pablo Greco 40546a
+{
Pablo Greco 40546a
+    VIR_AUTOFREE(char *) value = NULL;
Pablo Greco 40546a
+    VIR_AUTOFREE(char *) str = NULL;
Pablo Greco 40546a
+    char *tmp;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    /* The cfs_period should be greater or equal than 1ms, and less or equal
Pablo Greco 40546a
+     * than 1s.
Pablo Greco 40546a
+     */
Pablo Greco 40546a
+    if (cfs_period < 1000 || cfs_period > 1000000) {
Pablo Greco 40546a
+        virReportError(VIR_ERR_INVALID_ARG,
Pablo Greco 40546a
+                       _("cfs_period '%llu' must be in range (1000, 1000000)"),
Pablo Greco 40546a
+                       cfs_period);
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPU,
Pablo Greco 40546a
+                             "cpu.max", &str) < 0) {
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (!(tmp = strchr(str, ' '))) {
Pablo Greco 40546a
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
Pablo Greco 40546a
+                       _("Invalid 'cpu.max' data."));
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+    *tmp = '\n';
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (virAsprintf(&value, "%s %llu", str, cfs_period) < 0)
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return virCgroupSetValueStr(group, VIR_CGROUP_CONTROLLER_CPU,
Pablo Greco 40546a
+                                "cpu.max", value);
Pablo Greco 40546a
+}
Pablo Greco 40546a
+
Pablo Greco 40546a
+
Pablo Greco 40546a
+static int
Pablo Greco 40546a
+virCgroupV2GetCpuCfsPeriod(virCgroupPtr group,
Pablo Greco 40546a
+                           unsigned long long *cfs_period)
Pablo Greco 40546a
+{
Pablo Greco 40546a
+    VIR_AUTOFREE(char *) str = NULL;
Pablo Greco 40546a
+    char *tmp;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPU,
Pablo Greco 40546a
+                             "cpu.max", &str) < 0) {
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (!(tmp = strchr(str, ' '))) {
Pablo Greco 40546a
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
Pablo Greco 40546a
+                       _("Invalid 'cpu.max' data."));
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (virStrToLong_ull(tmp, NULL, 10, cfs_period) < 0) {
Pablo Greco 40546a
+        virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
+                       _("Failed to parse value '%s' from cpu.max."), str);
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return 0;
Pablo Greco 40546a
+}
Pablo Greco 40546a
+
Pablo Greco 40546a
+
Pablo Greco 40546a
 virCgroupBackend virCgroupV2Backend = {
Pablo Greco 40546a
     .type = VIR_CGROUP_BACKEND_TYPE_V2,
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1375,6 +1441,8 @@ virCgroupBackend virCgroupV2Backend = {
Pablo Greco 40546a
 
Pablo Greco 40546a
     .setCpuShares = virCgroupV2SetCpuShares,
Pablo Greco 40546a
     .getCpuShares = virCgroupV2GetCpuShares,
Pablo Greco 40546a
+    .setCpuCfsPeriod = virCgroupV2SetCpuCfsPeriod,
Pablo Greco 40546a
+    .getCpuCfsPeriod = virCgroupV2GetCpuCfsPeriod,
Pablo Greco 40546a
 };
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-- 
Pablo Greco 40546a
2.22.0
Pablo Greco 40546a