]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/cgroup: Silence IODeviceWeight= exclusive policy warnings 21795/head
authorMichal Koutný <mkoutny@suse.com>
Wed, 23 Mar 2022 18:02:06 +0000 (19:02 +0100)
committerMichal Koutný <mkoutny@suse.com>
Tue, 29 Mar 2022 16:06:40 +0000 (18:06 +0200)
A single device cannot have more than a single proportional control
policy at the same time. So either io.bfq.weight or io.weight will
always fail. Process the resulting values and emit a warning message
only when none was really configured.

This patch also drops warnings when setting [blk]io.bfq.weight fails,
the code would be too convoluted otherwise.

src/core/cgroup.c

index f1d5fda69b016f737849c7af7ed48f00ae6b5212..c4e078d78e6861933a4c94aadcf825e94b3b3b02 100644 (file)
@@ -1063,7 +1063,7 @@ 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, dev_t dev, uint64_t io_weight) {
+static int set_bfq_weight(Unit *u, const char *controller, dev_t dev, uint64_t io_weight) {
         static const char * const prop_names[] = {
                 "IOWeight",
                 "BlockIOWeight",
@@ -1094,34 +1094,39 @@ static void set_bfq_weight(Unit *u, const char *controller, dev_t dev, uint64_t
          * 795fe54c2a82 ("bfq: Add per-device weight") v5.4
          * are not interesting anymore. Old kernels will fail with EINVAL, while new kernels won't return
          * EINVAL on properly formatted input by us. Treat EINVAL accordingly. */
-        if (r == -EINVAL && major(dev) > 0 && !warned) {
-               log_unit_warning(u, "Kernel version does not accept per-device setting in %s.", p);
-               warned = true;
-        }
-        if (r < 0)
-                log_unit_full_errno(u, r == -EINVAL ? LOG_DEBUG : LOG_LEVEL_CGROUP_WRITE(r),
-                                    r, "Failed to set '%s' attribute on '%s' to '%.*s': %m",
-                                    p, empty_to_root(u->cgroup_path), (int) strcspn(buf, NEWLINE), buf);
-        else if (io_weight != bfq_weight)
+        if (r == -EINVAL && major(dev) > 0) {
+               if (!warned) {
+                        log_unit_warning(u, "Kernel version does not accept per-device setting in %s.", p);
+                        warned = true;
+               }
+               r = -EOPNOTSUPP; /* mask as unconfigured device */
+        } else if (r >= 0 && io_weight != bfq_weight)
                 log_unit_debug(u, "%s=%" PRIu64 " scaled to %s=%" PRIu64,
                                prop_names[2*(major(dev) > 0) + streq(controller, "blkio")],
                                io_weight, p, bfq_weight);
+        return r;
 }
 
 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;
-        int r;
+        int r, r1, r2;
 
-        r = lookup_block_device(dev_path, &dev);
-        if (r < 0)
+        if (lookup_block_device(dev_path, &dev) < 0)
                 return;
 
-        /* BFQ per-device weights work since Linux kernel v5.4. */
-        set_bfq_weight(u, "io", dev, io_weight);
+        r1 = 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);
+        r2 = cg_set_attribute("io", u->cgroup_path, "io.weight", buf);
+
+        /* Look at the configured device, when both fail, prefer io.weight errno. */
+        r = r2 == -EOPNOTSUPP ? r1 : r2;
+
+        if (r < 0)
+                log_unit_full_errno(u, LOG_LEVEL_CGROUP_WRITE(r),
+                                    r, "Failed to set 'io[.bfq].weight' attribute on '%s' to '%.*s': %m",
+                                    empty_to_root(u->cgroup_path), (int) strcspn(buf, NEWLINE), buf);
 }
 
 static void cgroup_apply_blkio_device_weight(Unit *u, const char *dev_path, uint64_t blkio_weight) {
@@ -1326,7 +1331,7 @@ static void set_io_weight(Unit *u, uint64_t weight) {
 
         assert(u);
 
-        set_bfq_weight(u, "io", makedev(0, 0), weight);
+        (void) 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);
@@ -1337,7 +1342,7 @@ static void set_blkio_weight(Unit *u, uint64_t weight) {
 
         assert(u);
 
-        set_bfq_weight(u, "blkio", makedev(0, 0), weight);
+        (void) set_bfq_weight(u, "blkio", makedev(0, 0), weight);
 
         xsprintf(buf, "%" PRIu64 "\n", weight);
         (void) set_attribute_and_warn(u, "blkio", "blkio.weight", buf);