]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: add support for IOReadIOPSMax and IOWriteIOPSMax 3289/head
authorTejun Heo <htejun@fb.com>
Wed, 18 May 2016 20:50:56 +0000 (13:50 -0700)
committerTejun Heo <tj@kernel.org>
Wed, 18 May 2016 20:50:56 +0000 (13:50 -0700)
cgroup IO controller supports maximum limits for both bandwidth and IOPS but
systemd resource control currently only supports bandwidth limits.  This patch
adds support for IOReadIOPSMax and IOWriteIOPSMax when unified cgroup hierarchy
is in use.

It isn't difficult to also add BlockIOReadIOPS and BlockIOWriteIOPS for legacy
hierarchies but IO control on legacy hierarchies is half-broken anyway, so
let's leave it alone for now.

man/systemd.resource-control.xml
src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/core/cgroup.c
src/core/dbus-cgroup.c
src/core/load-fragment-gperf.gperf.m4

index 313a49a9595a74ace93fae8e41a2b1e2f2eed984..8a95e1196b8d332a6f250933d571db2e7933291a 100644 (file)
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>IOReadIOPSMax=<replaceable>device</replaceable> <replaceable>IOPS</replaceable></varname></term>
+        <term><varname>IOWriteIOPSMax=<replaceable>device</replaceable> <replaceable>IOPS</replaceable></varname></term>
+
+        <listitem>
+          <para>Set the per-device overall block I/O IOs-Per-Second maximum limit for the executed processes, if the
+          unified control group hierarchy is used on the system. This limit is not work-conserving and the executed
+          processes are not allowed to use more even if the device has idle capacity.  Takes a space-separated pair of
+          a file path and an IOPS value to specify the device specific IOPS. The file path may be a path to a block
+          device node, or as any other file in which case the backing block device of the file system of the file is
+          used. If the IOPS is suffixed with K, M, G, or T, the specified IOPS is parsed as KiloIOPS, MegaIOPS,
+          GigaIOPS, or TeraIOPS, respectively, to the base of 1000. (Example:
+          "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 1K"). This controls the <literal>io.max</literal> control
+          group attributes. Use this option multiple times to set IOPS limits for multiple devices. For details about
+          this control group attribute, see <ulink
+          url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.
+          </para>
+
+          <para>Implies <literal>IOAccounting=true</literal>.</para>
+
+          <para>This setting is supported only if the unified control group hierarchy is used.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>BlockIOAccounting=</varname></term>
 
index 8eab10074885fb0d7e72cd8661730839b443d922..7cdc97ee3cb8be7c56596b18e48061758b3311c8 100644 (file)
@@ -2272,11 +2272,15 @@ int cg_weight_parse(const char *s, uint64_t *ret) {
 const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX] = {
         [CGROUP_IO_RBPS_MAX]    = CGROUP_LIMIT_MAX,
         [CGROUP_IO_WBPS_MAX]    = CGROUP_LIMIT_MAX,
+        [CGROUP_IO_RIOPS_MAX]   = CGROUP_LIMIT_MAX,
+        [CGROUP_IO_WIOPS_MAX]   = CGROUP_LIMIT_MAX,
 };
 
 static const char* const cgroup_io_limit_type_table[_CGROUP_IO_LIMIT_TYPE_MAX] = {
         [CGROUP_IO_RBPS_MAX]    = "IOReadBandwidthMax",
         [CGROUP_IO_WBPS_MAX]    = "IOWriteBandwidthMax",
+        [CGROUP_IO_RIOPS_MAX]   = "IOReadIOPSMax",
+        [CGROUP_IO_WIOPS_MAX]   = "IOWriteIOPSMax",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(cgroup_io_limit_type, CGroupIOLimitType);
index 0d96fb6b76cf53860b07f41b2d30a026b3ea3fd3..4bb529129668d7f6394f04816ea95fe67aefe2fd 100644 (file)
@@ -76,6 +76,8 @@ static inline bool CGROUP_WEIGHT_IS_OK(uint64_t x) {
 typedef enum CGroupIOLimitType {
         CGROUP_IO_RBPS_MAX,
         CGROUP_IO_WBPS_MAX,
+        CGROUP_IO_RIOPS_MAX,
+        CGROUP_IO_WIOPS_MAX,
 
         _CGROUP_IO_LIMIT_TYPE_MAX,
         _CGROUP_IO_LIMIT_TYPE_INVALID = -1
index 0b902fa6f759527a9b1eb6a925dd2eefb98e7d03..a54634469f9957d4e29b1cce8b85f6d64e2cbb14 100644 (file)
@@ -439,7 +439,7 @@ void cgroup_context_apply(CGroupContext *c, CGroupMask mask, const char *path, M
 
                 LIST_FOREACH_SAFE(device_limits, l, next, c->io_device_limits) {
                         char limit_bufs[_CGROUP_IO_LIMIT_TYPE_MAX][DECIMAL_STR_MAX(uint64_t)];
-                        char buf[DECIMAL_STR_MAX(dev_t)*2+2+(5+DECIMAL_STR_MAX(uint64_t)+1)*2];
+                        char buf[DECIMAL_STR_MAX(dev_t)*2+2+(6+DECIMAL_STR_MAX(uint64_t)+1)*4];
                         CGroupIOLimitType type;
                         dev_t dev;
                         unsigned n = 0;
@@ -458,8 +458,9 @@ void cgroup_context_apply(CGroupContext *c, CGroupMask mask, const char *path, M
                                 }
                         }
 
-                        xsprintf(buf, "%u:%u rbps=%s wbps=%s\n", major(dev), minor(dev),
-                                 limit_bufs[CGROUP_IO_RBPS_MAX], limit_bufs[CGROUP_IO_WBPS_MAX]);
+                        xsprintf(buf, "%u:%u rbps=%s wbps=%s riops=%s wiops=%s\n", major(dev), minor(dev),
+                                 limit_bufs[CGROUP_IO_RBPS_MAX], limit_bufs[CGROUP_IO_WBPS_MAX],
+                                 limit_bufs[CGROUP_IO_RIOPS_MAX], limit_bufs[CGROUP_IO_WIOPS_MAX]);
                         r = cg_set_attribute("io", path, "io.max", buf);
                         if (r < 0)
                                 log_full_errno(IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
index 4372828e307946f8cfd3a6e6582eb22b33ccdbd4..29c2edaf6bcf5d19e8c9daa4a5cc8c5f2b93b772 100644 (file)
@@ -213,6 +213,8 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
         SD_BUS_PROPERTY("IODeviceWeight", "a(st)", property_get_io_device_weight, 0, 0),
         SD_BUS_PROPERTY("IOReadBandwidthMax", "a(st)", property_get_io_device_limits, 0, 0),
         SD_BUS_PROPERTY("IOWriteBandwidthMax", "a(st)", property_get_io_device_limits, 0, 0),
+        SD_BUS_PROPERTY("IOReadIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
+        SD_BUS_PROPERTY("IOWriteIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
         SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, blockio_accounting), 0),
         SD_BUS_PROPERTY("BlockIOWeight", "t", NULL, offsetof(CGroupContext, blockio_weight), 0),
         SD_BUS_PROPERTY("StartupBlockIOWeight", "t", NULL, offsetof(CGroupContext, startup_blockio_weight), 0),
index ad45611d9d72bf9d3a081091d592ed272ff86a05..819341898092d5ce39627d021442012e7c66f466 100644 (file)
@@ -126,6 +126,8 @@ $1.StartupIOWeight,              config_parse_io_weight,             0,
 $1.IODeviceWeight,               config_parse_io_device_weight,      0,                             offsetof($1, cgroup_context)
 $1.IOReadBandwidthMax,           config_parse_io_limit,              0,                             offsetof($1, cgroup_context)
 $1.IOWriteBandwidthMax,          config_parse_io_limit,              0,                             offsetof($1, cgroup_context)
+$1.IOReadIOPSMax,                config_parse_io_limit,              0,                             offsetof($1, cgroup_context)
+$1.IOWriteIOPSMax,               config_parse_io_limit,              0,                             offsetof($1, cgroup_context)
 $1.BlockIOAccounting,            config_parse_bool,                  0,                             offsetof($1, cgroup_context.blockio_accounting)
 $1.BlockIOWeight,                config_parse_blockio_weight,        0,                             offsetof($1, cgroup_context.blockio_weight)
 $1.StartupBlockIOWeight,         config_parse_blockio_weight,        0,                             offsetof($1, cgroup_context.startup_blockio_weight)