From 900c58b7f963d5054921e31bbd0b6005155b284a Mon Sep 17 00:00:00 2001 From: Pavel Hrdina Date: Fri, 17 Aug 2018 16:18:38 +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 --- 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 520904308f..f8bddc360d 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -630,7 +630,7 @@ virCgroupMakeGroup(virCgroupPtr parent, * * Returns 0 on success, -1 on error */ -static int +int virCgroupNew(pid_t pid, const char *path, virCgroupPtr parent, @@ -1533,51 +1533,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: * @@ -1648,7 +1603,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); } @@ -1663,18 +1618,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); } @@ -1689,25 +1633,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); } @@ -1722,18 +1648,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); } @@ -1748,25 +1663,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); } @@ -1781,18 +1678,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 0cd70cc512..17654f62d7 100644 --- a/src/util/vircgroupv1.c +++ b/src/util/vircgroupv1.c @@ -1377,6 +1377,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) @@ -1493,6 +1538,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, @@ -1533,6 +1695,12 @@ virCgroupBackend virCgroupV1Backend = { .setMemory = virCgroupV1SetMemory, .getMemoryStat = virCgroupV1GetMemoryStat, .getMemoryUsage = virCgroupV1GetMemoryUsage, + .setMemoryHardLimit = virCgroupV1SetMemoryHardLimit, + .getMemoryHardLimit = virCgroupV1GetMemoryHardLimit, + .setMemorySoftLimit = virCgroupV1SetMemorySoftLimit, + .getMemorySoftLimit = virCgroupV1GetMemorySoftLimit, + .setMemSwapHardLimit = virCgroupV1SetMemSwapHardLimit, + .getMemSwapHardLimit = virCgroupV1GetMemSwapHardLimit, }; -- GitLab