Skip to content

Commit b9a0fde

Browse files
authored
Merge pull request #1767 from giuseppe/change-formula-cpu-shares-conversion
cgroup: change conversion from CPU shares to weight
2 parents c3bfab0 + 72e5468 commit b9a0fde

File tree

6 files changed

+81
-23
lines changed

6 files changed

+81
-23
lines changed

configure.ac

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,41 @@ AS_IF([test "x$enable_criu" != "xno"], [
269269
270270
], [AC_MSG_NOTICE([CRIU support disabled per user request])])
271271

272+
AC_MSG_CHECKING([for log2])
273+
AC_LINK_IFELSE([
274+
AC_LANG_PROGRAM([
275+
#include <math.h>
276+
#include <stdlib.h>
277+
], [
278+
double result = log2 ((double) rand ());
279+
return (int) result;
280+
])
281+
], [
282+
# log2 works without -lm (musl libc)
283+
AC_MSG_RESULT([yes])
284+
AC_DEFINE([HAVE_LOG2], [1], [Define if log2 is available])
285+
], [
286+
# Try with -lm (glibc)
287+
LIBS="$LIBS -lm"
288+
AC_LINK_IFELSE([
289+
AC_LANG_PROGRAM([
290+
#include <math.h>
291+
#include <stdlib.h>
292+
], [
293+
double result = log2 ((double) rand ());
294+
return (int) result;
295+
])
296+
], [
297+
# log2 works with -lm
298+
AC_MSG_RESULT([yes (with -lm)])
299+
AC_DEFINE([HAVE_LOG2], [1], [Define if log2 is available])
300+
], [
301+
# log2 not available - restore LIBS and fail
302+
AC_MSG_RESULT([no])
303+
AC_MSG_ERROR([*** log2 function is required but not found])
304+
])
305+
])
306+
272307
FOUND_LIBS=$LIBS
273308
LIBS=""
274309

crun.1

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,10 @@ allbox;
846846
l l l l
847847
l l l l .
848848
\fBOCI (x)\fP \fBcgroup 2 value (y)\fP \fBconversion\fP \fBcomment\fP
849-
shares cpu.weight y = (1 + ((x - 2) * 9999) / 262142) T{
849+
shares cpu.weight T{
850+
y=10^((log2(x)^2 + 125 * log2(x)) / 612.0 - 7.0 / 34.0)
851+
T}
852+
T{
850853
convert from [2-262144] to [1-10000]
851854
T}
852855
period cpu.max y = x T{

crun.1.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -712,11 +712,11 @@ they are converted when needed from the cgroup v1 configuration.
712712

713713
## CPU controller
714714

715-
| OCI (x) | cgroup 2 value (y) | conversion | comment |
716-
|---|---|---|---|
717-
| shares | cpu.weight | y = (1 + ((x - 2) \* 9999) / 262142) | convert from [2-262144] to [1-10000]|
718-
| period | cpu.max | y = x| period and quota are written together|
719-
| quota | cpu.max | y = x| period and quota are written together|
715+
| OCI (x) | cgroup 2 value (y) | conversion | comment |
716+
|---------|--------------------|---------------------------------------------------------|---------------------------------------|
717+
| shares | cpu.weight | y=10^((log2(x)^2 + 125 * log2(x)) / 612.0 - 7.0 / 34.0) | convert from [2-262144] to [1-10000] |
718+
| period | cpu.max | y = x | period and quota are written together |
719+
| quota | cpu.max | y = x | period and quota are written together |
720720

721721
## blkio controller
722722

src/libcrun/cgroup-internal.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#include "container.h"
2222
#include "utils.h"
2323

24+
#include <stdint.h>
25+
#include <math.h>
26+
2427
enum
2528
{
2629
CGROUP_MEMORY = 1 << 0,
@@ -76,8 +79,22 @@ int libcrun_cgroup_pause_unpause_path (const char *cgroup_path, const bool pause
7679
static inline uint64_t
7780
convert_shares_to_weight (uint64_t shares)
7881
{
79-
/* convert linearly from 2-262144 to 1-10000. */
80-
return (1 + ((shares - 2) * 9999) / 262142);
82+
double l, exponent;
83+
84+
/* The value of 0 means "unset". */
85+
if (shares == 0)
86+
return 0;
87+
if (shares <= 2)
88+
return 1;
89+
if (shares >= 262144)
90+
return 10000;
91+
92+
l = log2 ((double) shares);
93+
94+
/* Quadratic function which fits min, max, and default. */
95+
exponent = (l * l + 125 * l) / 612.0 - 7.0 / 34.0;
96+
97+
return (uint64_t) ceil (pow (10, exponent));
8198
}
8299

83100
int initialize_cpuset_subsystem (const char *path, libcrun_error_t *err);

tests/alpine-build/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
FROM alpine
22

33
RUN apk add gcc automake autoconf libtool gettext pkgconf git make musl-dev \
4-
python3 libcap-dev libseccomp-dev yajl-dev argp-standalone go-md2man
4+
python3 libcap-dev libseccomp-dev yajl-dev argp-standalone go-md2man gperf
55

66
COPY run-tests.sh /usr/local/bin
77

tests/test_resources.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -291,23 +291,26 @@ def test_resources_cpu_weight_systemd():
291291
sys.stderr.write("# found wrong CPUWeight for the systemd scope\n")
292292
return 1
293293

294-
run_crun_command(['update', '--cpu-share', '4321', cid])
295-
# this is the expected cpu weight after the conversion from the CPUShares
296-
expected_weight = "165"
294+
for values in [(2, 1), (3, 2), (1024, 100), (260000, 9929), (262144, 10000)]:
295+
cpu_shares = values[0]
296+
# this is the expected cpu weight after the conversion from the CPUShares
297+
expected_weight = str(values[1])
297298

298-
out = run_crun_command(["exec", cid, "/init", "cat", "/sys/fs/cgroup/cpu.weight"])
299-
if expected_weight not in out:
300-
sys.stderr.write("# found wrong CPUWeight %s for the container cgroup\n" % out)
301-
return -1
299+
run_crun_command(['update', '--cpu-share', str(cpu_shares), cid])
302300

303-
out = subprocess.check_output(['systemctl', 'show','-PCPUWeight', scope ], close_fds=False).decode().strip()
304-
# as above
305-
if out != expected_weight:
306-
out = subprocess.check_output(['systemctl', '--user', 'show','-PCPUWeight', scope ], close_fds=False).decode().strip()
301+
out = run_crun_command(["exec", cid, "/init", "cat", "/sys/fs/cgroup/cpu.weight"])
302+
if expected_weight not in out:
303+
sys.stderr.write("found wrong CPUWeight %s instead of %s for the container cgroup\n" % (out, expected_weight))
304+
return -1
307305

308-
if out != expected_weight:
309-
sys.stderr.write("# found wrong CPUWeight for the systemd scope\n")
310-
return 1
306+
out = subprocess.check_output(['systemctl', 'show','-PCPUWeight', scope ], close_fds=False).decode().strip()
307+
# as above
308+
if out != expected_weight:
309+
out = subprocess.check_output(['systemctl', '--user', 'show','-PCPUWeight', scope ], close_fds=False).decode().strip()
310+
311+
if out != expected_weight:
312+
sys.stderr.write("found wrong CPUWeight for the systemd scope\n")
313+
return 1
311314
finally:
312315
if cid is not None:
313316
run_crun_command(["delete", "-f", cid])

0 commit comments

Comments
 (0)