]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fs/resctrl: Introduce interface to modify io_alloc capacity bitmasks
authorBabu Moger <babu.moger@amd.com>
Thu, 13 Nov 2025 00:57:35 +0000 (18:57 -0600)
committerBorislav Petkov (AMD) <bp@alien8.de>
Sat, 22 Nov 2025 13:28:31 +0000 (14:28 +0100)
The io_alloc feature in resctrl enables system software to configure the
portion of the cache allocated for I/O traffic. When supported, the
io_alloc_cbm file in resctrl provides access to capacity bitmasks (CBMs)
allocated for I/O devices.

Enable users to modify io_alloc CBMs by writing to the io_alloc_cbm resctrl
file when the io_alloc feature is enabled.

Mirror the CBMs between CDP_CODE and CDP_DATA when CDP is enabled to present
consistent I/O allocation information to user space.

Signed-off-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Link: https://patch.msgid.link/67609641b03ccfba18a8ee0bf9dbd1f3dcbecda3.1762995456.git.babu.moger@amd.com
Documentation/filesystems/resctrl.rst
fs/resctrl/ctrlmondata.c
fs/resctrl/internal.h
fs/resctrl/rdtgroup.c

index e7994538e0cef74e33123c296adeef369a288ae6..bbc4b6cbb71dce4036095409448476bb5005a947 100644 (file)
@@ -196,6 +196,18 @@ related to allocation:
                        # cat /sys/fs/resctrl/info/L3/io_alloc_cbm
                        0=ffff;1=ffff
 
+               CBMs can be configured by writing to the interface.
+
+               Example::
+
+                       # echo 1=ff > /sys/fs/resctrl/info/L3/io_alloc_cbm
+                       # cat /sys/fs/resctrl/info/L3/io_alloc_cbm
+                       0=ffff;1=00ff
+
+                       # echo "0=ff;1=f" > /sys/fs/resctrl/info/L3/io_alloc_cbm
+                       # cat /sys/fs/resctrl/info/L3/io_alloc_cbm
+                       0=00ff;1=000f
+
                When CDP is enabled "io_alloc_cbm" associated with the CDP_DATA and CDP_CODE
                resources may reflect the same values. For example, values read from and
                written to /sys/fs/resctrl/info/L3DATA/io_alloc_cbm may be reflected by
index c43bedea70d7a1357128afb3a13d8d6c94e8e196..332918fc961a3d7475d2c5225d4a688d8b128cc9 100644 (file)
@@ -864,3 +864,96 @@ out_unlock:
        cpus_read_unlock();
        return ret;
 }
+
+static int resctrl_io_alloc_parse_line(char *line,  struct rdt_resource *r,
+                                      struct resctrl_schema *s, u32 closid)
+{
+       enum resctrl_conf_type peer_type;
+       struct rdt_parse_data data;
+       struct rdt_ctrl_domain *d;
+       char *dom = NULL, *id;
+       unsigned long dom_id;
+
+next:
+       if (!line || line[0] == '\0')
+               return 0;
+
+       dom = strsep(&line, ";");
+       id = strsep(&dom, "=");
+       if (!dom || kstrtoul(id, 10, &dom_id)) {
+               rdt_last_cmd_puts("Missing '=' or non-numeric domain\n");
+               return -EINVAL;
+       }
+
+       dom = strim(dom);
+       list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
+               if (d->hdr.id == dom_id) {
+                       data.buf = dom;
+                       data.mode = RDT_MODE_SHAREABLE;
+                       data.closid = closid;
+                       if (parse_cbm(&data, s, d))
+                               return -EINVAL;
+                       /*
+                        * Keep io_alloc CLOSID's CBM of CDP_CODE and CDP_DATA
+                        * in sync.
+                        */
+                       if (resctrl_arch_get_cdp_enabled(r->rid)) {
+                               peer_type = resctrl_peer_type(s->conf_type);
+                               memcpy(&d->staged_config[peer_type],
+                                      &d->staged_config[s->conf_type],
+                                      sizeof(d->staged_config[0]));
+                       }
+                       goto next;
+               }
+       }
+
+       return -EINVAL;
+}
+
+ssize_t resctrl_io_alloc_cbm_write(struct kernfs_open_file *of, char *buf,
+                                  size_t nbytes, loff_t off)
+{
+       struct resctrl_schema *s = rdt_kn_parent_priv(of->kn);
+       struct rdt_resource *r = s->res;
+       u32 io_alloc_closid;
+       int ret = 0;
+
+       /* Valid input requires a trailing newline */
+       if (nbytes == 0 || buf[nbytes - 1] != '\n')
+               return -EINVAL;
+
+       buf[nbytes - 1] = '\0';
+
+       cpus_read_lock();
+       mutex_lock(&rdtgroup_mutex);
+       rdt_last_cmd_clear();
+
+       if (!r->cache.io_alloc_capable) {
+               rdt_last_cmd_printf("io_alloc is not supported on %s\n", s->name);
+               ret = -ENODEV;
+               goto out_unlock;
+       }
+
+       if (!resctrl_arch_get_io_alloc_enabled(r)) {
+               rdt_last_cmd_printf("io_alloc is not enabled on %s\n", s->name);
+               ret = -EINVAL;
+               goto out_unlock;
+       }
+
+       io_alloc_closid = resctrl_io_alloc_closid(r);
+
+       rdt_staged_configs_clear();
+       ret = resctrl_io_alloc_parse_line(buf, r, s, io_alloc_closid);
+       if (ret)
+               goto out_clear_configs;
+
+       ret = resctrl_arch_update_domains(r, io_alloc_closid);
+
+out_clear_configs:
+       rdt_staged_configs_clear();
+out_unlock:
+       mutex_unlock(&rdtgroup_mutex);
+       cpus_read_unlock();
+
+       return ret ?: nbytes;
+}
index 779a575e08282c283ed0b20784558bf37c994cce..e1eda74881a9a5343866a3505afa8f582dc49162 100644 (file)
@@ -440,6 +440,8 @@ ssize_t resctrl_io_alloc_write(struct kernfs_open_file *of, char *buf,
 const char *rdtgroup_name_by_closid(u32 closid);
 int resctrl_io_alloc_cbm_show(struct kernfs_open_file *of, struct seq_file *seq,
                              void *v);
+ssize_t resctrl_io_alloc_cbm_write(struct kernfs_open_file *of, char *buf,
+                                  size_t nbytes, loff_t off);
 
 #ifdef CONFIG_RESCTRL_FS_PSEUDO_LOCK
 int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp);
index ac326db9b5ba09924d8453dc42f3be92ca76dca2..361497489d875cd6b544dc6c1e3c710e5f3324aa 100644 (file)
@@ -1973,9 +1973,10 @@ static struct rftype res_common_files[] = {
        },
        {
                .name           = "io_alloc_cbm",
-               .mode           = 0444,
+               .mode           = 0644,
                .kf_ops         = &rdtgroup_kf_single_ops,
                .seq_show       = resctrl_io_alloc_cbm_show,
+               .write          = resctrl_io_alloc_cbm_write,
        },
        {
                .name           = "max_threshold_occupancy",