From: Babu Moger <babu.moger@amd.com>
To: <corbet@lwn.net>, <tony.luck@intel.com>,
<reinette.chatre@intel.com>, <Dave.Martin@arm.com>,
<james.morse@arm.com>, <tglx@kernel.org>, <bp@alien8.de>,
<ben.horgan@arm.com>, <fenghuay@nvidia.com>
Cc: <skhan@linuxfoundation.org>, <x86@kernel.org>,
<babu.moger@amd.com>, <mingo@redhat.com>,
<dave.hansen@linux.intel.com>, <hpa@zytor.com>,
<akpm@linux-foundation.org>, <rdunlap@infradead.org>,
<peterz@infradead.org>, <feng.tang@linux.alibaba.com>,
<dapeng1.mi@linux.intel.com>, <elver@google.com>,
<enelsonmoore@gmail.com>, <kuba@kernel.org>,
<ebiggers@kernel.org>, <lirongqing@baidu.com>,
<seanjc@google.com>, <nikunj@amd.com>, <xin@zytor.com>,
<pawan.kumar.gupta@linux.intel.com>, <tiala@microsoft.com>,
<chang.seok.bae@intel.com>, <kprateek.nayak@amd.com>,
<prathyushi.nangia@amd.com>, <kim.phillips@amd.com>,
<naveen@kernel.org>, <darwi@linutronix.de>,
<elena.reshetova@intel.com>, <linux-doc@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <thomas.lendacky@amd.com>,
<eranian@google.com>, <peternewman@google.com>,
<qinyuntan@linux.alibaba.com>
Subject: [RESEND PATCH v4 14/15] fs/resctrl: Allow user space to write kmode_cpus/kmode_cpus_list
Date: Tue, 7 Jul 2026 16:50:15 -0500 [thread overview]
Message-ID: <e2deefce19f3cf087ea96a7aba3f6850812e3036.1783461016.git.babu.moger@amd.com> (raw)
In-Reply-To: <cover.1783461016.git.babu.moger@amd.com>
kmode_cpus and kmode_cpus_list expose the CPU scope for the rdtgroup bound
to the active kernel-mode policy. They are currently read-only, so changing
the scope requires rebinding through info/kernel_mode, which reprograms the
whole binding instead of only the CPUs whose state changes.
Make kmode_cpus and kmode_cpus_list writable. Parse writes as a bitmap or
CPU range list. Reject pseudo-locked and pseudo-lock-setup groups, writes
to a group other than resctrl_kcfg.k_rdtgrp (including stale file
descriptors left open across an info/kernel_mode change), malformed input,
and masks that name offline CPUs.
Update the bound group's kmode_cpu_mask and reprogram hardware
incrementally: disable kernel-mode association on CPUs in the old mask but
not the new mask, and enable it on CPUs in the new mask but not the old
mask.
Document the interface in Documentation/filesystems/resctrl.rst.
Signed-off-by: Babu Moger <babu.moger@amd.com>
---
v4: Empty masks are now allowed and updated masks are in rdtgroup->kmode_cpu_mask.
Updated the changelog.
v3: New patch to add "kmode_cpus" and "kmode_cpus_list" to support
kernel_modes.
---
Documentation/filesystems/resctrl.rst | 30 +++++
fs/resctrl/rdtgroup.c | 151 +++++++++++++++++++++++++-
2 files changed, 179 insertions(+), 2 deletions(-)
diff --git a/Documentation/filesystems/resctrl.rst b/Documentation/filesystems/resctrl.rst
index 5a13814d1325..4a2bdd74d4aa 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -676,6 +676,36 @@ All groups contain the following files:
"cpus_list":
Just like "cpus", only using ranges of CPUs instead of bitmasks.
+"kmode_cpus":
+ Visible only on the rdtgroup currently bound to the active kernel
+ mode (see "info/kernel_mode"); hidden on every other rdtgroup,
+ including when "inherit_ctrl_and_mon" is active.
+
+ Bitmask of the logical CPUs scoped for this group's kernel-mode
+ binding. At bind time through info/kernel_mode, every currently
+ online CPU is included in the scope. CPUs that come online later
+ are automatically added to the scope and programmed with the binding.
+
+ Writing a mask reprograms the binding incrementally: it enables on
+ the CPUs newly added by the write and disables on the CPUs dropped
+ from the previous mask. An empty mask disables the binding on all
+ CPUs in the current scope. The mask must contain only online CPUs;
+ masks naming offline CPUs are rejected.
+ Errors are reported in "info/last_cmd_status". Example::
+
+ # mkdir ctrl1
+ # echo "global_assign_ctrl_inherit_mon_per_cpu:group=ctrl1//" \
+ > info/kernel_mode
+ # echo 0-3 > ctrl1/kmode_cpus_list
+ # cat ctrl1/kmode_cpus
+ f
+ # cat ctrl1/kmode_cpus_list
+ 0-3
+
+"kmode_cpus_list":
+ Just like "kmode_cpus", only using ranges of CPUs instead of bitmasks.
+ Writable with the same semantics and restrictions as "kmode_cpus".
+
When control is enabled all CTRL_MON groups will also contain:
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 7b06c3b3f00e..8ecd107368b3 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -423,6 +423,151 @@ static int rdtgroup_kmode_cpus_show(struct kernfs_open_file *of,
return ret;
}
+/**
+ * kmode_cpus_write() - Update @rdtgrp's kmode_cpu_mask from @newmask
+ * @rdtgrp: Resctrl group whose kmode_cpu_mask is being updated.
+ * @kmode: Kernel-mode policy currently active on @rdtgrp.
+ * @newmask: Set of online CPUs scoped for @rdtgrp's kernel-mode binding.
+ * @tmpmask: Caller-allocated scratch cpumask used to compute the
+ * incremental enable/disable deltas; contents on entry are
+ * ignored and on return are unspecified.
+ *
+ * Compute the difference between @rdtgrp->kmode_cpu_mask and @newmask
+ * and call resctrl_arch_configure_kmode() only on the CPUs whose enable
+ * state actually changes:
+ *
+ * - disable on (old & ~new)
+ * - enable on (new & ~old)
+ *
+ * Then copy @newmask into @rdtgrp->kmode_cpu_mask so subsequent
+ * show/write operations reflect the updated scope.
+ */
+static void kmode_cpus_write(struct rdtgroup *rdtgrp, enum resctrl_kernel_mode kmode,
+ cpumask_var_t newmask, cpumask_var_t tmpmask)
+{
+ bool assign_mon = (kmode == GLOBAL_ASSIGN_CTRL_ASSIGN_MON_PER_CPU);
+ u32 closid, rmid;
+
+ closid = rdtgrp->closid;
+ rmid = rdtgrp->mon.rmid;
+
+ /* CPUs dropped from this group: old & ~newmask. */
+ cpumask_andnot(tmpmask, &rdtgrp->kmode_cpu_mask, newmask);
+ if (!cpumask_empty(tmpmask))
+ resctrl_arch_configure_kmode(tmpmask, closid, rmid, assign_mon, false);
+
+ /* CPUs newly added: newmask & ~old. */
+ cpumask_andnot(tmpmask, newmask, &rdtgrp->kmode_cpu_mask);
+ if (!cpumask_empty(tmpmask))
+ resctrl_arch_configure_kmode(tmpmask, closid, rmid, assign_mon, true);
+
+ cpumask_copy(&rdtgrp->kmode_cpu_mask, newmask);
+}
+
+/**
+ * rdtgroup_kmode_cpus_write() - Sysfs write handler for kmode_cpus[_list]
+ * @of: kernfs open file (selects bitmap vs range-list parsing via
+ * is_cpu_list()).
+ * @buf: NUL-terminated input from userspace.
+ * @nbytes: Length of @buf, returned on success.
+ * @off: File offset (unused).
+ *
+ * Parses @buf into a cpumask and rejects:
+ * - pseudo-locked / pseudo-lock-setup groups,
+ * - writes when INHERIT_CTRL_AND_MON is active or to a group other than
+ * resctrl_kcfg.k_rdtgrp (stale fds opened before an info/kernel_mode
+ * change),
+ * - malformed input,
+ * - masks containing offline CPUs.
+ *
+ * Validated masks are passed to kmode_cpus_write() to update
+ * @rdtgrp->kmode_cpu_mask and reprogram hardware incrementally.
+ * Errors are reported in last_cmd_status.
+ *
+ * Return: @nbytes on success, -ENOENT if the group has been deleted,
+ * -EINVAL for pseudo-locked or pseudo-lock-setup groups, malformed input, or
+ * offline CPUs in the requested mask, -EBUSY if INHERIT_CTRL_AND_MON is active
+ * or the group is not resctrl_kcfg.k_rdtgrp, and -ENOMEM if the scratch
+ * cpumasks cannot be allocated.
+ */
+static ssize_t rdtgroup_kmode_cpus_write(struct kernfs_open_file *of,
+ char *buf, size_t nbytes, loff_t off)
+{
+ cpumask_var_t tmpmask, newmask;
+ struct rdtgroup *rdtgrp;
+ int ret;
+
+ if (!buf)
+ return -EINVAL;
+
+ if (!zalloc_cpumask_var(&tmpmask, GFP_KERNEL))
+ return -ENOMEM;
+ if (!zalloc_cpumask_var(&newmask, GFP_KERNEL)) {
+ free_cpumask_var(tmpmask);
+ return -ENOMEM;
+ }
+
+ rdtgrp = rdtgroup_kn_lock_live(of->kn);
+ if (!rdtgrp) {
+ ret = -ENOENT;
+ goto unlock;
+ }
+
+ rdt_last_cmd_clear();
+
+ if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED ||
+ rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
+ ret = -EINVAL;
+ rdt_last_cmd_puts("Pseudo-locked group cannot host kernel-mode binding\n");
+ goto unlock;
+ }
+
+ if (resctrl_kcfg.kmode_cur == INHERIT_CTRL_AND_MON) {
+ ret = -EBUSY;
+ rdt_last_cmd_puts("No active kernel-mode binding\n");
+ goto unlock;
+ }
+
+ /*
+ * The visibility layer (kernfs_show()) prevents fresh open() on a
+ * non-bound group, but file descriptors opened while the group was
+ * bound stay valid across an info/kernel_mode change. Reject those
+ * stale-fd writes so they cannot corrupt the now-active binding.
+ */
+ if (resctrl_kcfg.k_rdtgrp != rdtgrp) {
+ ret = -EBUSY;
+ rdt_last_cmd_puts("Group is not the active kernel-mode binding\n");
+ goto unlock;
+ }
+
+ if (is_cpu_list(of))
+ ret = cpulist_parse(buf, newmask);
+ else
+ ret = cpumask_parse(buf, newmask);
+
+ if (ret) {
+ rdt_last_cmd_puts("Bad CPU list/mask\n");
+ goto unlock;
+ }
+
+ /* kernel-mode binding is only programmed on online CPUs. */
+ cpumask_andnot(tmpmask, newmask, cpu_online_mask);
+ if (!cpumask_empty(tmpmask)) {
+ ret = -EINVAL;
+ rdt_last_cmd_puts("Can only assign online CPUs\n");
+ goto unlock;
+ }
+
+ kmode_cpus_write(rdtgrp, resctrl_kcfg.kmode_cur, newmask, tmpmask);
+
+unlock:
+ rdtgroup_kn_unlock(of->kn);
+ free_cpumask_var(tmpmask);
+ free_cpumask_var(newmask);
+
+ return ret ?: nbytes;
+}
+
/*
* Update the PGR_ASSOC MSR on all cpus in @cpu_mask,
*
@@ -2531,15 +2676,17 @@ static struct rftype res_common_files[] = {
},
{
.name = "kmode_cpus",
- .mode = 0444,
+ .mode = 0644,
.kf_ops = &rdtgroup_kf_single_ops,
+ .write = rdtgroup_kmode_cpus_write,
.seq_show = rdtgroup_kmode_cpus_show,
.fflags = RFTYPE_BASE,
},
{
.name = "kmode_cpus_list",
- .mode = 0444,
+ .mode = 0644,
.kf_ops = &rdtgroup_kf_single_ops,
+ .write = rdtgroup_kmode_cpus_write,
.seq_show = rdtgroup_kmode_cpus_show,
.flags = RFTYPE_FLAGS_CPUS_LIST,
.fflags = RFTYPE_BASE,
--
2.43.0
next prev parent reply other threads:[~2026-07-07 21:53 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-07 21:50 [RESEND PATCH v4 00/15] x86/resctrl: Add kernel-mode (e.g., PLZA) support to the resctrl subsystem Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 01/15] x86/resctrl: Support Privilege Level Zero Association (PLZA) Babu Moger
2026-07-07 22:01 ` Borislav Petkov
2026-07-08 14:51 ` Babu Moger
2026-07-08 17:27 ` Borislav Petkov
2026-07-08 16:55 ` Babu Moger
2026-07-08 23:28 ` Borislav Petkov
2026-07-09 0:00 ` Namhyung Kim
2026-07-09 0:12 ` Borislav Petkov
2026-07-10 0:55 ` Namhyung Kim
2026-07-10 1:46 ` Borislav Petkov
2026-07-07 21:50 ` [RESEND PATCH v4 02/15] x86/resctrl: Add PLZA support to command-line options Babu Moger
2026-07-08 17:39 ` Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 03/15] x86/resctrl: Add data structures and definitions for PLZA configuration Babu Moger
2026-07-08 20:20 ` Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 04/15] fs/resctrl: Introduce kernel mode (kmode) data structures Babu Moger
2026-07-08 20:56 ` Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 05/15] x86,fs/resctrl: Introduce architecture hooks to program kernel-mode Babu Moger
2026-07-08 23:04 ` Moger, Babu
2026-07-07 21:50 ` [RESEND PATCH v4 06/15] fs/resctrl: Introduce resctrl_set_kmode_support() to initialize supported modes Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 07/15] x86/resctrl: Expose the supported PLZA kernel-mode policies during init Babu Moger
2026-07-09 15:15 ` Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 08/15] fs/resctrl: Add interface to display supported and active kernel-mode policy Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 09/15] fs/resctrl: Introduce kmode_cpus/kmode_cpus_list per rdtgroup Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 10/15] fs/resctrl: Reset the kernel-mode binding when an rdtgroup is removed Babu Moger
2026-07-09 18:15 ` Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 11/15] fs/resctrl: Program kernel-mode binding when CPU comes online Babu Moger
2026-07-09 20:01 ` Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 12/15] fs/resctrl: Hide kmode_cpus[_list] on groups not bound to kernel-mode Babu Moger
2026-07-07 21:50 ` [RESEND PATCH v4 13/15] fs/resctrl: Add interface to modify kernel-mode via info/kernel_mode Babu Moger
2026-07-09 22:46 ` Moger, Babu
2026-07-07 21:50 ` Babu Moger [this message]
2026-07-09 23:14 ` [RESEND PATCH v4 14/15] fs/resctrl: Allow user space to write kmode_cpus/kmode_cpus_list Moger, Babu
2026-07-07 21:50 ` [RESEND PATCH v4 15/15] fs/resctrl: Add documentation on kernel_mode with example Babu Moger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e2deefce19f3cf087ea96a7aba3f6850812e3036.1783461016.git.babu.moger@amd.com \
--to=babu.moger@amd.com \
--cc=Dave.Martin@arm.com \
--cc=akpm@linux-foundation.org \
--cc=ben.horgan@arm.com \
--cc=bp@alien8.de \
--cc=chang.seok.bae@intel.com \
--cc=corbet@lwn.net \
--cc=dapeng1.mi@linux.intel.com \
--cc=darwi@linutronix.de \
--cc=dave.hansen@linux.intel.com \
--cc=ebiggers@kernel.org \
--cc=elena.reshetova@intel.com \
--cc=elver@google.com \
--cc=enelsonmoore@gmail.com \
--cc=eranian@google.com \
--cc=feng.tang@linux.alibaba.com \
--cc=fenghuay@nvidia.com \
--cc=hpa@zytor.com \
--cc=james.morse@arm.com \
--cc=kim.phillips@amd.com \
--cc=kprateek.nayak@amd.com \
--cc=kuba@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lirongqing@baidu.com \
--cc=mingo@redhat.com \
--cc=naveen@kernel.org \
--cc=nikunj@amd.com \
--cc=pawan.kumar.gupta@linux.intel.com \
--cc=peternewman@google.com \
--cc=peterz@infradead.org \
--cc=prathyushi.nangia@amd.com \
--cc=qinyuntan@linux.alibaba.com \
--cc=rdunlap@infradead.org \
--cc=reinette.chatre@intel.com \
--cc=seanjc@google.com \
--cc=skhan@linuxfoundation.org \
--cc=tglx@kernel.org \
--cc=thomas.lendacky@amd.com \
--cc=tiala@microsoft.com \
--cc=tony.luck@intel.com \
--cc=x86@kernel.org \
--cc=xin@zytor.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox