From: Michal Koutný Date: Fri, 10 Dec 2021 17:41:09 +0000 (+0100) Subject: core/cgroup: Apply IODeviceWeight= through BFQ attributes as well X-Git-Tag: v251-rc2~168^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9f0c0c4e158e835c7227dd677d6148607eece89d;p=thirdparty%2Fsystemd.git core/cgroup: Apply IODeviceWeight= through BFQ attributes as well There are two possible IO control mechanisms (io.cost and BFQ) that expose separate weights APIs. In systemd units we configure only a single device weight value so we need to write it to both attribute files. This patch extends to devices what is already done for default cgroup IO weight in commit 2dbc45aea747 ("cgroup: Also set io.bfq.weight"). This is possible with kernels >= v5.4 with commit 795fe54c2a82 ("bfq: Add per-device weight"). A warning is logged if the write fails on older kernels. Since per-device weight of a particular device cannot use both io.cost policy and BFQ scheduler, at least one warning is always expected with this approach (the method that is unconfigured). --- diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 42055e4e418..35edeac2adf 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1063,8 +1063,8 @@ 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")]; +static void set_bfq_weight(Unit *u, const char *controller, dev_t dev, uint64_t io_weight) { + char buf[DECIMAL_STR_MAX(dev_t)*2+2+DECIMAL_STR_MAX(uint64_t)+STRLEN("\n")]; const char *p; uint64_t bfq_weight; @@ -1075,11 +1075,15 @@ static void set_bfq_weight(Unit *u, const char *controller, uint64_t io_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 (major(dev) > 0) + xsprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), bfq_weight); + else + 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, + log_unit_debug(u, "%sIO%sWeight=%" PRIu64 " scaled to %s=%" PRIu64, streq(controller, "blkio") ? "Block" : "", + major(dev) > 0 ? "Device" : "", io_weight, p, bfq_weight); } @@ -1092,6 +1096,9 @@ static void cgroup_apply_io_device_weight(Unit *u, const char *dev_path, uint64_ if (r < 0) return; + /* BFQ per-device weights work since Linux kernel v5.4. */ + set_bfq_weight(u, "io", dev, io_weight); + xsprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), io_weight); (void) set_attribute_and_warn(u, "io", "io.weight", buf); } @@ -1298,7 +1305,7 @@ static void set_io_weight(Unit *u, uint64_t weight) { assert(u); - set_bfq_weight(u, "io", weight); + set_bfq_weight(u, "io", makedev(0, 0), weight); xsprintf(buf, "default %" PRIu64 "\n", weight); (void) set_attribute_and_warn(u, "io", "io.weight", buf); @@ -1309,7 +1316,7 @@ static void set_blkio_weight(Unit *u, uint64_t weight) { assert(u); - set_bfq_weight(u, "blkio", weight); + set_bfq_weight(u, "blkio", makedev(0, 0), weight); xsprintf(buf, "%" PRIu64 "\n", weight); (void) set_attribute_and_warn(u, "blkio", "blkio.weight", buf);