From 05610561d752380d3f75780056fea927d723b53b Mon Sep 17 00:00:00 2001 Message-Id: <05610561d752380d3f75780056fea927d723b53b@dist-git> From: Pavel Hrdina Date: Mon, 1 Jul 2019 17:07:47 +0200 Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)CpuCfsPeriod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 (cherry picked from commit 832422457214421211304bfb0c92b00546dcec53) Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 Signed-off-by: Pavel Hrdina Message-Id: <21d457977390fd50b26a2ea5f7f904946578accb.1561993100.git.phrdina@redhat.com> Reviewed-by: Ján Tomko --- src/util/vircgroupv2.c | 68 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c index cb9dd3d8e8..876785e4e1 100644 --- a/src/util/vircgroupv2.c +++ b/src/util/vircgroupv2.c @@ -1325,6 +1325,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, @@ -1375,6 +1441,8 @@ virCgroupBackend virCgroupV2Backend = { .setCpuShares = virCgroupV2SetCpuShares, .getCpuShares = virCgroupV2GetCpuShares, + .setCpuCfsPeriod = virCgroupV2SetCpuCfsPeriod, + .getCpuCfsPeriod = virCgroupV2GetCpuCfsPeriod, }; -- 2.22.0