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