|
|
c401cc |
From 47820a97323309465ebc3dd39a4dc74bd955a775 Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <47820a97323309465ebc3dd39a4dc74bd955a775.1386932211.git.jdenemar@redhat.com>
|
|
|
c401cc |
From: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c401cc |
Date: Tue, 10 Dec 2013 10:03:55 +0100
|
|
|
c401cc |
Subject: [PATCH] cgroups: Redefine what "unlimited" means wrt memory limits
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1024272
|
|
|
c401cc |
|
|
|
c401cc |
Since kernel 3.12 (commit 34ff8dc08956098563989d8599840b130be81252 in
|
|
|
c401cc |
linux-stable.git in particular) the value for 'unlimited' in cgroup
|
|
|
c401cc |
memory limits changed from LLONG_MAX to ULLONG_MAX. Due to rather
|
|
|
c401cc |
unfortunate choice of our VIR_DOMAIN_MEMORY_PARAM_UNLIMITED constant
|
|
|
c401cc |
(which we transfer as an unsigned long long in Kibibytes), we ended up
|
|
|
c401cc |
with the situation described below (applies to x86_64):
|
|
|
c401cc |
|
|
|
c401cc |
- 2^64-1 (ULLONG_MAX) -- "unlimited" in kernel = 3.12
|
|
|
c401cc |
|
|
|
c401cc |
- 2^63-1 (LLONG_MAX) -- "unlimited" in kernel < 3.12
|
|
|
c401cc |
- 2^63-1024 -- our PARAM_UNLIMITED scaled to Bytes
|
|
|
c401cc |
|
|
|
c401cc |
- 2^53-1 -- our PARAM_UNLIMITED unscaled (in Kibibytes)
|
|
|
c401cc |
|
|
|
c401cc |
This means that when any number within (2^63-1, 2^64-1] is read from
|
|
|
c401cc |
memory cgroup, we are transferring that number instead of "unlimited".
|
|
|
c401cc |
Unfortunately, changing VIR_DOMAIN_MEMORY_PARAM_UNLIMITED would break
|
|
|
c401cc |
ABI compatibility and thus we have to resort to a different solution.
|
|
|
c401cc |
|
|
|
c401cc |
With this patch every value greater than PARAM_UNLIMITED means
|
|
|
c401cc |
"unlimited". Even though this may seem misleading, we are already in
|
|
|
c401cc |
such unclear situation when running 3.12 kernel with memory limits set
|
|
|
c401cc |
to 2^63.
|
|
|
c401cc |
|
|
|
c401cc |
One example showing most of the problems at once (with kernel 3.12.2):
|
|
|
c401cc |
# virsh memtune asdf --hard-limit 9007199254740991 --swap-hard-limit -1
|
|
|
c401cc |
# echo 12345678901234567890 >\
|
|
|
c401cc |
/sys/fs/cgroup/memory/machine/asdf.libvirt-qemu/memory.soft_limit_in_bytes
|
|
|
c401cc |
# virsh memtune asdf
|
|
|
c401cc |
hard_limit : 18014398509481983
|
|
|
c401cc |
soft_limit : 12056327051986884
|
|
|
c401cc |
swap_hard_limit: 18014398509481983
|
|
|
c401cc |
|
|
|
c401cc |
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c401cc |
(cherry picked from commit 231656bbeb9e4d3bedc44362784c35eee21cf0f4)
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
src/util/vircgroup.c | 57 +++++++++++++++++++++++++++++++++++-----------------
|
|
|
c401cc |
1 file changed, 39 insertions(+), 18 deletions(-)
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
|
|
|
c401cc |
index cfb4b3f..ed53dff 100644
|
|
|
c401cc |
--- a/src/util/vircgroup.c
|
|
|
c401cc |
+++ b/src/util/vircgroup.c
|
|
|
c401cc |
@@ -2069,12 +2069,19 @@ int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb)
|
|
|
c401cc |
int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb)
|
|
|
c401cc |
{
|
|
|
c401cc |
long long unsigned int limit_in_bytes;
|
|
|
c401cc |
- int ret;
|
|
|
c401cc |
- ret = virCgroupGetValueU64(group,
|
|
|
c401cc |
- VIR_CGROUP_CONTROLLER_MEMORY,
|
|
|
c401cc |
- "memory.limit_in_bytes", &limit_in_bytes);
|
|
|
c401cc |
- if (ret == 0)
|
|
|
c401cc |
- *kb = limit_in_bytes >> 10;
|
|
|
c401cc |
+ int ret = -1;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (virCgroupGetValueU64(group,
|
|
|
c401cc |
+ VIR_CGROUP_CONTROLLER_MEMORY,
|
|
|
c401cc |
+ "memory.limit_in_bytes", &limit_in_bytes) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ *kb = limit_in_bytes >> 10;
|
|
|
c401cc |
+ if (*kb > VIR_DOMAIN_MEMORY_PARAM_UNLIMITED)
|
|
|
c401cc |
+ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ ret = 0;
|
|
|
c401cc |
+ cleanup:
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
@@ -2121,12 +2128,19 @@ int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb)
|
|
|
c401cc |
int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb)
|
|
|
c401cc |
{
|
|
|
c401cc |
long long unsigned int limit_in_bytes;
|
|
|
c401cc |
- int ret;
|
|
|
c401cc |
- ret = virCgroupGetValueU64(group,
|
|
|
c401cc |
- VIR_CGROUP_CONTROLLER_MEMORY,
|
|
|
c401cc |
- "memory.soft_limit_in_bytes", &limit_in_bytes);
|
|
|
c401cc |
- if (ret == 0)
|
|
|
c401cc |
- *kb = limit_in_bytes >> 10;
|
|
|
c401cc |
+ int ret = -1;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (virCgroupGetValueU64(group,
|
|
|
c401cc |
+ VIR_CGROUP_CONTROLLER_MEMORY,
|
|
|
c401cc |
+ "memory.soft_limit_in_bytes", &limit_in_bytes) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ *kb = limit_in_bytes >> 10;
|
|
|
c401cc |
+ if (*kb > VIR_DOMAIN_MEMORY_PARAM_UNLIMITED)
|
|
|
c401cc |
+ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ ret = 0;
|
|
|
c401cc |
+ cleanup:
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
@@ -2172,12 +2186,19 @@ int virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb)
|
|
|
c401cc |
int virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb)
|
|
|
c401cc |
{
|
|
|
c401cc |
long long unsigned int limit_in_bytes;
|
|
|
c401cc |
- int ret;
|
|
|
c401cc |
- ret = virCgroupGetValueU64(group,
|
|
|
c401cc |
- VIR_CGROUP_CONTROLLER_MEMORY,
|
|
|
c401cc |
- "memory.memsw.limit_in_bytes", &limit_in_bytes);
|
|
|
c401cc |
- if (ret == 0)
|
|
|
c401cc |
- *kb = limit_in_bytes >> 10;
|
|
|
c401cc |
+ int ret = -1;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (virCgroupGetValueU64(group,
|
|
|
c401cc |
+ VIR_CGROUP_CONTROLLER_MEMORY,
|
|
|
c401cc |
+ "memory.memsw.limit_in_bytes", &limit_in_bytes) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ *kb = limit_in_bytes >> 10;
|
|
|
c401cc |
+ if (*kb > VIR_DOMAIN_MEMORY_PARAM_UNLIMITED)
|
|
|
c401cc |
+ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ ret = 0;
|
|
|
c401cc |
+ cleanup:
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
--
|
|
|
c401cc |
1.8.5.1
|
|
|
c401cc |
|