From 5101d214a63b31847f80048d4ee34b5e62176ddd Mon Sep 17 00:00:00 2001 Message-Id: <5101d214a63b31847f80048d4ee34b5e62176ddd@dist-git> From: Pavel Hrdina Date: Mon, 1 Jul 2019 17:06:52 +0200 Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)Memory*Limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They all need virCgroupV1GetMemoryUnlimitedKB() so it's easier to move them in one commit. Reviewed-by: Fabiano Fidêncio Reviewed-by: Ján Tomko Signed-off-by: Pavel Hrdina (cherry picked from commit 900c58b7f963d5054921e31bbd0b6005155b284a) Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 Signed-off-by: Pavel Hrdina Message-Id: Reviewed-by: Ján Tomko --- src/util/vircgroup.c | 128 ++------------------------- src/util/vircgroupbackend.h | 30 +++++++ src/util/vircgrouppriv.h | 6 ++ src/util/vircgroupv1.c | 168 ++++++++++++++++++++++++++++++++++++ 4 files changed, 211 insertions(+), 121 deletions(-) diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index ed7252243c..6708eef0da 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -634,7 +634,7 @@ virCgroupMakeGroup(virCgroupPtr parent, * * Returns 0 on success, -1 on error */ -static int +int virCgroupNew(pid_t pid, const char *path, virCgroupPtr parent, @@ -1537,51 +1537,6 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group, } -/* - * Retrieve the "memory.limit_in_bytes" value from the memory controller - * root dir. This value cannot be modified by userspace and therefore - * is the maximum limit value supported by cgroups on the local system. - * Returns this value scaled to KB or falls back to the original - * VIR_DOMAIN_MEMORY_PARAM_UNLIMITED. Either way, remember the return - * value to avoid unnecessary cgroup filesystem access. - */ -static unsigned long long int virCgroupMemoryUnlimitedKB; -static virOnceControl virCgroupMemoryOnce = VIR_ONCE_CONTROL_INITIALIZER; - -static void -virCgroupMemoryOnceInit(void) -{ - virCgroupPtr group; - unsigned long long int mem_unlimited = 0ULL; - - if (virCgroupNew(-1, "/", NULL, -1, &group) < 0) - goto cleanup; - - if (!virCgroupHasController(group, VIR_CGROUP_CONTROLLER_MEMORY)) - goto cleanup; - - ignore_value(virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.limit_in_bytes", - &mem_unlimited)); - cleanup: - virCgroupFree(&group); - virCgroupMemoryUnlimitedKB = mem_unlimited >> 10; -} - -static unsigned long long int -virCgroupGetMemoryUnlimitedKB(void) -{ - if (virOnce(&virCgroupMemoryOnce, virCgroupMemoryOnceInit) < 0) - VIR_DEBUG("Init failed, will fall back to defaults."); - - if (virCgroupMemoryUnlimitedKB) - return virCgroupMemoryUnlimitedKB; - else - return VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; -} - - /** * virCgroupSetMemory: * @@ -1652,7 +1607,7 @@ virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) { - return virCgroupSetMemory(group, kb); + VIR_CGROUP_BACKEND_CALL(group, setMemoryHardLimit, -1, kb); } @@ -1667,18 +1622,7 @@ virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) { - long long unsigned int limit_in_bytes; - - if (virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.limit_in_bytes", &limit_in_bytes) < 0) - return -1; - - *kb = limit_in_bytes >> 10; - if (*kb >= virCgroupGetMemoryUnlimitedKB()) - *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; - - return 0; + VIR_CGROUP_BACKEND_CALL(group, getMemoryHardLimit, -1, kb); } @@ -1693,25 +1637,7 @@ virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) { - unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; - - if (kb > maxkb) { - virReportError(VIR_ERR_INVALID_ARG, - _("Memory '%llu' must be less than %llu"), - kb, maxkb); - return -1; - } - - if (kb == maxkb) - return virCgroupSetValueI64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.soft_limit_in_bytes", - -1); - else - return virCgroupSetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.soft_limit_in_bytes", - kb << 10); + VIR_CGROUP_BACKEND_CALL(group, setMemorySoftLimit, -1, kb); } @@ -1726,18 +1652,7 @@ virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) { - long long unsigned int limit_in_bytes; - - if (virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.soft_limit_in_bytes", &limit_in_bytes) < 0) - return -1; - - *kb = limit_in_bytes >> 10; - if (*kb >= virCgroupGetMemoryUnlimitedKB()) - *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; - - return 0; + VIR_CGROUP_BACKEND_CALL(group, getMemorySoftLimit, -1, kb); } @@ -1752,25 +1667,7 @@ virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) int virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) { - unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; - - if (kb > maxkb) { - virReportError(VIR_ERR_INVALID_ARG, - _("Memory '%llu' must be less than %llu"), - kb, maxkb); - return -1; - } - - if (kb == maxkb) - return virCgroupSetValueI64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.memsw.limit_in_bytes", - -1); - else - return virCgroupSetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.memsw.limit_in_bytes", - kb << 10); + VIR_CGROUP_BACKEND_CALL(group, setMemSwapHardLimit, -1, kb); } @@ -1785,18 +1682,7 @@ virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) int virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) { - long long unsigned int limit_in_bytes; - - if (virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.memsw.limit_in_bytes", &limit_in_bytes) < 0) - return -1; - - *kb = limit_in_bytes >> 10; - if (*kb >= virCgroupGetMemoryUnlimitedKB()) - *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; - - return 0; + VIR_CGROUP_BACKEND_CALL(group, getMemSwapHardLimit, -1, kb); } diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h index 8bdfc5c835..cdbca4b907 100644 --- a/src/util/vircgroupbackend.h +++ b/src/util/vircgroupbackend.h @@ -227,6 +227,30 @@ typedef int (*virCgroupGetMemoryUsageCB)(virCgroupPtr group, unsigned long *kb); +typedef int +(*virCgroupSetMemoryHardLimitCB)(virCgroupPtr group, + unsigned long long kb); + +typedef int +(*virCgroupGetMemoryHardLimitCB)(virCgroupPtr group, + unsigned long long *kb); + +typedef int +(*virCgroupSetMemorySoftLimitCB)(virCgroupPtr group, + unsigned long long kb); + +typedef int +(*virCgroupGetMemorySoftLimitCB)(virCgroupPtr group, + unsigned long long *kb); + +typedef int +(*virCgroupSetMemSwapHardLimitCB)(virCgroupPtr group, + unsigned long long kb); + +typedef int +(*virCgroupGetMemSwapHardLimitCB)(virCgroupPtr group, + unsigned long long *kb); + struct _virCgroupBackend { virCgroupBackendType type; @@ -269,6 +293,12 @@ struct _virCgroupBackend { virCgroupSetMemoryCB setMemory; virCgroupGetMemoryStatCB getMemoryStat; virCgroupGetMemoryUsageCB getMemoryUsage; + virCgroupSetMemoryHardLimitCB setMemoryHardLimit; + virCgroupGetMemoryHardLimitCB getMemoryHardLimit; + virCgroupSetMemorySoftLimitCB setMemorySoftLimit; + virCgroupGetMemorySoftLimitCB getMemorySoftLimit; + virCgroupSetMemSwapHardLimitCB setMemSwapHardLimit; + virCgroupGetMemSwapHardLimitCB getMemSwapHardLimit; }; typedef struct _virCgroupBackend virCgroupBackend; typedef virCgroupBackend *virCgroupBackendPtr; diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h index 3a968c1ce2..7b985280e1 100644 --- a/src/util/vircgrouppriv.h +++ b/src/util/vircgrouppriv.h @@ -88,6 +88,12 @@ int virCgroupGetValueForBlkDev(virCgroupPtr group, const char *path, char **value); +int virCgroupNew(pid_t pid, + const char *path, + virCgroupPtr parent, + int controllers, + virCgroupPtr *group); + int virCgroupNewPartition(const char *path, bool create, int controllers, diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c index 4f1d79a758..779288fb97 100644 --- a/src/util/vircgroupv1.c +++ b/src/util/vircgroupv1.c @@ -1378,6 +1378,51 @@ virCgroupV1GetBlkioDeviceWriteBps(virCgroupPtr group, } +/* + * Retrieve the "memory.limit_in_bytes" value from the memory controller + * root dir. This value cannot be modified by userspace and therefore + * is the maximum limit value supported by cgroups on the local system. + * Returns this value scaled to KB or falls back to the original + * VIR_DOMAIN_MEMORY_PARAM_UNLIMITED. Either way, remember the return + * value to avoid unnecessary cgroup filesystem access. + */ +static unsigned long long int virCgroupV1MemoryUnlimitedKB; +static virOnceControl virCgroupV1MemoryOnce = VIR_ONCE_CONTROL_INITIALIZER; + +static void +virCgroupV1MemoryOnceInit(void) +{ + virCgroupPtr group; + unsigned long long int mem_unlimited = 0ULL; + + if (virCgroupNew(-1, "/", NULL, -1, &group) < 0) + goto cleanup; + + if (!virCgroupV1HasController(group, VIR_CGROUP_CONTROLLER_MEMORY)) + goto cleanup; + + ignore_value(virCgroupGetValueU64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + "memory.limit_in_bytes", + &mem_unlimited)); + cleanup: + virCgroupFree(&group); + virCgroupV1MemoryUnlimitedKB = mem_unlimited >> 10; +} + +static unsigned long long int +virCgroupV1GetMemoryUnlimitedKB(void) +{ + if (virOnce(&virCgroupV1MemoryOnce, virCgroupV1MemoryOnceInit) < 0) + VIR_DEBUG("Init failed, will fall back to defaults."); + + if (virCgroupV1MemoryUnlimitedKB) + return virCgroupV1MemoryUnlimitedKB; + else + return VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; +} + + static int virCgroupV1SetMemory(virCgroupPtr group, unsigned long long kb) @@ -1494,6 +1539,123 @@ virCgroupV1GetMemoryUsage(virCgroupPtr group, } +static int +virCgroupV1SetMemoryHardLimit(virCgroupPtr group, + unsigned long long kb) +{ + return virCgroupV1SetMemory(group, kb); +} + + +static int +virCgroupV1GetMemoryHardLimit(virCgroupPtr group, + unsigned long long *kb) +{ + long long unsigned int limit_in_bytes; + + if (virCgroupGetValueU64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + "memory.limit_in_bytes", &limit_in_bytes) < 0) + return -1; + + *kb = limit_in_bytes >> 10; + if (*kb >= virCgroupV1GetMemoryUnlimitedKB()) + *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; + + return 0; +} + + +static int +virCgroupV1SetMemorySoftLimit(virCgroupPtr group, + unsigned long long kb) +{ + unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; + + if (kb > maxkb) { + virReportError(VIR_ERR_INVALID_ARG, + _("Memory '%llu' must be less than %llu"), + kb, maxkb); + return -1; + } + + if (kb == maxkb) + return virCgroupSetValueI64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + "memory.soft_limit_in_bytes", + -1); + else + return virCgroupSetValueU64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + "memory.soft_limit_in_bytes", + kb << 10); +} + + +static int +virCgroupV1GetMemorySoftLimit(virCgroupPtr group, + unsigned long long *kb) +{ + long long unsigned int limit_in_bytes; + + if (virCgroupGetValueU64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + "memory.soft_limit_in_bytes", &limit_in_bytes) < 0) + return -1; + + *kb = limit_in_bytes >> 10; + if (*kb >= virCgroupV1GetMemoryUnlimitedKB()) + *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; + + return 0; +} + + +static int +virCgroupV1SetMemSwapHardLimit(virCgroupPtr group, + unsigned long long kb) +{ + unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; + + if (kb > maxkb) { + virReportError(VIR_ERR_INVALID_ARG, + _("Memory '%llu' must be less than %llu"), + kb, maxkb); + return -1; + } + + if (kb == maxkb) + return virCgroupSetValueI64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + "memory.memsw.limit_in_bytes", + -1); + else + return virCgroupSetValueU64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + "memory.memsw.limit_in_bytes", + kb << 10); +} + + +static int +virCgroupV1GetMemSwapHardLimit(virCgroupPtr group, + unsigned long long *kb) +{ + long long unsigned int limit_in_bytes; + + if (virCgroupGetValueU64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + "memory.memsw.limit_in_bytes", &limit_in_bytes) < 0) + return -1; + + *kb = limit_in_bytes >> 10; + if (*kb >= virCgroupV1GetMemoryUnlimitedKB()) + *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; + + return 0; +} + + virCgroupBackend virCgroupV1Backend = { .type = VIR_CGROUP_BACKEND_TYPE_V1, @@ -1534,6 +1696,12 @@ virCgroupBackend virCgroupV1Backend = { .setMemory = virCgroupV1SetMemory, .getMemoryStat = virCgroupV1GetMemoryStat, .getMemoryUsage = virCgroupV1GetMemoryUsage, + .setMemoryHardLimit = virCgroupV1SetMemoryHardLimit, + .getMemoryHardLimit = virCgroupV1GetMemoryHardLimit, + .setMemorySoftLimit = virCgroupV1SetMemorySoftLimit, + .getMemorySoftLimit = virCgroupV1GetMemorySoftLimit, + .setMemSwapHardLimit = virCgroupV1SetMemSwapHardLimit, + .getMemSwapHardLimit = virCgroupV1GetMemSwapHardLimit, }; -- 2.22.0