From d43ffcac84400e539f54323fe6a4125022d4ffe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Koutn=C3=BD?= Date: Fri, 10 Dec 2021 17:44:19 +0100 Subject: [PATCH 1/3] core/cgroup: Provide information about applied BFQ scaling The BFQ weights are not passed verbatim to the kernel, provide that information in a form of debug message so that users are not surprised/confused when IOWeight != io.bfq.weight. --- src/core/cgroup.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index f58de95a49..07d53b2fb6 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1279,6 +1279,7 @@ assert_cc(BFQ_WEIGHT(10000) == 1000); static void set_io_weight(Unit *u, uint64_t weight) { char buf[STRLEN("default \n")+DECIMAL_STR_MAX(uint64_t)]; + uint64_t bfq_weight; assert(u); @@ -1286,8 +1287,11 @@ static void set_io_weight(Unit *u, uint64_t weight) { * See also: https://github.com/systemd/systemd/pull/13335 and * https://github.com/torvalds/linux/commit/65752aef0a407e1ef17ec78a7fc31ba4e0b360f9. * The range is 1..1000 apparently, and the default is 100. */ - xsprintf(buf, "%" PRIu64 "\n", BFQ_WEIGHT(weight)); - (void) set_attribute_and_warn(u, "io", "io.bfq.weight", buf); + bfq_weight = BFQ_WEIGHT(weight); + xsprintf(buf, "%" PRIu64 "\n", bfq_weight); + if (set_attribute_and_warn(u, "io", "io.bfq.weight", buf) >= 0 && weight != bfq_weight) + log_unit_debug(u, "IOWeight=%" PRIu64 " scaled to io.bfq.weight=%" PRIu64, + weight, bfq_weight); xsprintf(buf, "default %" PRIu64 "\n", weight); (void) set_attribute_and_warn(u, "io", "io.weight", buf); @@ -1295,12 +1299,16 @@ static void set_io_weight(Unit *u, uint64_t weight) { static void set_blkio_weight(Unit *u, uint64_t weight) { char buf[STRLEN("\n")+DECIMAL_STR_MAX(uint64_t)]; + uint64_t bfq_weight; assert(u); /* FIXME: see comment in set_io_weight(). */ - xsprintf(buf, "%" PRIu64 "\n", BFQ_WEIGHT(weight)); - (void) set_attribute_and_warn(u, "blkio", "blkio.bfq.weight", buf); + bfq_weight = BFQ_WEIGHT(weight); + xsprintf(buf, "%" PRIu64 "\n", bfq_weight); + if (set_attribute_and_warn(u, "blkio", "blkio.bfq.weight", buf) >= 0 && weight != bfq_weight) + log_unit_debug(u, "BlockIOWeight=%" PRIu64 " scaled to blkio.bfq.weight=%" PRIu64, + weight, bfq_weight); xsprintf(buf, "%" PRIu64 "\n", weight); (void) set_attribute_and_warn(u, "blkio", "blkio.weight", buf); From d2bd0bfa362a26a8cd6e1d68e5c485f129fbb379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Koutn=C3=BD?= Date: Fri, 10 Dec 2021 19:00:45 +0100 Subject: [PATCH 2/3] cgroup-util: Move macros to macros and tests to tests Friends to friends to be consistent with the other macros and make tests separate from main code. --- src/basic/cgroup-util.h | 14 ++++++++++++++ src/core/cgroup.c | 19 ------------------- src/test/test-cgroup-util.c | 9 +++++++++ 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index 21275e9eaa..461c01b3c2 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -127,6 +127,20 @@ static inline bool CGROUP_CPU_SHARES_IS_OK(uint64_t x) { (x >= CGROUP_CPU_SHARES_MIN && x <= CGROUP_CPU_SHARES_MAX); } +/* Special values for the special {blkio,io}.bfq.weight attribute */ +#define CGROUP_BFQ_WEIGHT_INVALID UINT64_MAX +#define CGROUP_BFQ_WEIGHT_MIN UINT64_C(1) +#define CGROUP_BFQ_WEIGHT_MAX UINT64_C(1000) +#define CGROUP_BFQ_WEIGHT_DEFAULT UINT64_C(100) + +/* Convert the normal io.weight value to io.bfq.weight */ +static inline uint64_t BFQ_WEIGHT(uint64_t io_weight) { + return + io_weight <= CGROUP_WEIGHT_DEFAULT ? + CGROUP_BFQ_WEIGHT_DEFAULT - (CGROUP_WEIGHT_DEFAULT - io_weight) * (CGROUP_BFQ_WEIGHT_DEFAULT - CGROUP_BFQ_WEIGHT_MIN) / (CGROUP_WEIGHT_DEFAULT - CGROUP_WEIGHT_MIN) : + CGROUP_BFQ_WEIGHT_DEFAULT + (io_weight - CGROUP_WEIGHT_DEFAULT) * (CGROUP_BFQ_WEIGHT_MAX - CGROUP_BFQ_WEIGHT_DEFAULT) / (CGROUP_WEIGHT_MAX - CGROUP_WEIGHT_DEFAULT); +} + /* Special values for the blkio.weight attribute */ #define CGROUP_BLKIO_WEIGHT_INVALID UINT64_MAX #define CGROUP_BLKIO_WEIGHT_MIN UINT64_C(10) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 07d53b2fb6..81147733a3 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -45,12 +45,6 @@ #define CGROUP_CPU_QUOTA_DEFAULT_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC) -/* Special values for the bfq.weight attribute */ -#define CGROUP_BFQ_WEIGHT_INVALID UINT64_MAX -#define CGROUP_BFQ_WEIGHT_MIN UINT64_C(1) -#define CGROUP_BFQ_WEIGHT_MAX UINT64_C(1000) -#define CGROUP_BFQ_WEIGHT_DEFAULT UINT64_C(100) - /* Returns the log level to use when cgroup attribute writes fail. When an attribute is missing or we have access * problems we downgrade to LOG_DEBUG. This is supposed to be nice to container managers and kernels which want to mask * out specific attributes from us. */ @@ -1264,19 +1258,6 @@ static int cgroup_apply_devices(Unit *u) { return r; } -/* Convert the normal io.weight value to io.bfq.weight */ -#define BFQ_WEIGHT(weight) \ - (weight <= CGROUP_WEIGHT_DEFAULT ? \ - CGROUP_BFQ_WEIGHT_DEFAULT - (CGROUP_WEIGHT_DEFAULT - weight) * (CGROUP_BFQ_WEIGHT_DEFAULT - CGROUP_BFQ_WEIGHT_MIN) / (CGROUP_WEIGHT_DEFAULT - CGROUP_WEIGHT_MIN) : \ - CGROUP_BFQ_WEIGHT_DEFAULT + (weight - CGROUP_WEIGHT_DEFAULT) * (CGROUP_BFQ_WEIGHT_MAX - CGROUP_BFQ_WEIGHT_DEFAULT) / (CGROUP_WEIGHT_MAX - CGROUP_WEIGHT_DEFAULT)) - -assert_cc(BFQ_WEIGHT(1) == 1); -assert_cc(BFQ_WEIGHT(50) == 50); -assert_cc(BFQ_WEIGHT(100) == 100); -assert_cc(BFQ_WEIGHT(500) == 136); -assert_cc(BFQ_WEIGHT(5000) == 545); -assert_cc(BFQ_WEIGHT(10000) == 1000); - static void set_io_weight(Unit *u, uint64_t weight) { char buf[STRLEN("default \n")+DECIMAL_STR_MAX(uint64_t)]; uint64_t bfq_weight; diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index 93b114b3fd..7113b07a95 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -426,4 +426,13 @@ TEST(cg_get_keyed_attribute) { } } +TEST(bfq_weight_conversion) { + assert_se(BFQ_WEIGHT(1) == 1); + assert_se(BFQ_WEIGHT(50) == 50); + assert_se(BFQ_WEIGHT(100) == 100); + assert_se(BFQ_WEIGHT(500) == 136); + assert_se(BFQ_WEIGHT(5000) == 545); + assert_se(BFQ_WEIGHT(10000) == 1000); +} + DEFINE_TEST_MAIN(LOG_DEBUG); From bec17e801a51a0e299315d6743372fa74b928d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Koutn=C3=BD?= Date: Fri, 10 Dec 2021 18:40:35 +0100 Subject: [PATCH 3/3] core/cgroup: Factor out BFQ weight setting No functional change. --- src/core/cgroup.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 81147733a3..316e8f571d 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1047,6 +1047,26 @@ static uint64_t cgroup_weight_io_to_blkio(uint64_t io_weight) { CGROUP_BLKIO_WEIGHT_MIN, CGROUP_BLKIO_WEIGHT_MAX); } +static void set_bfq_weight(Unit *u, const char *controller, uint64_t io_weight) { + char buf[DECIMAL_STR_MAX(uint64_t)+STRLEN("\n")]; + const char *p; + uint64_t bfq_weight; + + /* FIXME: drop this function when distro kernels properly support BFQ through "io.weight" + * See also: https://github.com/systemd/systemd/pull/13335 and + * https://github.com/torvalds/linux/commit/65752aef0a407e1ef17ec78a7fc31ba4e0b360f9. */ + p = strjoina(controller, ".bfq.weight"); + /* Adjust to kernel range is 1..1000, the default is 100. */ + bfq_weight = BFQ_WEIGHT(io_weight); + + xsprintf(buf, "%" PRIu64 "\n", bfq_weight); + + if (set_attribute_and_warn(u, controller, p, buf) >= 0 && io_weight != bfq_weight) + log_unit_debug(u, "%sIOWeight=%" PRIu64 " scaled to %s=%" PRIu64, + streq(controller, "blkio") ? "Block" : "", + io_weight, p, bfq_weight); +} + static void cgroup_apply_io_device_weight(Unit *u, const char *dev_path, uint64_t io_weight) { char buf[DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(uint64_t)+1]; dev_t dev; @@ -1260,19 +1280,10 @@ static int cgroup_apply_devices(Unit *u) { static void set_io_weight(Unit *u, uint64_t weight) { char buf[STRLEN("default \n")+DECIMAL_STR_MAX(uint64_t)]; - uint64_t bfq_weight; assert(u); - /* FIXME: drop this when distro kernels properly support BFQ through "io.weight" - * See also: https://github.com/systemd/systemd/pull/13335 and - * https://github.com/torvalds/linux/commit/65752aef0a407e1ef17ec78a7fc31ba4e0b360f9. - * The range is 1..1000 apparently, and the default is 100. */ - bfq_weight = BFQ_WEIGHT(weight); - xsprintf(buf, "%" PRIu64 "\n", bfq_weight); - if (set_attribute_and_warn(u, "io", "io.bfq.weight", buf) >= 0 && weight != bfq_weight) - log_unit_debug(u, "IOWeight=%" PRIu64 " scaled to io.bfq.weight=%" PRIu64, - weight, bfq_weight); + set_bfq_weight(u, "io", weight); xsprintf(buf, "default %" PRIu64 "\n", weight); (void) set_attribute_and_warn(u, "io", "io.weight", buf); @@ -1280,16 +1291,10 @@ static void set_io_weight(Unit *u, uint64_t weight) { static void set_blkio_weight(Unit *u, uint64_t weight) { char buf[STRLEN("\n")+DECIMAL_STR_MAX(uint64_t)]; - uint64_t bfq_weight; assert(u); - /* FIXME: see comment in set_io_weight(). */ - bfq_weight = BFQ_WEIGHT(weight); - xsprintf(buf, "%" PRIu64 "\n", bfq_weight); - if (set_attribute_and_warn(u, "blkio", "blkio.bfq.weight", buf) >= 0 && weight != bfq_weight) - log_unit_debug(u, "BlockIOWeight=%" PRIu64 " scaled to blkio.bfq.weight=%" PRIu64, - weight, bfq_weight); + set_bfq_weight(u, "blkio", weight); xsprintf(buf, "%" PRIu64 "\n", weight); (void) set_attribute_and_warn(u, "blkio", "blkio.weight", buf);