[libvirt] [PATCH v2 36/53] [ACKED] vircgroup: introduce virCgroupV2(Set|Get)CpuCfsPeriod

Pavel Hrdina phrdina at redhat.com
Fri Oct 5 12:43:57 UTC 2018


In order to set CPU cfs period using cgroup v2 'cpu.max' interface
we need to load the current value of CPU cfs quota first because
format of 'cpu.max' interface is '$quota $period' and in order to
change 'period' we need to write 'quota' as well.  Writing only one
number changes only 'quota'.

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 src/util/vircgroupv2.c | 68 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
index 986b2d07c1..24c5bb3e3d 100644
--- a/src/util/vircgroupv2.c
+++ b/src/util/vircgroupv2.c
@@ -1333,6 +1333,72 @@ virCgroupV2GetCpuShares(virCgroupPtr group,
 }
 
 
+static int
+virCgroupV2SetCpuCfsPeriod(virCgroupPtr group,
+                           unsigned long long cfs_period)
+{
+    VIR_AUTOFREE(char *) value = NULL;
+    VIR_AUTOFREE(char *) str = NULL;
+    char *tmp;
+
+    /* The cfs_period should be greater or equal than 1ms, and less or equal
+     * than 1s.
+     */
+    if (cfs_period < 1000 || cfs_period > 1000000) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("cfs_period '%llu' must be in range (1000, 1000000)"),
+                       cfs_period);
+        return -1;
+    }
+
+    if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPU,
+                             "cpu.max", &str) < 0) {
+        return -1;
+    }
+
+    if (!(tmp = strchr(str, ' '))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Invalid 'cpu.max' data."));
+        return -1;
+    }
+    *tmp = '\n';
+
+    if (virAsprintf(&value, "%s %llu", str, cfs_period) < 0)
+        return -1;
+
+    return virCgroupSetValueStr(group, VIR_CGROUP_CONTROLLER_CPU,
+                                "cpu.max", value);
+}
+
+
+static int
+virCgroupV2GetCpuCfsPeriod(virCgroupPtr group,
+                           unsigned long long *cfs_period)
+{
+    VIR_AUTOFREE(char *) str = NULL;
+    char *tmp;
+
+    if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPU,
+                             "cpu.max", &str) < 0) {
+        return -1;
+    }
+
+    if (!(tmp = strchr(str, ' '))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Invalid 'cpu.max' data."));
+        return -1;
+    }
+
+    if (virStrToLong_ull(tmp, NULL, 10, cfs_period) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Failed to parse value '%s' from cpu.max."), str);
+        return -1;
+    }
+
+    return 0;
+}
+
+
 virCgroupBackend virCgroupV2Backend = {
     .type = VIR_CGROUP_BACKEND_TYPE_V2,
 
@@ -1383,6 +1449,8 @@ virCgroupBackend virCgroupV2Backend = {
 
     .setCpuShares = virCgroupV2SetCpuShares,
     .getCpuShares = virCgroupV2GetCpuShares,
+    .setCpuCfsPeriod = virCgroupV2SetCpuCfsPeriod,
+    .getCpuCfsPeriod = virCgroupV2GetCpuCfsPeriod,
 };
 
 
-- 
2.17.1




More information about the libvir-list mailing list