[PATCH v6 09/18] fs/resctrl: Add interface to display kernel mode status

From: Babu Moger

Date: Thu Oct 01 2026 - 11:19:21 EST


Resctrl kernel modes control how allocation and monitoring associations
are applied in kernel mode relative to user mode.

Add info/kernel_mode to expose the supported and active kernel modes via
the resctrl filesystem. Supported modes are listed one per line, with the
active mode enclosed in square brackets.

Document the interface in Documentation/filesystems/resctrl.rst.

Signed-off-by: Babu Moger <babu.moger@xxxxxxx>
---
v6: Rewrote the changelog to make it as feature and not as a bug fix.
Update the code to use the new name "global_enable_per_cpu".
Display ctrl or mon only when allocation or monitoring is supportd.

v5: Use resctrl_kcfg.caps and resctrl_kcfg.active after the struct split
from patch 0006. Rename resctrl_kmode_bind_str() to
resctrl_kmode_state_str() and ctrl_bind/mon_bind to ctrl_state/mon_state.
Used info_kn_lock()/info_kn_unlock().
Add documentation update in resctrl.rst.

v4: Fixed the display of inherit_ctrl_and_mon policy. It is not
associated with any group.
Added "uninitialized" for the non-active group.
Rewrote the changelog.

v3: New patch to handle the changed interface file info/kernel_mode.
Changed the group name to "none" if kmode binding is not done.
Reinette suggested "uninitialized". "none" seemed more relevent.
---
Documentation/filesystems/resctrl.rst | 48 +++++++++++++
fs/resctrl/rdtgroup.c | 100 ++++++++++++++++++++++++++
2 files changed, 148 insertions(+)

diff --git a/Documentation/filesystems/resctrl.rst b/Documentation/filesystems/resctrl.rst
index 73bf89d0ac83..73ccbb9594f5 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -527,6 +527,54 @@ 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" lists the
+ kernel modes supported by the system, one per line, with the active
+ mode enclosed in square brackets. A kernel mode determines the
+ allocation and monitoring associations when a task switches from
+ user mode to kernel mode.
+
+ Possible kernel modes are:
+
+ "inherit_user":
+ Kernel mode work uses the allocation and monitoring associations
+ of the user-space task on whose behalf it runs.
+
+ "global_enable_per_cpu":
+ Kernel mode work uses the allocation and/or monitoring
+ association of a backing CTRL_MON or MON group. The mode can
+ be activated or deactivated per CPU. The line contains group=
+ and whichever of ctrl= and mon= the platform supports::
+
+ global_enable_per_cpu:ctrl=<assign|inherit>;mon=<assign|inherit>;group=<CTRL_MON>/<MON>/
+
+ "ctrl":
+ "assign" if kernel mode work uses the allocation
+ association of the resource group named by "group",
+ "inherit" if it uses the allocation association of
+ the user-space task. Present only on systems that
+ support allocation.
+ "mon":
+ "assign" if kernel mode work uses the monitoring
+ association of the resource group named by "group",
+ "inherit" if it uses the monitoring association of
+ the user-space task. Present only on systems that
+ support monitoring.
+ "group":
+ Path of the resource group, relative to the resctrl
+ mount point. A CTRL_MON group is shown as <CTRL_MON>//,
+ a MON group as <CTRL_MON>/<MON>/.
+
+ When the mode is not active, the parameters are the defaults
+ used if it is activated without new values.
+
+ Example of a system that supports allocation and monitoring, with
+ default mode inherit_user::
+
+ # cat info/kernel_mode
+ [inherit_user]
+ global_enable_per_cpu:ctrl=assign;mon=assign;group=//
+
Resource alloc and monitor groups
=================================

diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 75b81d07a247..e82709d64a00 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -993,6 +993,99 @@ static int rdt_last_cmd_status_show(struct kernfs_open_file *of,
return 0;
}

+/* Names used in info/kernel_mode; indexed by enum resctrl_kernel_mode */
+static const char * const resctrl_kmode_str[] = {
+ [RESCTRL_INHERIT_USER] = "inherit_user",
+ [RESCTRL_GLOBAL_ENABLE_PER_CPU] = "global_enable_per_cpu"
+};
+
+static_assert(ARRAY_SIZE(resctrl_kmode_str) == RESCTRL_NUM_KERNEL_MODES);
+
+static const char *resctrl_kmode_state_str(enum kmode_state state)
+{
+ return state == KMODE_ASSIGN ? "assign" : "inherit";
+}
+
+static void resctrl_kmode_group_path(struct rdtgroup *rdtgrp,
+ const char **ctrl, const char **mon)
+{
+ *ctrl = "";
+ *mon = "";
+
+ if (rdtgrp->type == RDTMON_GROUP) {
+ *ctrl = rdt_kn_name(rdtgrp->mon.parent->kn);
+ *mon = rdt_kn_name(rdtgrp->kn);
+ } else {
+ *ctrl = rdt_kn_name(rdtgrp->kn);
+ }
+}
+
+/**
+ * resctrl_kernel_mode_show() - Display supported and active kernel modes
+ * @of: kernfs open file
+ * @seq: output seq_file
+ * @v: unused
+ *
+ * Lists one line per mode and brackets the active mode. inherit_user
+ * has no parameters. global_enable_per_cpu prints ctrl= only when
+ * allocation is supported and mon= only when monitoring is supported,
+ * then group=.
+ *
+ * Return: 0 on success, or -ENOENT on error.
+ */
+static int resctrl_kernel_mode_show(struct kernfs_open_file *of,
+ struct seq_file *seq, void *v)
+{
+ const char *ctrl_grp, *mon_grp;
+ enum resctrl_kernel_mode mode;
+ bool active;
+ char sep;
+
+ if (!info_kn_lock(of->kn))
+ return -ENOENT;
+
+ for (mode = 0; mode < RESCTRL_NUM_KERNEL_MODES; mode++) {
+ if (!test_bit(mode, resctrl_kmode.kmode_sup))
+ continue;
+
+ active = resctrl_kmode.kmode_cur == mode;
+
+ seq_printf(seq, active ? "[%s" : "%s", resctrl_kmode_str[mode]);
+
+ if (mode == RESCTRL_GLOBAL_ENABLE_PER_CPU) {
+ ctrl_grp = "";
+ mon_grp = "";
+ if (active) {
+ if (resctrl_kmode.rdtgrp)
+ resctrl_kmode_group_path(resctrl_kmode.rdtgrp,
+ &ctrl_grp, &mon_grp);
+ else
+ pr_warn("%s active without a resource group\n",
+ resctrl_kmode_str[mode]);
+ }
+
+ sep = ':';
+ if (resctrl_arch_alloc_capable()) {
+ seq_printf(seq, "%cctrl=%s", sep,
+ resctrl_kmode_state_str(resctrl_kmode.ctrl));
+ sep = ';';
+ }
+ if (resctrl_arch_mon_capable()) {
+ seq_printf(seq, "%cmon=%s", sep,
+ resctrl_kmode_state_str(resctrl_kmode.mon));
+ sep = ';';
+ }
+ seq_printf(seq, "%cgroup=%s/%s/", sep, ctrl_grp, mon_grp);
+ }
+
+ seq_puts(seq, active ? "]\n" : "\n");
+ }
+
+ info_kn_unlock(of->kn);
+
+ return 0;
+}
+
void *rdt_kn_parent_priv(struct kernfs_node *kn)
{
/*
@@ -1978,6 +2071,13 @@ static struct rftype res_common_files[] = {
.seq_show = rdt_last_cmd_status_show,
.fflags = RFTYPE_TOP_INFO,
},
+ {
+ .name = "kernel_mode",
+ .mode = 0444,
+ .kf_ops = &rdtgroup_kf_single_ops,
+ .seq_show = resctrl_kernel_mode_show,
+ .fflags = RFTYPE_TOP_INFO,
+ },
{
.name = "mbm_assign_on_mkdir",
.mode = 0644,
--
2.43.0