[PATCH v2 11/16] fs/resctrl: Add write handler for info/kernel_mode

Babu Moger
2026-03-12T20:38:57Z

Add resctrl_kernel_mode_write() so users can set the current kernel
mode by writing a mode name to info/kernel_mode. Unsupported or invalid
names are rejected; errors are reported in info/last_cmd_status.

Add rdtgroup_config_kmode() to assign or clear a group for kernel mode
(e.g. PLZA), and extend struct rdtgroup with a kmode flag. Update
Documentation/filesystems/resctrl.rst to describe the kernel_mode file.

Signed-off-by: Babu Moger <babu.moger@amd.com>
---
v2: New patch to handle PLZA interfaces with /sys/fs/resctrl/info/ directory.
https://lore.kernel.org/lkml/2ab556af-095b-422b-9396-f845c6fd0342@intel.com/
---
Documentation/filesystems/resctrl.rst | 34 +++++++++
fs/resctrl/internal.h | 2 +
fs/resctrl/rdtgroup.c | 101 +++++++++++++++++++++++++-
3 files changed, 136 insertions(+), 1 deletion(-)

diff --git a/Documentation/filesystems/resctrl.rst b/Documentation/filesystems/resctrl.rst
index ba609f8d4de5..2107dd4b3649 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -514,6 +514,40 @@ conveyed in the error returns from file operations. E.g.
# cat info/last_cmd_status
mask f7 has non-consecutive 1-bits

+"kernel_mode":
+ In the top level of the "info" directory, "kernel_mode" controls how
+ resource allocation and monitoring work in kernel mode. This is used on
+ some platforms to assign a dedicated CLOSID and/or RMID to kernel threads.
+
+ Reading the file lists supported kernel modes, one per line. The
+ currently active mode is shown in square brackets; other modes supported
+ by the platform are shown without brackets. Example::
+
+ # cat info/kernel_mode
+ [inherit_ctrl_and_mon]
+ global_assign_ctrl_inherit_mon
+ global_assign_ctrl_assign_mon
+
+ Writing a mode name (followed by a newline) sets the current kernel mode.
+ The name must match one of the supported mode names exactly. Modes not
+ supported by the platform (e.g. not advertised when reading the file)
+ cannot be set. Errors are reported in "info/last_cmd_status". Example::
+
+ # echo "global_assign_ctrl_assign_mon" > info/kernel_mode
+ # cat info/kernel_mode
+ inherit_ctrl_and_mon
+ global_assign_ctrl_inherit_mon
+ [global_assign_ctrl_assign_mon]
+
+ Modes:
+
+ - "inherit_ctrl_and_mon": Kernel uses the same CLOSID and RMID as the
+ current user-space task (default).
+ - "global_assign_ctrl_inherit_mon": One CLOSID is assigned for all
+ kernel work; RMID is still inherited from user space.
+ - "global_assign_ctrl_assign_mon": One resource group (CLOSID and RMID)
+ is assigned for all kernel work.
+
Resource alloc and monitor groups
=================================

diff --git a/fs/resctrl/internal.h b/fs/resctrl/internal.h
index 1a9b29119f88..b5999d8079d6 100644
--- a/fs/resctrl/internal.h
+++ b/fs/resctrl/internal.h
@@ -216,6 +216,7 @@ struct mongroup {
* @mon: mongroup related data
* @mode: mode of resource group
* @mba_mbps_event: input monitoring event id when mba_sc is enabled
+ * @kmode: true if this group is assigned for kernel mode (e.g. PLZA)
* @plr: pseudo-locked region
*/
struct rdtgroup {
@@ -229,6 +230,7 @@ struct rdtgroup {
struct mongroup mon;
enum rdtgrp_mode mode;
enum resctrl_event_id mba_mbps_event;
+ bool kmode;
struct pseudo_lock_region *plr;
};

diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index bb775afc78f5..6cd928fabaa2 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -1019,6 +1019,104 @@ static int resctrl_kernel_mode_show(struct kernfs_open_file *of,
return 0;
}

+/**
+ * rdtgroup_config_kmode() - Enable or disable kernel mode (e.g. PLZA) for a group
+ * @rdtgrp: The rdtgroup to assign or unassign for kernel work.
+ * @enable: True to assign this group for kernel mode; false to clear.
+ *
+ * Programs arch state via resctrl_arch_configure_kmode() and
+ * resctrl_arch_set_kmode(), and updates resctrl_kcfg.k_rdtgrp. Only one group
+ * may have kmode at a time. Pseudo-locked groups cannot be used for kernel mode.
+ *
+ * Return: 0 on success, or -EINVAL if the group is pseudo-locked.
+ */
+static int rdtgroup_config_kmode(struct rdtgroup *rdtgrp, bool enable)
+{
+ struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
+ u32 closid;
+
+ if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) {
+ rdt_last_cmd_puts("Resource group is pseudo-locked\n");
+ return -EINVAL;
+ }
+
+ if (rdtgrp->type == RDTMON_GROUP)
+ closid = rdtgrp->mon.parent->closid;
+ else
+ closid = rdtgrp->closid;
+
+ resctrl_arch_configure_kmode(r, &resctrl_kcfg, closid, rdtgrp->mon.rmid);
+
+ resctrl_arch_set_kmode(&rdtgrp->cpu_mask, &resctrl_kcfg, closid,
+ rdtgrp->mon.rmid, enable);
+ rdtgrp->kmode = enable;
+ if (enable)
+ resctrl_kcfg.k_rdtgrp = rdtgrp;
+ else
+ resctrl_kcfg.k_rdtgrp = NULL;
+
+ return 0;
+}
+
+/**
+ * resctrl_kernel_mode_write() - Set current kernel mode via info/kernel_mode
+ * @of: kernfs file handle.
+ * @buf: Mode name string (e.g. "inherit_ctrl_and_mon"); must end with newline.
+ * @nbytes: Length of buf.
+ * @off: File offset (unused).
+ *
+ * Accepts one of the names in kmodes[]. The mode must be supported by the
+ * platform (resctrl_kcfg.kmode). On success updates resctrl_kcfg.kmode_cur.
+ * Errors are reported in last_cmd_status.
+ *
+ * Return: nbytes on success, or -EINVAL with last_cmd_status set on error.
+ */
+static ssize_t resctrl_kernel_mode_write(struct kernfs_open_file *of,
+ char *buf, size_t nbytes, loff_t off)
+{
+ int ret = 0;
+ u32 kmode;
+ int i;
+
+ if (nbytes == 0 || buf[nbytes - 1] != '\n')
+ return -EINVAL;
+ buf[nbytes - 1] = '\0';
+
+ mutex_lock(&rdtgroup_mutex);
+ rdt_last_cmd_clear();
+
+ for (i = 0; i < RESCTRL_KERNEL_MODES_NUM; i++) {
+ if (strcmp(buf, kmodes[i].name) != 0)
+ continue;
+ /* Mode name matched; reject if not supported by this platform. */
+ if (!(resctrl_kcfg.kmode & kmodes[i].val)) {
+ rdt_last_cmd_puts("Kernel mode not available\n");
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+ if (resctrl_kcfg.kmode_cur != kmodes[i].val) {
+ kmode = resctrl_kcfg.kmode_cur;
+ resctrl_kcfg.kmode_cur = kmodes[i].val;
+ if (resctrl_kcfg.k_rdtgrp) {
+ ret = rdtgroup_config_kmode(resctrl_kcfg.k_rdtgrp, true);
+ if (ret) {
+ /* Revert to the previous mode. */
+ resctrl_kcfg.kmode_cur = kmode;
+ rdt_last_cmd_puts("Kernel mode change failed\n");
+ }
+ }
+ goto out_unlock;
+ }
+ }
+
+ rdt_last_cmd_puts("Unknown or unsupported kernel mode\n");
+ ret = -EINVAL;
+
+out_unlock:
+ mutex_unlock(&rdtgroup_mutex);
+ return ret ?: nbytes;
+}
+
void *rdt_kn_parent_priv(struct kernfs_node *kn)
{
/*
@@ -1922,9 +2020,10 @@ static struct rftype res_common_files[] = {
},
{
.name = "kernel_mode",
- .mode = 0444,
+ .mode = 0644,
.kf_ops = &rdtgroup_kf_single_ops,
.seq_show = resctrl_kernel_mode_show,
+ .write = resctrl_kernel_mode_write,
.fflags = RFTYPE_TOP_INFO,
},
{
--
2.43.0