diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 5c2c9ed54e..f58de95a49 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -45,6 +45,12 @@ #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. */ @@ -1258,21 +1264,46 @@ static int cgroup_apply_devices(Unit *u) { return r; } -static void set_io_weight(Unit *u, const char *controller, uint64_t weight) { - char buf[8+DECIMAL_STR_MAX(uint64_t)+1]; - const char *p; +/* 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)) - p = strjoina(controller, ".weight"); - xsprintf(buf, "default %" PRIu64 "\n", weight); - (void) set_attribute_and_warn(u, controller, p, buf); +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)]; + + 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. */ - p = strjoina(controller, ".bfq.weight"); - xsprintf(buf, "%" PRIu64 "\n", (weight + 9) / 10); - (void) set_attribute_and_warn(u, controller, p, buf); + * 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); + + xsprintf(buf, "default %" PRIu64 "\n", weight); + (void) set_attribute_and_warn(u, "io", "io.weight", buf); +} + +static void set_blkio_weight(Unit *u, uint64_t weight) { + char buf[STRLEN("\n")+DECIMAL_STR_MAX(uint64_t)]; + + 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); + + xsprintf(buf, "%" PRIu64 "\n", weight); + (void) set_attribute_and_warn(u, "blkio", "blkio.weight", buf); } static void cgroup_apply_bpf_foreign_program(Unit *u) { @@ -1386,7 +1417,7 @@ static void cgroup_context_apply( } else weight = CGROUP_WEIGHT_DEFAULT; - set_io_weight(u, "io", weight); + set_io_weight(u, weight); if (has_io) { CGroupIODeviceLatency *latency; @@ -1456,7 +1487,7 @@ static void cgroup_context_apply( else weight = CGROUP_BLKIO_WEIGHT_DEFAULT; - set_io_weight(u, "blkio", weight); + set_blkio_weight(u, weight); if (has_io) { CGroupIODeviceWeight *w;