Skip to contentSkip to conversation

x86/resctrl: Add kernel-mode (e.g., PLZA) support to the resctrl subsystem

PATCH Superseded Babu Moger 6 participants 53 messages Aug 26 – Sep 22

Subsystems (4)

v5 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

Babu Moger

author reviewer
#0 lore raw

v5 cover x86/resctrl: Add kernel-mode (e.g., PLZA) support to the resctrl subsystem

Hi All,

This series adds support for AMD's Privilege-Level Zero Association (PLZA) so kernel work can use a separate resource allocation and/or monitoring association from the user task, and wires it up through a small generic "kernel mode" (kmode) layer in fs/resctrl so future architectures can plug in without touching(hopefully) core resctrl.

The features are documented in:

AMD64 Zen6 Platform Quality of Service (PQOS) Extensions, Publication # 69193 Revision 1.00, Issue Date March 2026

available at https://bugzilla.kernel.org/show_bug.cgi?id=206537

The patches are based on top of commit (tip/master v7.2):

e7bb1f1ccd17 Merge branch into tip/master: 'locking/urgent'

Any feedback is apprecated.

Background
==========

When memory bandwidth associated with a CLOSID is aggressively throttled, and a task with that CLOSID moves into kernel mode, the kernel operations are also aggressively throttled. This can stall forward progress and eventually degrade overall system performance.

Privilege-Level Zero Association (PLZA) allows the user to specify a CLOSID and/or RMID for execution at Privilege Level Zero. When PLZA is enabled on a CPU, kernel work at PL0 uses the CLOSID and/or RMID from MSR PQR_PLZA_ASSOC; otherwise, the CPU uses the CLOSID and RMID from PQR_ASSOC.

Design
======

A new sysfs file, info/kernel_mode, holds the global policy for resource allocation and monitoring of kernel work and the resource group (when applicable) associated with the policy. Reads list the supported modes and the currently active association; writes change the policy or associate a different group. Look at the thread below for design discussion.
https://lore.kernel.org/lkml/[email protected]/
https://lore.kernel.org/lkml/[email protected]/

Two kernel modes are exposed:

- inherit_user: kernel work inherits allocation and monitoring from the user task.
- assign_global_enable_per_cpu: kernel work may use separate allocation and/or monitoring associations. ctrl= and mon= select whether each dimension is assigned or inherited, and group= identifies the associated resource group using <CTRL_MON>/<MON>/ path syntax.

Per-rdtgroup files kmode_cpus and kmode_cpus_list scope the association to a subset of online CPUs without deactivating and re-associating. They are visible only on the group currently associated through info/kernel_mode.

Groups associated through kernel mode cannot enter pseudo-lock setup, change mode, or be renamed until the association is cleared.

The arch hook, resctrl_arch_configure_kmode(), keeps the fs/resctrl layer arch-neutral.

resctrl_set_kmode_support() lets architecture code register supported kernel-mode policies during resctrl initialization. On AMD, PLZA registers assign_global_enable_per_cpu when the feature is available.

Only AMD PLZA is wired up here; Intel and ARM can add their own support later by implementing the hooks.

Examples
========

(See Documentation/filesystems/resctrl.rst, "kernel_mode", "kmode_cpus", and "Examples on working with kernel_mode", for the full UAPI.)

# Mount resctrl

  # mount -t resctrl resctrl /sys/fs/resctrl
  # cd /sys/fs/resctrl

# Read the supported modes. The active mode is bracketed for display # only; do not include brackets when writing.

  # cat info/kernel_mode
  [inherit_user]
  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//

# Create a CTRL_MON group and associate kernel-mode allocation with it.

  # mkdir ctrl1
  # echo "assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//" \
          > info/kernel_mode
  # cat info/kernel_mode
  inherit_user
  [assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//]
  # kmode_cpus and kmode_cpus_list are visible only on the associated group.
  # ls ctrl1/kmode_cpus*
  ctrl1/kmode_cpus  ctrl1/kmode_cpus_list

# Restrict the association to a CPU subset; the write is incremental.

  # echo 0-3 > ctrl1/kmode_cpus_list
  # cat ctrl1/kmode_cpus
  f
  # cat ctrl1/kmode_cpus_list
  0-3

# Return to the default inherit policy.

  # echo "inherit_user" > info/kernel_mode
  # cat info/kernel_mode
  [inherit_user]
  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//

Tested on AMD with PLZA; builds on x86 without PLZA and does not expose assign_global_enable_per_cpu unless the feature is available.

Layout
======

01-03 x86: PLZA CPU feature, command-line option, and MSR/data-structure
plumbing.
04-07 fs/resctrl + x86: kernel mode policy enum, arch hooks, kmode state,
and resctrl_set_kmode_support().
08 x86/resctrl: register assign_global_enable_per_cpu when PLZA is
available.

  09     fs/resctrl: info/kernel_mode read-only introspection.
  10     fs/resctrl: hidden rdtgroup files for kmode_cpus visibility control.
  11     fs/resctrl: per-rdtgroup kmode_cpus/kmode_cpus_list read interface.
  12     fs/resctrl: program kernel-mode association when a CPU comes online.
  13     fs/resctrl: deactivate the association when a group is removed.
  14     fs/resctrl: info/kernel_mode write interface.
  15     fs/resctrl: incremental kmode_cpus/kmode_cpus_list writes.
  16     fs/resctrl: documentation and end-to-end examples.

Changelog
=========
v5:
- Collapse the two v4 global-assign modes into a single assign_global_enable_per_cpu policy with ctrl= and mon= options.
- Use "association" terminology consistently in code, errors, and documentation.
- Register assign_global_enable_per_cpu once during x86 resource discovery when PLZA is available.
- Reject mon=inherit when group= selects a monitor group.
- Split hidden-file support, deactivation-on-teardown, and PLZA mode registration into separate patches for easier review.
- Fix msr_pqr_plza_assoc truncation on 32-bit systems by using u64.
- Refresh documentation and add a readable end-to-end example walkthrough.
- Block pseudo-lock setup on kernel-mode-associated groups.
- Reject mode changes and rename while a group backs the active association.

v4:
- Reorder and split the series into 15 patches: separate read-only info/kernel_mode display from the write path; add hotplug support when a CPU comes online; add an end-to-end documentation/examples patch.
- Introduced resctrl_set_kmode_support() so architecture code can register supported kernel-mode policies during resctrl initialization.
- info/kernel_mode write: validate group type; run fail paths before tearing down the active association so errors retain the old state.
- kmode_cpus / kmode_cpus_list: writable with incremental enable/disable deltas; empty masks allowed; offline CPUs rejected.
- Hotplug: newly online CPUs are added to the associated group's kmode_cpu_mask and programmed when assign_global_enable_per_cpu is active.

v3:
- Generalise the layer beyond AMD: rename "PLZA mode" to "kernel mode" (kmode) in code, sysfs, and Documentation.
- Reset the association when the associated rdtgroup is removed, instead of leaving stale state.

v2:
- Similar to RFC with a new proposal; interface names were not final.
- Separated Global Bandwidth Enforcement (GLBE) from PLZA; this series only adds PLZA support.
- Used "kmode" instead of "PLZA" in the generic layer.

Previous versions:
v4: https://lore.kernel.org/lkml/[email protected]/
v3: https://lore.kernel.org/lkml/[email protected]/
v2: https://lore.kernel.org/lkml/[email protected]/
v1: https://lore.kernel.org/lkml/[email protected]/

Babu Moger (16):
x86/cpufeatures: Support Privilege Level Zero Association (PLZA) x86/resctrl: Add PLZA support to command-line options x86/resctrl: Add PLZA configuration definitions and data structures fs/resctrl: Introduce kernel mode policy enum x86,fs/resctrl: Introduce architecture hooks to program kernel mode fs/resctrl: Introduce kernel mode states for resctrl fs/resctrl: Introduce resctrl_set_kmode_support() to register
supported modes
x86/resctrl: Expose assign_global_enable_per_cpu when PLZA is
available
fs/resctrl: Add interface to display supported and active kernel modes fs/resctrl: Add support for hidden resource group files fs/resctrl: Introduce kmode_cpus/kmode_cpus_list per rdtgroup fs/resctrl: Program kernel mode assignments on CPU hotplug fs/resctrl: Deactivate the kernel mode association when a group is
removed
fs/resctrl: Add interface to modify kernel mode via info/kernel_mode fs/resctrl: Allow user space to write kmode_cpus/kmode_cpus_list fs/resctrl: Add documentation on kernel_mode with example

 .../admin-guide/kernel-parameters.txt         |   2 +-
 Documentation/filesystems/resctrl.rst         | 193 +++++
 arch/x86/include/asm/cpufeatures.h            |   1 +
 arch/x86/include/asm/msr-index.h              |   1 +
 arch/x86/kernel/cpu/resctrl/core.c            |   6 +
 arch/x86/kernel/cpu/resctrl/ctrlmondata.c     |  38 +
 arch/x86/kernel/cpu/resctrl/internal.h        |  47 ++
 arch/x86/kernel/cpu/scattered.c               |   1 +
 drivers/resctrl/mpam_resctrl.c                |   6 +
 fs/resctrl/internal.h                         |  60 ++
 fs/resctrl/pseudo_lock.c                      |   5 +
 fs/resctrl/rdtgroup.c                         | 795 ++++++++++++++++++
 include/linux/resctrl.h                       |  75 ++
 13 files changed, 1229 insertions(+), 1 deletion(-)
Signature · 1 line
2.43.0
author reviewer
#1 lore raw

PATCH v5 1/16 x86/cpufeatures: Support Privilege Level Zero Association (PLZA)

When memory bandwidth associated with a CLOSID is aggressively throttled, and a task with that CLOSID moves into kernel mode, the kernel operations are also aggressively throttled. This can stall forward progress and eventually degrade overall system performance.

AMD hardware supports a feature Privilege Level Zero Association (PLZA), which allows the CPU's CLOSID association to be changed during the transition from user mode to kernel mode. This allows the kernel to run using a different CLOSID than user space, which can improve system performance.

PLZA also applies to cache allocation and monitoring features and provides flexibility to manage allocation and monitoring associations independently.

The feature is detected via CPUID_Fn80000020_EBX_x00 [Bit 9]: Privilege Level Zero Association (PLZA).

The PLZA feature details are documented in [1] available from [2].

[1] AMD64 Zen6 Platform Quality of Service (PQOS) Extensions:

    Publication # 69193 Revision: 1.00, Issue Date: March 2026

---
v5: Added Acked-by from Boris.
Updated the changelog to include cache allocation and monitoring. Moved the Link tag last.
Updated subject line for cpufeatures.

v4: Split the patch into 2. This patch only handles x86 changes.
Re-wrote the changelog along the ABMC changes.

v3: Code did not change. Patch order changed.
Added documentation link.

v2: Rebased on top of the latest tip.

---
 arch/x86/include/asm/cpufeatures.h | 1 +
 arch/x86/kernel/cpu/scattered.c    | 1 +
 2 files changed, 2 insertions(+)
arch/x86/include/asm/cpufeatures.h +1 -0
index 73d5c740202d..cd7baa654d85 100644
@@ -519,6 +519,7 @@
 						      * and purposes if CLEAR_CPU_BUF_VM is set).
 						      */
 #define X86_FEATURE_X2AVIC_EXT		(21*32+20) /* AMD SVM x2AVIC support for 4k vCPUs */
+#define X86_FEATURE_PLZA		(21*32+21) /* Privilege Level Zero Association */
 
 /*
  * BUG word(s)
arch/x86/kernel/cpu/scattered.c +1 -0
index 8665a6474806..0cb91f24b6cb 100644
@@ -61,6 +61,7 @@ static const struct cpuid_bit cpuid_bits[] = {
 	{ X86_FEATURE_BMEC,			CPUID_EBX,  3, 0x80000020, 0 },
 	{ X86_FEATURE_ABMC,			CPUID_EBX,  5, 0x80000020, 0 },
 	{ X86_FEATURE_SDCIAE,			CPUID_EBX,  6, 0x80000020, 0 },
+	{ X86_FEATURE_PLZA,			CPUID_EBX,  9, 0x80000020, 0 },
 	{ X86_FEATURE_AMD_WORKLOAD_CLASS,	CPUID_EAX, 22, 0x80000021, 0 },
 	{ X86_FEATURE_TSA_SQ_NO,		CPUID_ECX,  1, 0x80000021, 0 },
 	{ X86_FEATURE_TSA_L1_NO,		CPUID_ECX,  2, 0x80000021, 0 },
Signature · 1 line
2.43.0
maintainer
#2 lore raw

Re: [PATCH v5 01/16] x86/cpufeatures: Support Privilege Level Zero Association (PLZA)

Hi Babu,

Quoted 7 lines · Babu Moger

When memory bandwidth associated with a CLOSID is aggressively throttled, and a task with that CLOSID moves into kernel mode, the kernel operations are also aggressively throttled. This can stall forward progress and eventually degrade overall system performance.

AMD hardware supports a feature Privilege Level Zero Association (PLZA), which allows the CPU's CLOSID association to be changed during the

CLOSID -> CLOSID and/or RMID?

Quoted 2 lines

transition from user mode to kernel mode. This allows the kernel to run using a different CLOSID than user space, which can improve system

CLOSID -> CLOSID and/or RMID?

Quoted 1 line

performance.

"... and/or separately monitor the work done in kernel mode."?

Quoted 3 lines

PLZA also applies to cache allocation and monitoring features and provides flexibility to manage allocation and monitoring associations independently.

This reads like an afterthought. Are users expected to use cache allocation while PLZA is enabled? Since only one resource group can be assigned I expect there to be quite a few sharp corners when both are in use. Kernel work done on behalf of high as well as low priority work will use the same cache allocations and thus neither could actually get full benefit from having dedicated cache portions?

Quoted 5 lines

The feature is detected via CPUID_Fn80000020_EBX_x00 [Bit 9]: Privilege Level Zero Association (PLZA).

The PLZA feature details are documented in [1] available from [2].

Quoted 7 lines

[1] AMD64 Zen6 Platform Quality of Service (PQOS) Extensions:

    Publication # 69193 Revision: 1.00, Issue Date: March 2026

---

Reinette

author reviewer
#3 lore raw

Re: [PATCH v5 01/16] x86/cpufeatures: Support Privilege Level Zero Association (PLZA)

Hi Reinette,

Thanks for the feedback for the series.

Quoted 8 lines · Reinette Chatre

Hi Babu,

Quoted 5 lines · Babu Moger

When memory bandwidth associated with a CLOSID is aggressively throttled, and a task with that CLOSID moves into kernel mode, the kernel operations are also aggressively throttled. This can stall forward progress and eventually degrade overall system performance.

Quoted 5 lines
Quoted 2 lines

AMD hardware supports a feature Privilege Level Zero Association (PLZA), which allows the CPU's CLOSID association to be changed during the

CLOSID -> CLOSID and/or RMID?

Sure.

Quoted 4 lines
Quoted 2 lines

transition from user mode to kernel mode. This allows the kernel to run using a different CLOSID than user space, which can improve system

CLOSID -> CLOSID and/or RMID?

Sure.

Quoted 3 lines
Quoted 1 line

performance.

"... and/or separately monitor the work done in kernel mode."?

Sure.

Quoted 11 lines
Quoted 4 lines

PLZA also applies to cache allocation and monitoring features and provides flexibility to manage allocation and monitoring associations independently.

This reads like an afterthought. Are users expected to use cache allocation while PLZA is enabled? Since only one resource group can be assigned I expect there to be quite a few sharp corners when both are in use. Kernel work done on behalf of high as well as low priority work will use the same cache allocations and thus neither could actually get full benefit from having dedicated cache portions?

The best-known use case today is to leave both cache allocation and memory bandwidth allocation at their default (maximum) settings and enable PLZA on all CPUs.

Users can, however, configure both cache allocation and memory bandwidth limits. In those cases, there can be corner-case behaviors and trade-offs.

If you think the current wording is misleading, I can drop that text and rephrase it along these lines to include both cache and memory.

"When cache and/or memory bandwidth associated with a CLOSID is aggressively throttled, and a task with that CLOSID moves into kernel mode, the kernel operations are also aggressively throttled. This can stall forward progress and eventually degrade overall system performance.

AMD hardware supports the Privilege Level Zero Association (PLZA) feature, which allows the CPU's CLOSID and/or RMID association to be changed during transitions from user mode to kernel mode. This enables the kernel to run with a different CLOSID and/or RMID than user space, improving system performance and/or allowing kernel work to be monitored separately."

Thanks
Babu

maintainer
#4 lore raw

Re: [PATCH v5 01/16] x86/cpufeatures: Support Privilege Level Zero Association (PLZA)

Hi Babu,

Quoted 2 lines · Babu Moger
Quoted 1 line · Reinette Chatre

On 8/26/26 12:32 PM, Babu Moger wrote:

...

Quoted 13 lines
Quoted 6 lines
Quoted 5 lines

PLZA also applies to cache allocation and monitoring features and provides flexibility to manage allocation and monitoring associations independently.

Quoted 6 lines

This reads like an afterthought. Are users expected to use cache allocation while PLZA is enabled? Since only one resource group can be assigned I expect there to be quite a few sharp corners when both are in use. Kernel work done on behalf of high as well as low priority work will use the same cache allocations and thus neither could actually get full benefit from having dedicated cache portions?

Quoted 3 lines

The best-known use case today is to leave both cache allocation and memory bandwidth allocation at their default (maximum) settings and enable PLZA on all CPUs.

Interesting. This sounds like all kernel work can access the entire cache and thus evict data from any user space tasks that may have used cache allocation to avoid interference.

Quoted 4 lines

Users can, however, configure both cache allocation and memory bandwidth limits. In those cases, there can be corner-case behaviors and trade-offs.

If you think the current wording is misleading, I can drop that text and rephrase it along these lines to include both cache and memory.

No, the wording is not misleading. The description just focuses on memory bandwidth allocation leaving impression that the feature only applies to that resource when it applies to all resources.

Quoted 7 lines

"When cache and/or memory bandwidth associated with a CLOSID is aggressively throttled, and a task with that CLOSID moves into kernel mode, the kernel operations are also aggressively throttled. This can stall forward progress and eventually degrade overall system performance.

Quoted 6 lines

AMD hardware supports the Privilege Level Zero Association (PLZA) feature, which allows the CPU's CLOSID and/or RMID association to be changed during transitions from user mode to kernel mode. This enables the kernel to run with a different CLOSID and/or RMID than user space, improving system performance and/or allowing kernel work to be monitored separately.">

I think what you have for memory bandwidth sounds good. I do not think the cache allocation and memory bandwidth usage descriptions should be mixed since the implications are so different. Could you please just add a snippet that highlights since the feature assigns CLOSID/RMID to kernel work it influences allocation and monitoring of all resources, not just memory bandwidth?

Reinette

author reviewer
#5 lore raw

Re: [PATCH v5 01/16] x86/cpufeatures: Support Privilege Level Zero Association (PLZA)

Hi Reinette,

Quoted 53 lines · Reinette Chatre

Hi Babu,

Quoted 2 lines · Babu Moger
Quoted 1 line · Reinette Chatre

On 8/26/26 12:32 PM, Babu Moger wrote:

...

Quoted 13 lines
Quoted 6 lines
Quoted 5 lines

PLZA also applies to cache allocation and monitoring features and provides flexibility to manage allocation and monitoring associations independently.

Quoted 6 lines

This reads like an afterthought. Are users expected to use cache allocation while PLZA is enabled? Since only one resource group can be assigned I expect there to be quite a few sharp corners when both are in use. Kernel work done on behalf of high as well as low priority work will use the same cache allocations and thus neither could actually get full benefit from having dedicated cache portions?

Quoted 3 lines

The best-known use case today is to leave both cache allocation and memory bandwidth allocation at their default (maximum) settings and enable PLZA on all CPUs.

Interesting. This sounds like all kernel work can access the entire cache and thus evict data from any user space tasks that may have used cache allocation to avoid interference.

Quoted 4 lines

Users can, however, configure both cache allocation and memory bandwidth limits. In those cases, there can be corner-case behaviors and trade-offs.

If you think the current wording is misleading, I can drop that text and rephrase it along these lines to include both cache and memory.

No, the wording is not misleading. The description just focuses on memory bandwidth allocation leaving impression that the feature only applies to that resource when it applies to all resources.

Quoted 7 lines

"When cache and/or memory bandwidth associated with a CLOSID is aggressively throttled, and a task with that CLOSID moves into kernel mode, the kernel operations are also aggressively throttled. This can stall forward progress and eventually degrade overall system performance.

Quoted 6 lines

AMD hardware supports the Privilege Level Zero Association (PLZA) feature, which allows the CPU's CLOSID and/or RMID association to be changed during transitions from user mode to kernel mode. This enables the kernel to run with a different CLOSID and/or RMID than user space, improving system performance and/or allowing kernel work to be monitored separately.">

Quoted 7 lines

I think what you have for memory bandwidth sounds good. I do not think the cache allocation and memory bandwidth usage descriptions should be mixed since the implications are so different. Could you please just add a snippet that highlights since the feature assigns CLOSID/RMID to kernel work it influences allocation and monitoring of all resources, not just memory bandwidth?

Yes. Sure.
Thanks
Babu

author reviewer
#6 lore raw

PATCH v5 2/16 x86/resctrl: Add PLZA support to command-line options

In reply to Babu Moger

Add a kernel command-line parameter to enable or disable the exposure of the PLZA (Privilege Level Zero Association) feature to resctrl.

This allows administrators to control PLZA visibility at boot time via the rdt= option (e.g. rdt=plza or rdt=!plza).

Resctrl exposes PLZA by default without requiring any explicit rdt= option if supported. The rdt=!plza parameter can be used to disable PLZA exposure to resctrl, while rdt=plza explicitly enables it.

---
v5: Updated the changelog to mention about rdt= options.

v4: Split the patch 1 from v3 into 2 patches.
This patch contains changes for resctrl subsystem.

---
 Documentation/admin-guide/kernel-parameters.txt | 2 +-
 Documentation/filesystems/resctrl.rst           | 1 +
 arch/x86/kernel/cpu/resctrl/core.c              | 2 ++
 3 files changed, 4 insertions(+), 1 deletion(-)
Documentation/admin-guide/kernel-parameters.txt +1 -1
index 66c1c879a0b2..9772ce838966 100644
@@ -6455,7 +6455,7 @@ Kernel parameters
 	rdt=		[HW,X86,RDT]
 			Turn on/off individual RDT features. List is:
 			cmt, mbmtotal, mbmlocal, l3cat, l3cdp, l2cat, l2cdp,
-			mba, smba, bmec, abmc, sdciae, energy[:guid],
+			mba, smba, bmec, abmc, sdciae, plza, energy[:guid],
 			perf[:guid].
 			E.g. to turn on cmt and turn off mba use:
 				rdt=cmt,!mba
Documentation/filesystems/resctrl.rst +1 -0
index e4b66af55ffb..f3e941404967 100644
@@ -28,6 +28,7 @@ SMBA (Slow Memory Bandwidth Allocation)				""
 BMEC (Bandwidth Monitoring Event Configuration)			""
 ABMC (Assignable Bandwidth Monitoring Counters)			""
 SDCIAE (Smart Data Cache Injection Allocation Enforcement)	""
+PLZA (Privilege Level Zero Association)				""
 =============================================================== ================================
 
 Historically, new features were made visible by default in /proc/cpuinfo. This
arch/x86/kernel/cpu/resctrl/core.c +2 -0
index 55214d6fdc49..4ca8bedeb995 100644
@@ -803,6 +803,7 @@ enum {
 	RDT_FLAG_BMEC,
 	RDT_FLAG_ABMC,
 	RDT_FLAG_SDCIAE,
+	RDT_FLAG_PLZA,
 };
 
 #define RDT_OPT(idx, n, f)	\
@@ -830,6 +831,7 @@ static struct rdt_options rdt_options[]  __ro_after_init = {
 	RDT_OPT(RDT_FLAG_BMEC,	    "bmec",	X86_FEATURE_BMEC),
 	RDT_OPT(RDT_FLAG_ABMC,	    "abmc",	X86_FEATURE_ABMC),
 	RDT_OPT(RDT_FLAG_SDCIAE,    "sdciae",	X86_FEATURE_SDCIAE),
+	RDT_OPT(RDT_FLAG_PLZA,	    "plza",	X86_FEATURE_PLZA),
 };
 #define NUM_RDT_OPTIONS ARRAY_SIZE(rdt_options)
 
Signature · 1 line
2.43.0
maintainer
#7 lore raw

Re: [PATCH v5 02/16] x86/resctrl: Add PLZA support to command-line options

Hi Babu,

Quoted 9 lines · Babu Moger

Add a kernel command-line parameter to enable or disable the exposure of the PLZA (Privilege Level Zero Association) feature to resctrl.

This allows administrators to control PLZA visibility at boot time via the rdt= option (e.g. rdt=plza or rdt=!plza).

Resctrl exposes PLZA by default without requiring any explicit rdt= option if supported. The rdt=!plza parameter can be used to disable PLZA exposure to resctrl, while rdt=plza explicitly enables it.

There is a lot of repetition. How about something like:

Add "plza" to the rdt= command-line parameter so PLZA exposure to resctrl can be enabled or disabled at boot. PLZA is exposed by default when supported; rdt=!plza suppresses it.

Patch looks good.

Reinette

author reviewer
#8 lore raw

Re: [PATCH v5 02/16] x86/resctrl: Add PLZA support to command-line options

Hi Reinette,

Quoted 13 lines · Reinette Chatre

Hi Babu,

Quoted 9 lines · Babu Moger

Add a kernel command-line parameter to enable or disable the exposure of the PLZA (Privilege Level Zero Association) feature to resctrl.

This allows administrators to control PLZA visibility at boot time via the rdt= option (e.g. rdt=plza or rdt=!plza).

Resctrl exposes PLZA by default without requiring any explicit rdt= option if supported. The rdt=!plza parameter can be used to disable PLZA exposure to resctrl, while rdt=plza explicitly enables it.

Quoted 8 lines

There is a lot of repetition. How about something like:

Add "plza" to the rdt= command-line parameter so PLZA exposure to resctrl can be enabled or disabled at boot. PLZA is exposed by default when supported; rdt=!plza suppresses it.

Patch looks good.

Thanks
Babu

author reviewer
#9 lore raw

PATCH v5 3/16 x86/resctrl: Add PLZA configuration definitions and data structures

In reply to Babu Moger

Privilege Level Zero Association (PLZA) enables the kernel to switch to different CLOSID and/or RMID than those used in user mode when entering kernel mode. CLOSID and RMID selection are independent and can be configured separately.

PLZA associations are programmed on a per-CPU basis through MSR_IA32_PQR_PLZA_ASSOC (0xc00003fc), which contains the kernel RMID and CLOSID values along with their corresponding enable bits.

Add the MSR definition and the msr_pqr_plza_assoc union to describe the register bitfield layout required for PLZA configuration and subsequent programming support.

---
v5: Sashiko reported:
https://sashiko.dev/#/patchset/cover.1783461016.git.babu.moger%40amd.com?part=3
Fix the union truncate issue on 32 bit systems by using u64. Updated the changelog and code comments.

v4: Re-wrote the changelog and code comment.

v3: No code changes. Patch order changed. Improved changelog.

v2: No changes. Just rebasing on top of the latest tip branch.

---
 arch/x86/include/asm/msr-index.h       |  1 +
 arch/x86/kernel/cpu/resctrl/internal.h | 47 ++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)
arch/x86/include/asm/msr-index.h +1 -0
index 3a8e51a0c9e8..849e8587631c 100644
@@ -1294,6 +1294,7 @@
 /* - AMD: */
 #define MSR_IA32_MBA_BW_BASE		0xc0000200
 #define MSR_IA32_SMBA_BW_BASE		0xc0000280
+#define MSR_IA32_PQR_PLZA_ASSOC		0xc00003fc
 #define MSR_IA32_L3_QOS_ABMC_CFG	0xc00003fd
 #define MSR_IA32_L3_QOS_EXT_CFG		0xc00003ff
 #define MSR_IA32_EVT_CFG_BASE		0xc0000400
arch/x86/kernel/cpu/resctrl/internal.h +47 -0

53 lines not on this page · raw message

Signature · 1 line
2.43.0
maintainer
#10 lore raw

Re: [PATCH v5 03/16] x86/resctrl: Add PLZA configuration definitions and data structures

Hi Babu,

arch/x86/kernel/cpu/resctrl/internal.h union l3_qos_abmc_cfg { · line 225

Quoted 9 lines · Babu Moger
arch/x86/kernel/cpu/resctrl/internal.h +1 -0
index e3cfa0c10e92..2f4c60487a5d 100644
@@ -222,6 +222,53 @@ union l3_qos_abmc_cfg {
 	unsigned long full;
 };
 
+/*

I understand that this is not specifically kernel-doc (since no /**) but it clearly follows the pattern and also needs to match the style used in this file. Considering this, please use custom that describes members first before the long description? With members described first the long description can then use @ when referring to the members.

arch/x86/kernel/cpu/resctrl/internal.h union l3_qos_abmc_cfg { · line 238

Quoted 13 lines
arch/x86/kernel/cpu/resctrl/internal.h +13 -0
+ * Privilege Level Zero Association (PLZA) is configured via
+ * MSR_IA32_PQR_PLZA_ASSOC. This MSR must be programmed on every CPU in
+ * a QoS domain. Each domain supports a single PLZA CLOSID and/or RMID
+ * association, and all fields except PLZA_EN must be programmed
+ * identically across the domain to ensure consistent behavior.
+ *
+ * RMID and CLOSID selection are controlled independently. When PLZA is
+ * enabled (plza_en = 1), CPL0 uses CLOSID and RMID values from
+ * MSR_IA32_PQR_PLZA_ASSOC depending on the corresponding enable bits.
+ * When PLZA is disabled (plza_en = 0), the CLOSID and RMID are always
+ * taken from MSR_IA32_PQR_ASSOC regardless of privilege level.
+ *
+ *   - rmid_en = 1: use the RMID programmed in this MSR.

"this MSR" -> "MSR_IA32_PQR_PLZA_ASSOC" or keeping text similar to the rmid_en = 0 scenario may make it easier to follow what the bit accomplishes:

	- @rmid_en = 1: use the RMID from MSR_IA32_PQR_PLZA_ASSOC if
			@plza_en = 1

arch/x86/kernel/cpu/resctrl/internal.h union l3_qos_abmc_cfg { · line 240

Quoted 2 lines
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
+ *   - rmid_en = 0: use the RMID from MSR_IA32_PQR_ASSOC.
+ *   - closid_en = 1: use the CLOSID programmed in this MSR.

same comment as for rmid_en bit:

	- @closid_en = 1: use the CLOSID from MSR_IA32_PQR_PLZA_ASSOC
			  if @plza_en = 1

arch/x86/kernel/cpu/resctrl/internal.h union l3_qos_abmc_cfg { · line 245

Quoted 5 lines
arch/x86/kernel/cpu/resctrl/internal.h +5 -0
+ *   - closid_en = 0: use the CLOSID from MSR_IA32_PQR_ASSOC.
+ *
+ * This allows PLZA to override only RMID, only CLOSID, or both. If both
+ * rmid_en and closid_en are clear, the effective behavior is the same as
+ * when PLZA is disabled, with RMID and CLOSID derived from

"derived from" -> "used from"?

Quoted 19 lines
arch/x86/kernel/cpu/resctrl/internal.h +19 -0
+ * MSR_IA32_PQR_ASSOC irrespective of privilege level.
+ *
+ * @rmid		: RMID programmed for PLZA.
+ * @reserved1		: Reserved.
+ * @rmid_en		: Enable RMID for PLZA.
+ * @closid		: CLOSID programmed for PLZA.
+ * @reserved2		: Reserved.
+ * @closid_en		: Enable CLOSID for PLZA.
+ * @reserved3		: Reserved.
+ * @plza_en		: Enable PLZA. When enabled, PLZA applies to the
+ *			  given CPU.
+ */
+union msr_pqr_plza_assoc {
+	struct {
+		u64	rmid		:12,
+			reserved1	:19,
+			rmid_en		: 1,
+			closid		: 4,
+			reserved2	:11,

arch/x86/kernel/cpu/resctrl/internal.h union l3_qos_abmc_cfg { · line 274

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/internal.h +7 -0
+			closid_en	: 1,
+			reserved3	:15,
+			plza_en		: 1;
+	} split;
+	u64	full;
+};
+
 void rdt_ctrl_update(void *arg);
 
 int rdt_get_l3_mon_config(struct rdt_resource *r);

Reinette

author reviewer
#11 lore raw

Re: [PATCH v5 03/16] x86/resctrl: Add PLZA configuration definitions and data structures

Hi Reinette,

Quoted 11 lines · Reinette Chatre

Hi Babu,

Quoted 8 lines · Babu Moger
arch/x86/kernel/cpu/resctrl/internal.h +0 -0
index e3cfa0c10e92..2f4c60487a5d 100644
@@ -222,6 +222,53 @@ union l3_qos_abmc_cfg {
  	unsigned long full;
  };
 
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/internal.h union l3_qos_abmc_cfg { · line 225

Quoted 1 line
arch/x86/kernel/cpu/resctrl/internal.h +1 -0
+/*

I understand that this is not specifically kernel-doc (since no /**) but it clearly follows the pattern and also needs to match the style used in this file. Considering this, please use custom that describes members first before the long description? With members described first the long description can then use @ when referring to the members.

Sure.

Quoted 15 lines
Quoted 4 lines
arch/x86/kernel/cpu/resctrl/internal.h +3 -0
+ * Privilege Level Zero Association (PLZA) is configured via
+ * MSR_IA32_PQR_PLZA_ASSOC. This MSR must be programmed on every CPU in
+ * a QoS domain. Each domain supports a single PLZA CLOSID and/or RMID

arch/x86/kernel/cpu/resctrl/internal.h union l3_qos_abmc_cfg { · line 238

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/internal.h +10 -0
+ * association, and all fields except PLZA_EN must be programmed
+ * identically across the domain to ensure consistent behavior.
+ *
+ * RMID and CLOSID selection are controlled independently. When PLZA is
+ * enabled (plza_en = 1), CPL0 uses CLOSID and RMID values from
+ * MSR_IA32_PQR_PLZA_ASSOC depending on the corresponding enable bits.
+ * When PLZA is disabled (plza_en = 0), the CLOSID and RMID are always
+ * taken from MSR_IA32_PQR_ASSOC regardless of privilege level.
+ *
+ *   - rmid_en = 1: use the RMID programmed in this MSR.
Quoted 4 lines

"this MSR" -> "MSR_IA32_PQR_PLZA_ASSOC" or keeping text similar to the rmid_en = 0 scenario may make it easier to follow what the bit accomplishes:

	- @rmid_en = 1: use the RMID from MSR_IA32_PQR_PLZA_ASSOC if
			@plza_en = 1

Sure.

Quoted 8 lines

arch/x86/kernel/cpu/resctrl/internal.h union l3_qos_abmc_cfg { · line 240

Quoted 3 lines
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
+ *   - rmid_en = 0: use the RMID from MSR_IA32_PQR_ASSOC.
+ *   - closid_en = 1: use the CLOSID programmed in this MSR.

same comment as for rmid_en bit:

	- @closid_en = 1: use the CLOSID from MSR_IA32_PQR_PLZA_ASSOC
			  if @plza_en = 1

Sure.

Quoted 8 lines

arch/x86/kernel/cpu/resctrl/internal.h union l3_qos_abmc_cfg { · line 245

Quoted 5 lines
arch/x86/kernel/cpu/resctrl/internal.h +5 -0
+ *   - closid_en = 0: use the CLOSID from MSR_IA32_PQR_ASSOC.
+ *
+ * This allows PLZA to override only RMID, only CLOSID, or both. If both
+ * rmid_en and closid_en are clear, the effective behavior is the same as
+ * when PLZA is disabled, with RMID and CLOSID derived from

"derived from" -> "used from"?

Sure.

Thanks
Babu

author reviewer
#12 lore raw

PATCH v5 4/16 fs/resctrl: Introduce kernel mode policy enum

In reply to Babu Moger

Kernel mode traffic can use different allocation and monitoring associations than the originating user task. On x86, Privilege Level Zero Association (PLZA) enables the kernel to switch to a different CLOSID/RMID when entering kernel mode.

Architectures need a common way to name kernel modes before resctrl can report what is active or what the platform supports.

Introduce enum resctrl_kernel_mode:
- RESCTRL_INHERIT_USER: Kernel mode inherits allocation and monitoring from the user task.
- RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU: Kernel mode may use allocation and/or monitoring associations that differ from the user task. On x86, CLOSID and RMID can be configured independently for kernel mode.

---
v5: Collapse the two global-assign modes into a single
RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU value. Update the changelog to match the enum names and descriptions in the code.

v4: Updated the changelog to be generic as possible.
Moved the enum resctrl_kernel_mode to include/linux/resctrl.h. Updated the code comments to be generic.
Removed resctrl_kmode_cfg from the code. This definition can be fs specific only and architectures dont need to know. Changed enum name to resctrl_kernel_mode from resctrl_kernel_modes.

v3: Removed resctrl_kmode definition.
Changed the kernel mode definitions to enum resctrl_kernel_modes. Used BIT() to set/test the features.
Added details to changelog.

v2: New patch to handle PLZA interfaces with /sys/fs/resctrl/info/ directory.

    https://lore.kernel.org/lkml/[email protected]/
---
 include/linux/resctrl.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
include/linux/resctrl.h +25 -0
index dd09c2ce9a0f..4245d1e65ccc 100644
@@ -704,6 +704,31 @@ int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable);
  */
 bool resctrl_arch_get_io_alloc_enabled(struct rdt_resource *r);
 
+/**
+ * enum resctrl_kernel_mode - Kernel mode control and monitoring association.
+ *
+ * @RESCTRL_INHERIT_USER:
+ *     Kernel mode inherits both allocation and monitoring associations
+ *     from the user space task. On x86, kernel uses the same CLOSID and
+ *     RMID as the user-space task.
+ *
+ * @RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU:
+ *     Kernel mode may use allocation and monitoring associations that
+ *     differ from the user task. On x86, CLOSID and RMID are configured
+ *     independently; either or both may differ from user mode.
+ *
+ *     All online CPUs are included by default. A subset may be selected
+ *     through the resctrl group interface, and a CTRL_MON or MON group
+ *     may be associated with this mode.
+ */
+enum resctrl_kernel_mode {
+	RESCTRL_INHERIT_USER,
+	RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU,
+	RESCTRL_KMODE_LAST = RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU
+};
+
+#define RESCTRL_NUM_KERNEL_MODES (RESCTRL_KMODE_LAST + 1)
+
 extern unsigned int resctrl_rmid_realloc_threshold;
 extern unsigned int resctrl_rmid_realloc_limit;
 
Signature · 1 line
2.43.0
maintainer
#13 lore raw

Re: [PATCH v5 04/16] fs/resctrl: Introduce kernel mode policy enum

Hi Babu,

Quoted 1 line · Babu Moger

Kernel mode traffic can use different allocation and monitoring

"traffic" -> "work" to not imply this is just about memory traffic but also includes cache allocation?

Quoted 16 lines

associations than the originating user task. On x86, Privilege Level Zero Association (PLZA) enables the kernel to switch to a different CLOSID/RMID when entering kernel mode.

Architectures need a common way to name kernel modes before resctrl can report what is active or what the platform supports.

Introduce enum resctrl_kernel_mode:
- RESCTRL_INHERIT_USER: Kernel mode inherits allocation and monitoring from the user task.
- RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU: Kernel mode may use allocation and/or monitoring associations that differ from the user task. On x86, CLOSID and RMID can be configured independently for kernel mode.

---

...

Quoted 12 lines
---
 include/linux/resctrl.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
include/linux/resctrl.h +0 -0
index dd09c2ce9a0f..4245d1e65ccc 100644
@@ -704,6 +704,31 @@ int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable);
  */
 bool resctrl_arch_get_io_alloc_enabled(struct rdt_resource *r);
 

include/linux/resctrl.h int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable); · line 716

Quoted 10 lines
include/linux/resctrl.h +10 -0
+/**
+ * enum resctrl_kernel_mode - Kernel mode control and monitoring association.
+ *
+ * @RESCTRL_INHERIT_USER:
+ *     Kernel mode inherits both allocation and monitoring associations
+ *     from the user space task. On x86, kernel uses the same CLOSID and
+ *     RMID as the user-space task.
+ *
+ * @RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU:
+ *     Kernel mode may use allocation and monitoring associations that

Why is this "may use"? Could this be made more accurate? Consider, for example:
All kernel mode work uses the same allocation and/or monitoring association via an assigned CTRL_MON or MON group. The mode can be enabled/disabled per-CPU. When the mode is disabled on a CPU then the kernel work on that CPU inherits the allocation and monitoring association from the user space task, effectively the kernel mode becomes RESCTRL_INHERIT_USER on that CPU.

include/linux/resctrl.h int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable); · line 718

Quoted 2 lines
include/linux/resctrl.h +2 -0
+ *     differ from the user task. On x86, CLOSID and RMID are configured
+ *     independently; either or both may differ from user mode.

Please first provide all details that support what resctrl fs exposes to user space before, if at all, adding any x86 specific details.

include/linux/resctrl.h int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable); · line 722

Quoted 4 lines
include/linux/resctrl.h +4 -0
+ *
+ *     All online CPUs are included by default. A subset may be selected
+ *     through the resctrl group interface, and a CTRL_MON or MON group
+ *     may be associated with this mode.

Please note that the word "associated" appears in multiple contexts here.

include/linux/resctrl.h int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable); · line 726

Quoted 4 lines
include/linux/resctrl.h +4 -0
+ */
+enum resctrl_kernel_mode {
+	RESCTRL_INHERIT_USER,
+	RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU,

Something that stands out in this series is the multiple occurrences of "assigned" in the new interface. What do you think of just dropping "assign" from the kernel mode name?

include/linux/resctrl.h int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable); · line 734

Quoted 8 lines
include/linux/resctrl.h +5 -0
+	RESCTRL_KMODE_LAST = RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU
+};
+
+#define RESCTRL_NUM_KERNEL_MODES (RESCTRL_KMODE_LAST + 1)
+
 extern unsigned int resctrl_rmid_realloc_threshold;
 extern unsigned int resctrl_rmid_realloc_limit;
 

Reinette

author reviewer
#14 lore raw

Re: [PATCH v5 04/16] fs/resctrl: Introduce kernel mode policy enum

Hi Reinette,

Quoted 7 lines · Reinette Chatre

Hi Babu,

Quoted 1 line · Babu Moger

Kernel mode traffic can use different allocation and monitoring

"traffic" -> "work" to not imply this is just about memory traffic but also includes cache allocation?

Sure.

Quoted 43 lines
Quoted 17 lines

associations than the originating user task. On x86, Privilege Level Zero Association (PLZA) enables the kernel to switch to a different CLOSID/RMID when entering kernel mode.

Architectures need a common way to name kernel modes before resctrl can report what is active or what the platform supports.

Introduce enum resctrl_kernel_mode:
- RESCTRL_INHERIT_USER: Kernel mode inherits allocation and monitoring from the user task.
- RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU: Kernel mode may use allocation and/or monitoring associations that differ from the user task. On x86, CLOSID and RMID can be configured independently for kernel mode.

---

...

Quoted 12 lines
---
  include/linux/resctrl.h | 25 +++++++++++++++++++++++++
  1 file changed, 25 insertions(+)
include/linux/resctrl.h +0 -0
index dd09c2ce9a0f..4245d1e65ccc 100644
@@ -704,6 +704,31 @@ int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable);
   */
  bool resctrl_arch_get_io_alloc_enabled(struct rdt_resource *r);
 

include/linux/resctrl.h int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable); · line 716

Quoted 10 lines
include/linux/resctrl.h +10 -0
+/**
+ * enum resctrl_kernel_mode - Kernel mode control and monitoring association.
+ *
+ * @RESCTRL_INHERIT_USER:
+ *     Kernel mode inherits both allocation and monitoring associations
+ *     from the user space task. On x86, kernel uses the same CLOSID and
+ *     RMID as the user-space task.
+ *
+ * @RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU:
+ *     Kernel mode may use allocation and monitoring associations that
Quoted 9 lines

Why is this "may use"? Could this be made more accurate? Consider, for example:
All kernel mode work uses the same allocation and/or monitoring association via an assigned CTRL_MON or MON group. The mode can be enabled/disabled per-CPU. When the mode is disabled on a CPU then the kernel work on that CPU inherits the allocation and monitoring association from the user space task, effectively the kernel mode becomes RESCTRL_INHERIT_USER on that CPU.

Sure. Thanks.

Quoted 7 lines

include/linux/resctrl.h int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable); · line 718

Quoted 3 lines
include/linux/resctrl.h +2 -0
+ *     differ from the user task. On x86, CLOSID and RMID are configured
+ *     independently; either or both may differ from user mode.

Please first provide all details that support what resctrl fs exposes to user space before, if at all, adding any x86 specific details.

Sure.

Quoted 6 lines

include/linux/resctrl.h int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable); · line 722

Quoted 4 lines
include/linux/resctrl.h +4 -0
+ *
+ *     All online CPUs are included by default. A subset may be selected
+ *     through the resctrl group interface, and a CTRL_MON or MON group
+ *     may be associated with this mode.

Please note that the word "associated" appears in multiple contexts here.

"assigned" might work better here.

Quoted 9 lines

include/linux/resctrl.h int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable); · line 726

Quoted 5 lines
include/linux/resctrl.h +4 -0
+ */
+enum resctrl_kernel_mode {
+	RESCTRL_INHERIT_USER,
+	RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU,

Something that stands out in this series is the multiple occurrences of "assigned" in the new interface. What do you think of just dropping "assign" from the kernel mode name?

Actually, I was thinking about shortening the name here.

Let's remove "assign" from here.

Thanks
Babu
.

author reviewer
#15 lore raw

PATCH v5 5/16 x86,fs/resctrl: Introduce architecture hooks to program kernel mode

In reply to Babu Moger

Kernel modes defined by enum resctrl_kernel_mode must be applied on the CPUs when user space activates, deactivates, or updates a configuration.

Generic resctrl has no architecture hook to apply these modes across a CPU mask when the active mode changes.

Add resctrl_arch_configure_kmode() to program kernel mode allocation and monitoring associations on @cpu_mask. Accept separate assign_ctrl and assign_mon parameters so CLOSID and RMID can be assigned independently.

Implement the x86 hook to program per-CPU PLZA settings. On x86, PLZA programs these associations per CPU, with CLOSID and RMID configured independently.

Provide an MPAM stub so the filesystem layer can call the hook on systems without PLZA.

---
v5: Fix kernel-doc for resctrl_arch_configure_kmode(), wire assign_ctrl
through to PLZA closid_en, and update the changelog.
Add calling context in API doc.

v4: Added assign_mon parameter in resctrl_arch_configure_kmode() to program the RMID
as discussed in below.
https://lore.kernel.org/lkml/[email protected]/
Reintroduce independent monitoring assignment via assign_mon after removing the task-based PLZA approach in v3.
Changed cpumask type to "const struct cpumask *cpu_mask".
Added MPAM stub to avoid any linking issues when resctrl_arch_configure_kmode() is called from FS layer. Thanks to Qinyun.
Re-wrote the changelog to be generic.
Updated code comments.
v3: Removed task based PLZA implementation so related changes are removed.
Per-task RMID handling is replaced by group type selection in the fs layer. Updated the change log with details.
Removed resctrl_arch_set_kmode() as arch only provides the modes supported. It is FS which decided which mode to apply.
v2: Updated the commit message to include the sequence of steps to enable PLZA.
Added mode code comments for clarity.
Added kmode to function names to be generic.

---
 arch/x86/kernel/cpu/resctrl/ctrlmondata.c | 38 +++++++++++++++++++++++
 drivers/resctrl/mpam_resctrl.c            |  6 ++++
 include/linux/resctrl.h                   | 33 ++++++++++++++++++++
 3 files changed, 77 insertions(+)
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +38 -0
index e74f1ed54b86..40fd5e31c94e 100644
@@ -131,3 +131,41 @@ int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable)
 
 	return 0;
 }
+
+static void resctrl_kmode_set_one_amd(void *arg)
+{
+	union msr_pqr_plza_assoc *plza = arg;
+
+	wrmsrq(MSR_IA32_PQR_PLZA_ASSOC, plza->full);
+}
+
+/*
+ * Program Privilege Level Zero Association (PLZA) on @cpu_mask.
+ *
+ * When @enable is true, kernel mode allocation on @cpu_mask uses @closid from
+ * MSR_IA32_PQR_PLZA_ASSOC if @assign_ctrl is true, otherwise the CLOSID from
+ * MSR_IA32_PQR_ASSOC. Kernel mode monitoring uses @rmid from
+ * MSR_IA32_PQR_PLZA_ASSOC if @assign_mon is true, otherwise the RMID of the
+ * current task.
+ *
+ * @cpu_mask:	CPUs whose PLZA MSR should be updated.
+ * @closid:	CLOSID to use for kernel mode allocation when @assign_ctrl is true.
+ * @assign_ctrl: Whether PLZA should provide the kernel mode CLOSID.
+ * @rmid:	RMID to use for kernel mode monitoring when @assign_mon is true.
+ * @assign_mon: Whether PLZA should provide the kernel mode RMID.
+ * @enable:	Whether PLZA should provide the kernel mode association.
+ */
+void resctrl_arch_configure_kmode(const struct cpumask *cpu_mask, u32 closid,
+				  bool assign_ctrl, u32 rmid,
+				  bool assign_mon, bool enable)
+{
+	union msr_pqr_plza_assoc plza = { 0 };
+
+	plza.split.rmid = rmid;
+	plza.split.rmid_en = assign_mon;
+	plza.split.closid = closid;
+	plza.split.closid_en = assign_ctrl;
+	plza.split.plza_en = enable;
+
+	on_each_cpu_mask(cpu_mask, resctrl_kmode_set_one_amd, &plza, 1);
+}
drivers/resctrl/mpam_resctrl.c +6 -0
index 9d223057953a..286284ac8423 100644
@@ -139,6 +139,12 @@ bool resctrl_arch_get_io_alloc_enabled(struct rdt_resource *r)
 	return false;
 }
 
+void resctrl_arch_configure_kmode(const struct cpumask *cpu_mask, u32 closid,
+				  bool assign_ctrl, u32 rmid, bool assign_mon,
+				  bool enable)
+{
+}
+
 void resctrl_arch_pre_mount(void)
 {
 }
include/linux/resctrl.h +33 -0
index 4245d1e65ccc..8b30eef835aa 100644
@@ -729,6 +729,39 @@ enum resctrl_kernel_mode {
 
 #define RESCTRL_NUM_KERNEL_MODES (RESCTRL_KMODE_LAST + 1)
 
+/**
+ * resctrl_arch_configure_kmode() - Program kernel mode association
+ * @cpu_mask:	CPUs to assign the kernel mode on.
+ * @closid:	CLOSID that matches the RMID to program kernel mode. Depending
+ *		on the architecture, the counter may match traffic of both
+ *		@closid and @rmid, or @rmid only.
+ * @assign_ctrl: true to assign @closid for kernel mode; false to inherit
+ *		association from the user-space task.
+ * @rmid:	RMID to program the kernel mode. Some architectures may use
+ *		CLOSID/RMID separately, others will consider them together.
+ * @assign_mon:	true to assign @rmid for kernel mode; false to inherit
+ *		monitoring association from the user-space task.
+ * @enable:	true to enable kernel mode association on CPUs in @cpu_mask;
+ *		false to disable kernel mode.
+ *
+ * The function can be called in the following scenarios:
+ * - If a per-cpu kernel mode is active when user space switches to a new
+ *   per-cpu kernel mode then resctrl_arch_configure_kmode() will first be
+ *   called to de-activate the active kernel mode on all CPUs that the
+ *   kernel mode is active on.
+ * - When user space switches to a new per-cpu kernel mode then
+ *   resctrl_arch_configure_kmode() is called with cpu_online_mask.
+ * - When user space adds a CPU to an active per-cpu kernel mode.
+ * - When user space removes a CPU from an active per-cpu kernel mode.
+ * - resctrl fs will always provide the same closid, assign_ctrl, rmid,
+ *   and assign_mon parameters when activating a kernel mode, all
+ *   interactions (adding/removing CPU) while the kernel mode is active,
+ *   as well as when de-activating the kernel mode.
+ */
+void resctrl_arch_configure_kmode(const struct cpumask *cpu_mask, u32 closid,
+				  bool assign_ctrl, u32 rmid, bool assign_mon,
+				  bool enable);
+
 extern unsigned int resctrl_rmid_realloc_threshold;
 extern unsigned int resctrl_rmid_realloc_limit;
 
Signature · 1 line
2.43.0
maintainer
#16 lore raw

Re: [PATCH v5 05/16] x86,fs/resctrl: Introduce architecture hooks to program kernel mode

Hi Babu,

Quoted 3 lines · Babu Moger

Kernel modes defined by enum resctrl_kernel_mode must be applied on the CPUs when user space activates, deactivates, or updates a configuration.

Not necessarily. This is just what PLZA/RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU requires, no? The "applied on the CPUs" seems specific to the RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU mode - hence the name includes "enable per CPU". Above text implies that all possible kernel modes require this, we know that upcoming ones don't so this could just be specific to the only kernel mode that needs it?

Quoted 3 lines

Generic resctrl has no architecture hook to apply these modes across a CPU mask when the active mode changes.

I cannot believe this. v3 of this series wrote the changelogs of this new feature enabling as bugfixes. I asked you several times in v3 to not do this:

https://lore.kernel.org/lkml/[email protected]/
https://lore.kernel.org/lkml/[email protected]/
https://lore.kernel.org/lkml/[email protected]/

v4 did not follow that style ... but now this style of presenting enabling code as bugfix is back in v5! In v2 I already expressed frustration that every new series seemingly starts from scratch

https://lore.kernel.org/lkml/[email protected]/

Now a new version seems to forget feedback from just two versions ago :(

Quoted 4 lines

Add resctrl_arch_configure_kmode() to program kernel mode allocation and monitoring associations on @cpu_mask. Accept separate assign_ctrl and assign_mon parameters so CLOSID and RMID can be assigned independently.

Below is just a sampling from the last two versions of me asking you to not just verbatim describe the code:

https://lore.kernel.org/lkml/[email protected]/ V3
https://lore.kernel.org/lkml/[email protected]/ V3
https://lore.kernel.org/lkml/[email protected]/ V3
https://lore.kernel.org/lkml/[email protected]/ V4
https://lore.kernel.org/lkml/[email protected]/ V4
https://lore.kernel.org/lkml/[email protected]/ V4

Again, please do not just verbatim describe what clearly can be seen from the patch. Use the changelog to describe why the code behaves a certain way.

Maybe you need this request to come from Boris instead before you start following the guidance? Here are some examples:

https://lore.kernel.org/all/20240702124524.GEZoP2ZKcTcKl1ca1R@fat_crate.local/
https://lore.kernel.org/lkml/20250911165433.GBaML-yTUZHkywuJIe@fat_crate.local/

From here on the changelogs all seem to have this strange pattern of:
"Architecture needs X"

"Architecture is missing X"

"Verbatim description of X implementation"

Apart from the issues mentioned above this interchangeable repetition turns the changelogs into a blur. The x86 format for changelogs is described in Documentation/process/maintainer-tip.rst. Just follow that. This should not be new to you.

Do not expect further comments on any of the changelogs that follow. I consider them all unusable.

I clearly demonstrate above that you ignore my feedback. There really seems no reason for me to provide any. I'll make a final attempt to provide feedback to *just* the patches (as much as I can without being able to use the changelogs) to try and help this work make progress.

Quoted 9 lines

Implement the x86 hook to program per-CPU PLZA settings. On x86, PLZA programs these associations per CPU, with CLOSID and RMID configured independently.

Provide an MPAM stub so the filesystem layer can call the hook on systems without PLZA.

---

...

Quoted 3 lines
---
 arch/x86/kernel/cpu/resctrl/ctrlmondata.c | 38 +++++++++++++++++++++++
 drivers/resctrl/mpam_resctrl.c            |  6 ++++

Needs "arm" in subject prefix.

Quoted 12 lines
 include/linux/resctrl.h                   | 33 ++++++++++++++++++++
 3 files changed, 77 insertions(+)
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +1 -0
index e74f1ed54b86..40fd5e31c94e 100644
@@ -131,3 +131,41 @@ int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable)
 
 	return 0;
 }
+

arch/x86/kernel/cpu/resctrl/ctrlmondata.c int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable) · line 144

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +10 -0
+static void resctrl_kmode_set_one_amd(void *arg)
+{
+	union msr_pqr_plza_assoc *plza = arg;
+
+	wrmsrq(MSR_IA32_PQR_PLZA_ASSOC, plza->full);
+}
+
+/*
+ * Program Privilege Level Zero Association (PLZA) on @cpu_mask.
+ *

Please follow the custom with function parameters described first, followed by description.

arch/x86/kernel/cpu/resctrl/ctrlmondata.c int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable) · line 149

Quoted 5 lines
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +5 -0
+ * When @enable is true, kernel mode allocation on @cpu_mask uses @closid from
+ * MSR_IA32_PQR_PLZA_ASSOC if @assign_ctrl is true, otherwise the CLOSID from
+ * MSR_IA32_PQR_ASSOC. Kernel mode monitoring uses @rmid from
+ * MSR_IA32_PQR_PLZA_ASSOC if @assign_mon is true, otherwise the RMID of the
+ * current task.

This just seems to duplicate the description of union msr_pqr_plza_assoc?

arch/x86/kernel/cpu/resctrl/ctrlmondata.c int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable) · line 152

Quoted 3 lines
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +3 -0
+ *
+ * @cpu_mask:	CPUs whose PLZA MSR should be updated.
+ * @closid:	CLOSID to use for kernel mode allocation when @assign_ctrl is true.

Contrary to what the comment states the closid parameter is always programmed, whether assign_ctrl is true or false. A valid closid is thus expected to always be provided?

arch/x86/kernel/cpu/resctrl/ctrlmondata.c int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable) · line 154

Quoted 2 lines
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +2 -0
+ * @assign_ctrl: Whether PLZA should provide the kernel mode CLOSID.
+ * @rmid:	RMID to use for kernel mode monitoring when @assign_mon is true.

Same comment.

Quoted 39 lines
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +17 -0
+ * @assign_mon: Whether PLZA should provide the kernel mode RMID.
+ * @enable:	Whether PLZA should provide the kernel mode association.
+ */
+void resctrl_arch_configure_kmode(const struct cpumask *cpu_mask, u32 closid,
+				  bool assign_ctrl, u32 rmid,
+				  bool assign_mon, bool enable)
+{
+	union msr_pqr_plza_assoc plza = { 0 };
+
+	plza.split.rmid = rmid;
+	plza.split.rmid_en = assign_mon;
+	plza.split.closid = closid;
+	plza.split.closid_en = assign_ctrl;
+	plza.split.plza_en = enable;
+
+	on_each_cpu_mask(cpu_mask, resctrl_kmode_set_one_amd, &plza, 1);
+}
drivers/resctrl/mpam_resctrl.c +6 -0
index 9d223057953a..286284ac8423 100644
@@ -139,6 +139,12 @@ bool resctrl_arch_get_io_alloc_enabled(struct rdt_resource *r)
 	return false;
 }
 
+void resctrl_arch_configure_kmode(const struct cpumask *cpu_mask, u32 closid,
+				  bool assign_ctrl, u32 rmid, bool assign_mon,
+				  bool enable)
+{
+}
+
 void resctrl_arch_pre_mount(void)
 {
 }
include/linux/resctrl.h +0 -0
index 4245d1e65ccc..8b30eef835aa 100644

include/linux/resctrl.h enum resctrl_kernel_mode { · line 733

Quoted 5 lines
include/linux/resctrl.h +2 -0
@@ -729,6 +729,39 @@ enum resctrl_kernel_mode {
 
 #define RESCTRL_NUM_KERNEL_MODES (RESCTRL_KMODE_LAST + 1)
 
+/**
+ * resctrl_arch_configure_kmode() - Program kernel mode association

resctrl_arch_configure_kmode() implies a generic kernel mode callback but the parameters are specific to the global, per-CPU mode. I expect that either the kernel mode self be a parameter or the callback be unique to the kernel mode.
To simplify the parameter management this could be the latter and renamed
to something like "resctrl_arch_configure_kmode_global()"/"resctrl_arch_configure_global_kmode()" ?

Quoted 4 lines
include/linux/resctrl.h +4 -0
+ * @cpu_mask:	CPUs to assign the kernel mode on.
+ * @closid:	CLOSID that matches the RMID to program kernel mode. Depending
+ *		on the architecture, the counter may match traffic of both
+ *		@closid and @rmid, or @rmid only.

include/linux/resctrl.h enum resctrl_kernel_mode { · line 747

Quoted 10 lines
include/linux/resctrl.h +10 -0
+ * @assign_ctrl: true to assign @closid for kernel mode; false to inherit
+ *		association from the user-space task.
+ * @rmid:	RMID to program the kernel mode. Some architectures may use
+ *		CLOSID/RMID separately, others will consider them together.
+ * @assign_mon:	true to assign @rmid for kernel mode; false to inherit
+ *		monitoring association from the user-space task.
+ * @enable:	true to enable kernel mode association on CPUs in @cpu_mask;
+ *		false to disable kernel mode.
+ *
+ * The function can be called in the following scenarios:

"can be" -> "is"?

include/linux/resctrl.h enum resctrl_kernel_mode { · line 748

Quoted 1 line
include/linux/resctrl.h +1 -0
+ * - If a per-cpu kernel mode is active when user space switches to a new

per-cpu -> per-CPU

include/linux/resctrl.h enum resctrl_kernel_mode { · line 749

Quoted 1 line
include/linux/resctrl.h +1 -0
+ *   per-cpu kernel mode then resctrl_arch_configure_kmode() will first be

"a new per-cpu kernel mode" - what does this refer to? There is only one per-CPU kernel mode, no? It may help to refer to the kernel modes explicitly by their enum value to be clear which modes this callback applies to.

include/linux/resctrl.h enum resctrl_kernel_mode { · line 755

Quoted 6 lines
include/linux/resctrl.h +6 -0
+ *   called to de-activate the active kernel mode on all CPUs that the
+ *   kernel mode is active on.
+ * - When user space switches to a new per-cpu kernel mode then
+ *   resctrl_arch_configure_kmode() is called with cpu_online_mask.
+ * - When user space adds a CPU to an active per-cpu kernel mode.
+ * - When user space removes a CPU from an active per-cpu kernel mode.

Above scenarios all have the "per-cpu kernel mode" in description that confirms that this callback is dedicated to this single kernel mode and not actually a generic "enable kernel mode" callback.

Below does not seem to fall under "scenario" like the above but actually represents a contract between fs and arch that can be separated and highlighted.

include/linux/resctrl.h enum resctrl_kernel_mode { · line 757

Quoted 2 lines
include/linux/resctrl.h +2 -0
+ * - resctrl fs will always provide the same closid, assign_ctrl, rmid,
+ *   and assign_mon parameters when activating a kernel mode, all

"a kernel mode" -> this callback is not generic so it should be specific to which modes it applies to.

include/linux/resctrl.h enum resctrl_kernel_mode { · line 767

Quoted 10 lines
include/linux/resctrl.h +7 -0
+ *   interactions (adding/removing CPU) while the kernel mode is active,
+ *   as well as when de-activating the kernel mode.
+ */
+void resctrl_arch_configure_kmode(const struct cpumask *cpu_mask, u32 closid,
+				  bool assign_ctrl, u32 rmid, bool assign_mon,
+				  bool enable);
+
 extern unsigned int resctrl_rmid_realloc_threshold;
 extern unsigned int resctrl_rmid_realloc_limit;
 

Reinette

author reviewer
#17 lore raw

Re: [PATCH v5 05/16] x86,fs/resctrl: Introduce architecture hooks to program kernel mode

Hi Reinette,

Quoted 7 lines · Reinette Chatre

Hi Babu,

Quoted 3 lines · Babu Moger

Kernel modes defined by enum resctrl_kernel_mode must be applied on the CPUs when user space activates, deactivates, or updates a configuration.

Quoted 6 lines

Not necessarily. This is just what PLZA/RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU requires, no? The "applied on the CPUs" seems specific to the RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU mode - hence the name includes "enable per CPU". Above text implies that all possible kernel modes require this, we know that upcoming ones don't so this could just be specific to the only kernel mode that needs it?

That is correct. Will rephrase it.

Quoted 12 lines
Quoted 4 lines

Generic resctrl has no architecture hook to apply these modes across a CPU mask when the active mode changes.

I cannot believe this. v3 of this series wrote the changelogs of this new feature enabling as bugfixes. I asked you several times in v3 to not do this:

https://lore.kernel.org/lkml/[email protected]/
https://lore.kernel.org/lkml/[email protected]/
https://lore.kernel.org/lkml/[email protected]/

Quoted 7 lines

v4 did not follow that style ... but now this style of presenting enabling code as bugfix is back in v5! In v2 I already expressed frustration that every new series seemingly starts from scratch

https://lore.kernel.org/lkml/[email protected]/

Now a new version seems to forget feedback from just two versions ago :(

My apologies. Thank you for the feedback. I'll address these issues and aim for a better version in the next revision.

Quoted 37 lines
Quoted 5 lines

Add resctrl_arch_configure_kmode() to program kernel mode allocation and monitoring associations on @cpu_mask. Accept separate assign_ctrl and assign_mon parameters so CLOSID and RMID can be assigned independently.

Below is just a sampling from the last two versions of me asking you to not just verbatim describe the code:

https://lore.kernel.org/lkml/[email protected]/ V3
https://lore.kernel.org/lkml/[email protected]/ V3
https://lore.kernel.org/lkml/[email protected]/ V3
https://lore.kernel.org/lkml/[email protected]/ V4
https://lore.kernel.org/lkml/[email protected]/ V4
https://lore.kernel.org/lkml/[email protected]/ V4

Again, please do not just verbatim describe what clearly can be seen from the patch. Use the changelog to describe why the code behaves a certain way.

Maybe you need this request to come from Boris instead before you start following the guidance? Here are some examples:

https://lore.kernel.org/all/20240702124524.GEZoP2ZKcTcKl1ca1R@fat_crate.local/
https://lore.kernel.org/lkml/20250911165433.GBaML-yTUZHkywuJIe@fat_crate.local/

Quoted 1 line

From here on the changelogs all seem to have this strange pattern of:

"Architecture needs X"

"Architecture is missing X"

"Verbatim description of X implementation"

Apart from the issues mentioned above this interchangeable repetition turns the changelogs into a blur. The x86 format for changelogs is described in Documentation/process/maintainer-tip.rst. Just follow that. This should not be new to you.

Quoted 7 lines

Do not expect further comments on any of the changelogs that follow. I consider them all unusable.

I clearly demonstrate above that you ignore my feedback. There really seems no reason for me to provide any. I'll make a final attempt to provide feedback to *just* the patches (as much as I can without being able to use the changelogs) to try and help this work make progress.

Again, my apologies. It wasn't intentional. I try to address your feedback in every revision, but clearly I'm still missing the mark here.

I'll keep working on it and do my best to improve with each version. :(

Thanks for your patience and continued feedback. Please do not hesitate to call it.

Quoted 11 lines
Quoted 10 lines

Implement the x86 hook to program per-CPU PLZA settings. On x86, PLZA programs these associations per CPU, with CLOSID and RMID configured independently.

Provide an MPAM stub so the filesystem layer can call the hook on systems without PLZA.

---

Quoted 7 lines

...

Quoted 3 lines
---
  arch/x86/kernel/cpu/resctrl/ctrlmondata.c | 38 +++++++++++++++++++++++
  drivers/resctrl/mpam_resctrl.c            |  6 ++++

Needs "arm" in subject prefix.

Sure.

Quoted 10 lines
Quoted 10 lines
  include/linux/resctrl.h                   | 33 ++++++++++++++++++++
  3 files changed, 77 insertions(+)
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +0 -0
index e74f1ed54b86..40fd5e31c94e 100644
@@ -131,3 +131,41 @@ int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable)
 
Quoted 16 lines

arch/x86/kernel/cpu/resctrl/ctrlmondata.c int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable) · line 144

Quoted 13 lines
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +11 -0
  	return 0;
  }
+
+static void resctrl_kmode_set_one_amd(void *arg)
+{
+	union msr_pqr_plza_assoc *plza = arg;
+
+	wrmsrq(MSR_IA32_PQR_PLZA_ASSOC, plza->full);
+}
+
+/*
+ * Program Privilege Level Zero Association (PLZA) on @cpu_mask.
+ *

Please follow the custom with function parameters described first, followed by description.

Sure.

Quoted 8 lines

arch/x86/kernel/cpu/resctrl/ctrlmondata.c int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable) · line 149

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +5 -0
+ * When @enable is true, kernel mode allocation on @cpu_mask uses @closid from
+ * MSR_IA32_PQR_PLZA_ASSOC if @assign_ctrl is true, otherwise the CLOSID from
+ * MSR_IA32_PQR_ASSOC. Kernel mode monitoring uses @rmid from
+ * MSR_IA32_PQR_PLZA_ASSOC if @assign_mon is true, otherwise the RMID of the
+ * current task.

This just seems to duplicate the description of union msr_pqr_plza_assoc?

Yes. Some of it. Let me shorten it little bit for the context here.

Quoted 7 lines

arch/x86/kernel/cpu/resctrl/ctrlmondata.c int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable) · line 152

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +3 -0
+ *
+ * @cpu_mask:	CPUs whose PLZA MSR should be updated.
+ * @closid:	CLOSID to use for kernel mode allocation when @assign_ctrl is true.

Contrary to what the comment states the closid parameter is always programmed, whether assign_ctrl is true or false. A valid closid is thus expected to always be provided?

Yes. Will change it.

Quoted 6 lines

arch/x86/kernel/cpu/resctrl/ctrlmondata.c int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable) · line 154

Quoted 3 lines
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +2 -0
+ * @assign_ctrl: Whether PLZA should provide the kernel mode CLOSID.
+ * @rmid:	RMID to use for kernel mode monitoring when @assign_mon is true.

Same comment.

Sure.

Quoted 42 lines
Quoted 42 lines
arch/x86/kernel/cpu/resctrl/ctrlmondata.c +17 -0
+ * @assign_mon: Whether PLZA should provide the kernel mode RMID.
+ * @enable:	Whether PLZA should provide the kernel mode association.
+ */
+void resctrl_arch_configure_kmode(const struct cpumask *cpu_mask, u32 closid,
+				  bool assign_ctrl, u32 rmid,
+				  bool assign_mon, bool enable)
+{
+	union msr_pqr_plza_assoc plza = { 0 };
+
+	plza.split.rmid = rmid;
+	plza.split.rmid_en = assign_mon;
+	plza.split.closid = closid;
+	plza.split.closid_en = assign_ctrl;
+	plza.split.plza_en = enable;
+
+	on_each_cpu_mask(cpu_mask, resctrl_kmode_set_one_amd, &plza, 1);
+}
drivers/resctrl/mpam_resctrl.c +6 -0
index 9d223057953a..286284ac8423 100644
@@ -139,6 +139,12 @@ bool resctrl_arch_get_io_alloc_enabled(struct rdt_resource *r)
  	return false;
  }
 
+void resctrl_arch_configure_kmode(const struct cpumask *cpu_mask, u32 closid,
+				  bool assign_ctrl, u32 rmid, bool assign_mon,
+				  bool enable)
+{
+}
+
  void resctrl_arch_pre_mount(void)
  {
  }
include/linux/resctrl.h +0 -0
index 4245d1e65ccc..8b30eef835aa 100644
@@ -729,6 +729,39 @@ enum resctrl_kernel_mode {
 
  #define RESCTRL_NUM_KERNEL_MODES (RESCTRL_KMODE_LAST + 1)
 
Quoted 8 lines

include/linux/resctrl.h enum resctrl_kernel_mode { · line 733

Quoted 2 lines
include/linux/resctrl.h +2 -0
+/**
+ * resctrl_arch_configure_kmode() - Program kernel mode association

resctrl_arch_configure_kmode() implies a generic kernel mode callback but the parameters are specific to the global, per-CPU mode. I expect that either the kernel mode self be a parameter or the callback be unique to the kernel mode.
To simplify the parameter management this could be the latter and renamed
to something like "resctrl_arch_configure_kmode_global()"/"resctrl_arch_configure_global_kmode()" ?

Yes, Sure. Will change it to "resctrl_arch_configure_kmode_global()".

Quoted 16 lines
Quoted 5 lines
include/linux/resctrl.h +4 -0
+ * @cpu_mask:	CPUs to assign the kernel mode on.
+ * @closid:	CLOSID that matches the RMID to program kernel mode. Depending
+ *		on the architecture, the counter may match traffic of both
+ *		@closid and @rmid, or @rmid only.

include/linux/resctrl.h enum resctrl_kernel_mode { · line 747

Quoted 10 lines
include/linux/resctrl.h +10 -0
+ * @assign_ctrl: true to assign @closid for kernel mode; false to inherit
+ *		association from the user-space task.
+ * @rmid:	RMID to program the kernel mode. Some architectures may use
+ *		CLOSID/RMID separately, others will consider them together.
+ * @assign_mon:	true to assign @rmid for kernel mode; false to inherit
+ *		monitoring association from the user-space task.
+ * @enable:	true to enable kernel mode association on CPUs in @cpu_mask;
+ *		false to disable kernel mode.
+ *
+ * The function can be called in the following scenarios:
Quoted 1 line

"can be" -> "is"?

ok.>

Quoted 3 lines

include/linux/resctrl.h enum resctrl_kernel_mode { · line 748

Quoted 1 line
include/linux/resctrl.h +1 -0
+ * - If a per-cpu kernel mode is active when user space switches to a new

per-cpu -> per-CPU

sure.

Quoted 6 lines

include/linux/resctrl.h enum resctrl_kernel_mode { · line 749

Quoted 2 lines
include/linux/resctrl.h +1 -0
+ *   per-cpu kernel mode then resctrl_arch_configure_kmode() will first be

"a new per-cpu kernel mode" - what does this refer to? There is only one per-CPU kernel mode, no? It may help to refer to the kernel modes explicitly by their enum value to be clear which modes this callback applies to.

Yes.

"RESCTRL_GLOBAL_ENABLE_PER_CPU kernel mode."

Quoted 8 lines

include/linux/resctrl.h enum resctrl_kernel_mode { · line 755

Quoted 7 lines
include/linux/resctrl.h +6 -0
+ *   called to de-activate the active kernel mode on all CPUs that the
+ *   kernel mode is active on.
+ * - When user space switches to a new per-cpu kernel mode then
+ *   resctrl_arch_configure_kmode() is called with cpu_online_mask.
+ * - When user space adds a CPU to an active per-cpu kernel mode.
+ * - When user space removes a CPU from an active per-cpu kernel mode.
Quoted 7 lines

Above scenarios all have the "per-cpu kernel mode" in description that confirms that this callback is dedicated to this single kernel mode and not actually a generic "enable kernel mode" callback.

Below does not seem to fall under "scenario" like the above but actually represents a contract between fs and arch that can be separated and highlighted.

I can add a line about the difference.

Quoted 6 lines

include/linux/resctrl.h enum resctrl_kernel_mode { · line 757

Quoted 3 lines
include/linux/resctrl.h +2 -0
+ * - resctrl fs will always provide the same closid, assign_ctrl, rmid,
+ *   and assign_mon parameters when activating a kernel mode, all

"a kernel mode" -> this callback is not generic so it should be specific to which modes it applies to.

Will mention the kernel mode name here.

Thanks
Babu

author reviewer
#18 lore raw

PATCH v5 6/16 fs/resctrl: Introduce kernel mode states for resctrl

In reply to Babu Moger

Architectures need the generic resctrl filesystem to track supported kernel modes, the active mode, and per-dimension assignment state.

Generic resctrl has no place to store this policy state today.

Add struct resctrl_kmode_cfg to hold supported modes, active mode, control/monitoring assignment state, and the bound resource group. Initialize defaults from resctrl_arch_alloc_capable() and resctrl_arch_mon_capable() during resctrl_init().

---
v5: Replace per-mode registration helpers with a single resctrl_kmode_cfg
structure. Derive ctrl_en and mon_en from resctrl_arch_alloc_capable() and resctrl_arch_mon_capable() during filesystem init. Update code comments and changelog.

v4: New patch to initialize supported kernel modes.
https://lore.kernel.org/lkml/[email protected]/
Changed the kmode_cur to enum resctrl_kernel_mode in resctrl_kmode_cfg. Moved the resctrl_kmode_cfg to filesystem code.

---
 fs/resctrl/internal.h | 51 +++++++++++++++++++++++++++++++++++++++++++
 fs/resctrl/rdtgroup.c | 33 ++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+)
fs/resctrl/internal.h +51 -0
index e62a277dee85..4087bf44a06d 100644
@@ -314,6 +314,57 @@ struct mbm_state {
 	u32	prev_bw;
 };
 
+/**
+ * enum kmode_state - Control or monitoring state for a kernel mode
+ * @KMODE_INHERIT: Inherit from the user space task.
+ * @KMODE_ASSIGN: Use a global assignment for kernel mode.
+ */
+enum kmode_state {
+	KMODE_INHERIT,
+	KMODE_ASSIGN
+};
+
+/**
+ * struct resctrl_kmode_caps - Static kernel mode capabilities
+ * @kmode_sup:	Bitmap of supported kernel modes. Empty when neither
+ *		@ctrl_en nor @mon_en is set and kernel mode policy is
+ *		unavailable on this system.
+ * @ctrl_en:	Whether kernel mode may use global assignment for control.
+ * @mon_en:	Whether kernel mode may use global assignment for monitoring.
+ */
+struct resctrl_kmode_caps {
+	DECLARE_BITMAP(kmode_sup, RESCTRL_NUM_KERNEL_MODES);
+	bool				ctrl_en;
+	bool				mon_en;
+};
+
+/**
+ * struct resctrl_kmode_active - Runtime kernel mode state
+ * @kmode_cur:	Currently selected kernel mode.
+ * @ctrl_mode:	Control assignment state when kernel mode is active.
+ * @mon_mode:	Monitoring assignment state when kernel mode is active.
+ * @k_rdtgrp:	Resource group backing global assignment mode.
+ *
+ * When @kmode_cur is %RESCTRL_INHERIT_USER, assignment state is ignored and
+ * @k_rdtgrp is %NULL.
+ */
+struct resctrl_kmode_active {
+	enum resctrl_kernel_mode	kmode_cur;
+	enum kmode_state		ctrl_mode;
+	enum kmode_state		mon_mode;
+	struct rdtgroup			*k_rdtgrp;
+};
+
+/**
+ * struct resctrl_kmode_cfg - Global kernel mode state
+ * @caps:	Supported modes and assignment capabilities.
+ * @active:	Active mode, assignment state, and assigned group.
+ */
+struct resctrl_kmode_cfg {
+	struct resctrl_kmode_caps	caps;
+	struct resctrl_kmode_active	active;
+};
+
 extern struct mutex rdtgroup_mutex;
 
 static inline const char *rdt_kn_name(const struct kernfs_node *kn)
fs/resctrl/rdtgroup.c +33 -0
index 5dcbb0a964e8..3c53f3f74e5a 100644
@@ -76,6 +76,13 @@ static void rdtgroup_destroy_root(void);
 
 struct dentry *debugfs_resctrl;
 
+/*
+ * Global kernel mode policy state: supported modes, active mode, assignment
+ * capabilities, assignment state, and the resource group selected for a global
+ * assignment.
+ */
+static struct resctrl_kmode_cfg resctrl_kcfg;
+
 /*
  * Memory bandwidth monitoring event to use for the default CTRL_MON group
  * and each new CTRL_MON group created by the user.  Only relevant when
@@ -2297,6 +2304,30 @@ static void io_alloc_init(void)
 	}
 }
 
+/*
+ * Initialize kernel mode policy defaults from architecture capabilities.
+ *
+ * When ctrl_en or mon_en is set, RESCTRL_INHERIT_USER is supported and
+ * selected as the initial active mode. When neither is set, kmode_sup is
+ * left empty, kernel mode policy is unavailable, and kmode_cur remains at
+ * its zero-initialized default (RESCTRL_INHERIT_USER) but is unused.
+ */
+static void resctrl_kmode_init(void)
+{
+	resctrl_kcfg.caps.ctrl_en = resctrl_arch_alloc_capable();
+	resctrl_kcfg.active.ctrl_mode = KMODE_INHERIT;
+	resctrl_kcfg.caps.mon_en = resctrl_arch_mon_capable();
+	resctrl_kcfg.active.mon_mode = KMODE_INHERIT;
+	resctrl_kcfg.active.k_rdtgrp = NULL;
+
+	if (resctrl_kcfg.caps.ctrl_en || resctrl_kcfg.caps.mon_en) {
+		resctrl_kcfg.active.kmode_cur = RESCTRL_INHERIT_USER;
+		__set_bit(RESCTRL_INHERIT_USER, resctrl_kcfg.caps.kmode_sup);
+	} else {
+		bitmap_zero(resctrl_kcfg.caps.kmode_sup, RESCTRL_NUM_KERNEL_MODES);
+	}
+}
+
 void resctrl_file_fflags_init(const char *config, unsigned long fflags)
 {
 	struct rftype *rft;
@@ -4816,6 +4847,8 @@ int resctrl_init(void)
 	if (ret)
 		return ret;
 
+	resctrl_kmode_init();
+
 	ret = sysfs_create_mount_point(fs_kobj, "resctrl");
 	if (ret) {
 		resctrl_l3_mon_resource_exit();
Signature · 1 line
2.43.0
maintainer
#19 lore raw

Re: [PATCH v5 06/16] fs/resctrl: Introduce kernel mode states for resctrl

Hi Babu,

Quoted 20 lines · Babu Moger
---
 fs/resctrl/internal.h | 51 +++++++++++++++++++++++++++++++++++++++++++
 fs/resctrl/rdtgroup.c | 33 ++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+)
fs/resctrl/internal.h +7 -0
index e62a277dee85..4087bf44a06d 100644
@@ -314,6 +314,57 @@ struct mbm_state {
 	u32	prev_bw;
 };
 
+/**
+ * enum kmode_state - Control or monitoring state for a kernel mode
+ * @KMODE_INHERIT: Inherit from the user space task.
+ * @KMODE_ASSIGN: Use a global assignment for kernel mode.
+ */
+enum kmode_state {
+	KMODE_INHERIT,

fs/resctrl/internal.h struct mbm_state { · line 333

Quoted 10 lines
fs/resctrl/internal.h +10 -0
+	KMODE_ASSIGN
+};
+
+/**
+ * struct resctrl_kmode_caps - Static kernel mode capabilities
+ * @kmode_sup:	Bitmap of supported kernel modes. Empty when neither
+ *		@ctrl_en nor @mon_en is set and kernel mode policy is
+ *		unavailable on this system.
+ * @ctrl_en:	Whether kernel mode may use global assignment for control.
+ * @mon_en:	Whether kernel mode may use global assignment for monitoring.

Why is ctrl_en and mon_en needed? It seems to just store the output of whether system supports allocation and monitoring. I only see these used when user interacts reads or writes the kernel mode so not a "hot path" that needs to be optimized. Can these just be dropped and just use resctrl_arch_alloc_capable() and resctrl_arch_mon_capable() directly? Please note they are in process of being changed/renamed:

https://lore.kernel.org/lkml/[email protected]/

Quoted 6 lines
fs/resctrl/internal.h +6 -0
+ */
+struct resctrl_kmode_caps {
+	DECLARE_BITMAP(kmode_sup, RESCTRL_NUM_KERNEL_MODES);
+	bool				ctrl_en;
+	bool				mon_en;
+};

fs/resctrl/internal.h struct mbm_state { · line 349

Quoted 10 lines
fs/resctrl/internal.h +10 -0
+
+/**
+ * struct resctrl_kmode_active - Runtime kernel mode state
+ * @kmode_cur:	Currently selected kernel mode.
+ * @ctrl_mode:	Control assignment state when kernel mode is active.
+ * @mon_mode:	Monitoring assignment state when kernel mode is active.
+ * @k_rdtgrp:	Resource group backing global assignment mode.
+ *
+ * When @kmode_cur is %RESCTRL_INHERIT_USER, assignment state is ignored and
+ * @k_rdtgrp is %NULL.

This implies that this is only the state for RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU. If it is made specifically so there is no need to pretend it is generic and add all these caveats.

fs/resctrl/internal.h struct mbm_state { · line 354

Quoted 5 lines
fs/resctrl/internal.h +5 -0
+ */
+struct resctrl_kmode_active {
+	enum resctrl_kernel_mode	kmode_cur;
+	enum kmode_state		ctrl_mode;
+	enum kmode_state		mon_mode;

Is "mode" accurate? This is all about kernel "mode" and now control and monitoring have other modes?

fs/resctrl/internal.h struct mbm_state { · line 355

Quoted 1 line
fs/resctrl/internal.h +1 -0
+	struct rdtgroup			*k_rdtgrp;

Could naming be consistent? Consider, for example, kmode_rdtgrp? Although if this struct can be specific to the global per-CPU kernel mode then it can just be "rdtgrp".

fs/resctrl/internal.h struct mbm_state { · line 361

Quoted 6 lines
fs/resctrl/internal.h +6 -0
+};
+
+/**
+ * struct resctrl_kmode_cfg - Global kernel mode state
+ * @caps:	Supported modes and assignment capabilities.
+ * @active:	Active mode, assignment state, and assigned group.

Please do not list the struct members as part of its description elsewhere since that will be difficult to keep accurate. Just describe what the struct represents.

Quoted 14 lines
fs/resctrl/internal.h +6 -0
+ */
+struct resctrl_kmode_cfg {
+	struct resctrl_kmode_caps	caps;
+	struct resctrl_kmode_active	active;
+};
+
 extern struct mutex rdtgroup_mutex;
 
 static inline const char *rdt_kn_name(const struct kernfs_node *kn)
fs/resctrl/rdtgroup.c +0 -0
index 5dcbb0a964e8..3c53f3f74e5a 100644

fs/resctrl/rdtgroup.c static void rdtgroup_destroy_root(void); · line 82

Quoted 7 lines
fs/resctrl/rdtgroup.c +4 -0
@@ -76,6 +76,13 @@ static void rdtgroup_destroy_root(void);
 
 struct dentry *debugfs_resctrl;
 
+/*
+ * Global kernel mode policy state: supported modes, active mode, assignment
+ * capabilities, assignment state, and the resource group selected for a global
+ * assignment.

Same here - please do not just provide a list of the struct's members. A high level description instead.

This code is really strange. This whole series is difficult to read. I have not seen these styles used before and surprised that it comes from you.

fs/resctrl/rdtgroup.c static void rdtgroup_destroy_root(void); · line 84

Quoted 2 lines
fs/resctrl/rdtgroup.c +2 -0
+ */
+static struct resctrl_kmode_cfg resctrl_kcfg;

I think the code will be easier to read if "resctrl_kcfg" -> "resctrl_kmode".

Quoted 5 lines
fs/resctrl/rdtgroup.c +1 -0
+
 /*
  * Memory bandwidth monitoring event to use for the default CTRL_MON group
  * and each new CTRL_MON group created by the user.  Only relevant when

fs/resctrl/rdtgroup.c static void io_alloc_init(void) · line 2313

Quoted 10 lines
fs/resctrl/rdtgroup.c +7 -0
@@ -2297,6 +2304,30 @@ static void io_alloc_init(void)
 	}
 }
 
+/*
+ * Initialize kernel mode policy defaults from architecture capabilities.
+ *
+ * When ctrl_en or mon_en is set, RESCTRL_INHERIT_USER is supported and
+ * selected as the initial active mode. When neither is set, kmode_sup is
+ * left empty, kernel mode policy is unavailable, and kmode_cur remains at
+ * its zero-initialized default (RESCTRL_INHERIT_USER) but is unused.

Above just verbatim describes the code. Please provide higher level why the code does what it does.

Quoted 21 lines
fs/resctrl/rdtgroup.c +17 -0
+ */
+static void resctrl_kmode_init(void)
+{
+	resctrl_kcfg.caps.ctrl_en = resctrl_arch_alloc_capable();
+	resctrl_kcfg.active.ctrl_mode = KMODE_INHERIT;
+	resctrl_kcfg.caps.mon_en = resctrl_arch_mon_capable();
+	resctrl_kcfg.active.mon_mode = KMODE_INHERIT;
+	resctrl_kcfg.active.k_rdtgrp = NULL;
+
+	if (resctrl_kcfg.caps.ctrl_en || resctrl_kcfg.caps.mon_en) {
+		resctrl_kcfg.active.kmode_cur = RESCTRL_INHERIT_USER;
+		__set_bit(RESCTRL_INHERIT_USER, resctrl_kcfg.caps.kmode_sup);
+	} else {
+		bitmap_zero(resctrl_kcfg.caps.kmode_sup, RESCTRL_NUM_KERNEL_MODES);
+	}
+}
+
 void resctrl_file_fflags_init(const char *config, unsigned long fflags)
 {
 	struct rftype *rft;

fs/resctrl/rdtgroup.c int resctrl_init(void) · line 4854

Quoted 8 lines
fs/resctrl/rdtgroup.c +2 -0
@@ -4816,6 +4847,8 @@ int resctrl_init(void)
 	if (ret)
 		return ret;
 
+	resctrl_kmode_init();
+
 	ret = sysfs_create_mount_point(fs_kobj, "resctrl");
 	if (ret) {
 		resctrl_l3_mon_resource_exit();

Reinette

author reviewer
#20 lore raw

Re: [PATCH v5 06/16] fs/resctrl: Introduce kernel mode states for resctrl

Hi Reinette,

Quoted 33 lines · Reinette Chatre

Hi Babu,

Quoted 29 lines · Babu Moger
---
  fs/resctrl/internal.h | 51 +++++++++++++++++++++++++++++++++++++++++++
  fs/resctrl/rdtgroup.c | 33 ++++++++++++++++++++++++++++
  2 files changed, 84 insertions(+)
fs/resctrl/internal.h +16 -0
index e62a277dee85..4087bf44a06d 100644
@@ -314,6 +314,57 @@ struct mbm_state {
  	u32	prev_bw;
  };
 
+/**
+ * enum kmode_state - Control or monitoring state for a kernel mode
+ * @KMODE_INHERIT: Inherit from the user space task.
+ * @KMODE_ASSIGN: Use a global assignment for kernel mode.
+ */
+enum kmode_state {
+	KMODE_INHERIT,
+	KMODE_ASSIGN
+};
+
+/**
+ * struct resctrl_kmode_caps - Static kernel mode capabilities
+ * @kmode_sup:	Bitmap of supported kernel modes. Empty when neither
+ *		@ctrl_en nor @mon_en is set and kernel mode policy is
+ *		unavailable on this system.
+ * @ctrl_en:	Whether kernel mode may use global assignment for control.
Quoted 8 lines

fs/resctrl/internal.h struct mbm_state { · line 333

Quoted 1 line
fs/resctrl/internal.h +1 -0
+ * @mon_en:	Whether kernel mode may use global assignment for monitoring.

Why is ctrl_en and mon_en needed? It seems to just store the output of whether system supports allocation and monitoring. I only see these used when user interacts reads or writes the kernel mode so not a "hot path" that needs to be optimized. Can these just be dropped and just use resctrl_arch_alloc_capable() and resctrl_arch_mon_capable() directly? Please note they are in process of being changed/renamed:

Sure. I'll remove it.

That also means we can consolidate everything into a single resctrl_kmode_cfg structure.

Quoted 14 lines

https://lore.kernel.org/lkml/[email protected]/

Quoted 12 lines
fs/resctrl/internal.h +12 -0
+ */
+struct resctrl_kmode_caps {
+	DECLARE_BITMAP(kmode_sup, RESCTRL_NUM_KERNEL_MODES);
+	bool				ctrl_en;
+	bool				mon_en;
+};
+
+/**
+ * struct resctrl_kmode_active - Runtime kernel mode state
+ * @kmode_cur:	Currently selected kernel mode.
+ * @ctrl_mode:	Control assignment state when kernel mode is active.
+ * @mon_mode:	Monitoring assignment state when kernel mode is active.
Quoted 8 lines

fs/resctrl/internal.h struct mbm_state { · line 349

Quoted 4 lines
fs/resctrl/internal.h +4 -0
+ * @k_rdtgrp:	Resource group backing global assignment mode.
+ *
+ * When @kmode_cur is %RESCTRL_INHERIT_USER, assignment state is ignored and
+ * @k_rdtgrp is %NULL.

This implies that this is only the state for RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU. If it is made specifically so there is no need to pretend it is generic and add all these caveats.

ok.

Quoted 9 lines

fs/resctrl/internal.h struct mbm_state { · line 354

Quoted 6 lines
fs/resctrl/internal.h +5 -0
+ */
+struct resctrl_kmode_active {
+	enum resctrl_kernel_mode	kmode_cur;
+	enum kmode_state		ctrl_mode;
+	enum kmode_state		mon_mode;

Is "mode" accurate? This is all about kernel "mode" and now control and monitoring have other modes?

It can be control and monitor.

Quoted 6 lines

fs/resctrl/internal.h struct mbm_state { · line 355

Quoted 2 lines
fs/resctrl/internal.h +1 -0
+	struct rdtgroup			*k_rdtgrp;

Could naming be consistent? Consider, for example, kmode_rdtgrp? Although if this struct can be specific to the global per-CPU kernel mode then it can just be "rdtgrp".

Sure.

Quoted 10 lines

fs/resctrl/internal.h struct mbm_state { · line 361

Quoted 7 lines
fs/resctrl/internal.h +6 -0
+};
+
+/**
+ * struct resctrl_kmode_cfg - Global kernel mode state
+ * @caps:	Supported modes and assignment capabilities.
+ * @active:	Active mode, assignment state, and assigned group.

Please do not list the struct members as part of its description elsewhere since that will be difficult to keep accurate. Just describe what the struct represents.

Will remove it.

Quoted 18 lines
Quoted 18 lines
fs/resctrl/internal.h +6 -0
+ */
+struct resctrl_kmode_cfg {
+	struct resctrl_kmode_caps	caps;
+	struct resctrl_kmode_active	active;
+};
+
  extern struct mutex rdtgroup_mutex;
 
  static inline const char *rdt_kn_name(const struct kernfs_node *kn)
fs/resctrl/rdtgroup.c +0 -0
index 5dcbb0a964e8..3c53f3f74e5a 100644
@@ -76,6 +76,13 @@ static void rdtgroup_destroy_root(void);
 
  struct dentry *debugfs_resctrl;
 
Quoted 7 lines

fs/resctrl/rdtgroup.c static void rdtgroup_destroy_root(void); · line 82

Quoted 4 lines
fs/resctrl/rdtgroup.c +4 -0
+/*
+ * Global kernel mode policy state: supported modes, active mode, assignment
+ * capabilities, assignment state, and the resource group selected for a global
+ * assignment.

Same here - please do not just provide a list of the struct's members. A high level description instead.

ok.

Quoted 3 lines

This code is really strange. This whole series is difficult to read. I have not seen these styles used before and surprised that it comes from you.

ack.

Quoted 5 lines

fs/resctrl/rdtgroup.c static void rdtgroup_destroy_root(void); · line 84

Quoted 3 lines
fs/resctrl/rdtgroup.c +2 -0
+ */
+static struct resctrl_kmode_cfg resctrl_kcfg;

I think the code will be easier to read if "resctrl_kcfg" -> "resctrl_kmode".

Sure.

Quoted 9 lines
Quoted 9 lines
fs/resctrl/rdtgroup.c +1 -0
+
  /*
   * Memory bandwidth monitoring event to use for the default CTRL_MON group
   * and each new CTRL_MON group created by the user.  Only relevant when
@@ -2297,6 +2304,30 @@ static void io_alloc_init(void)
  	}
  }
 
Quoted 10 lines

fs/resctrl/rdtgroup.c static void io_alloc_init(void) · line 2313

Quoted 7 lines
fs/resctrl/rdtgroup.c +7 -0
+/*
+ * Initialize kernel mode policy defaults from architecture capabilities.
+ *
+ * When ctrl_en or mon_en is set, RESCTRL_INHERIT_USER is supported and
+ * selected as the initial active mode. When neither is set, kmode_sup is
+ * left empty, kernel mode policy is unavailable, and kmode_cur remains at
+ * its zero-initialized default (RESCTRL_INHERIT_USER) but is unused.

Above just verbatim describes the code. Please provide higher level why the code does what it does.

ok.

Thanks
Babu

author reviewer
#21 lore raw

PATCH v5 7/16 fs/resctrl: Introduce resctrl_set_kmode_support() to register supported modes

In reply to Babu Moger

Architectures need to advertise supported kernel modes before resctrl can expose them through the filesystem.

Generic resctrl has no registration hook for architecture-specific kernel mode policies.

Introduce resctrl_set_kmode_support() to set the corresponding bit in resctrl_kcfg.caps.kmode_sup during initialization. Architectures may call this to register RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU when they support independent kernel mode control and/or monitoring assignment.

---
v5: New patch split from resctrl_kmode_cfg initialization. Register modes
in resctrl_kmode_cfg.caps.kmode_sup using RESCTRL_INHERIT_USER and RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU. Ignore out-of-range mode values.

v4: New patch to initialize supported kernel modes.

    https://lore.kernel.org/lkml/[email protected]/
---
 fs/resctrl/rdtgroup.c   | 13 +++++++++++++
 include/linux/resctrl.h | 17 +++++++++++++++++
 2 files changed, 30 insertions(+)
fs/resctrl/rdtgroup.c +13 -0
index 3c53f3f74e5a..3bb0e3a203ac 100644
@@ -892,6 +892,19 @@ static int rdtgroup_rmid_show(struct kernfs_open_file *of,
 	return ret;
 }
 
+/**
+ * resctrl_set_kmode_support() - Register a supported kernel mode
+ * @kmode:	Kernel mode policy supported by the architecture.
+ *
+ * Set the corresponding bit in resctrl_kcfg.caps.kmode_sup so @kmode
+ * is visible to the resctrl file system.
+ */
+void resctrl_set_kmode_support(enum resctrl_kernel_mode kmode)
+{
+	if (kmode < RESCTRL_NUM_KERNEL_MODES)
+		__set_bit(kmode, resctrl_kcfg.caps.kmode_sup);
+}
+
 #ifdef CONFIG_PROC_CPU_RESCTRL
 /*
  * A task can only be part of one resctrl control group and of one monitor
include/linux/resctrl.h +17 -0
index 8b30eef835aa..051aece77eb9 100644
@@ -729,6 +729,23 @@ enum resctrl_kernel_mode {
 
 #define RESCTRL_NUM_KERNEL_MODES (RESCTRL_KMODE_LAST + 1)
 
+/**
+ * resctrl_set_kmode_support() - Register a supported kernel mode
+ * @kmode: Kernel mode supported by the architecture.
+ *
+ * Set the corresponding bit in resctrl_kcfg.caps.kmode_sup so @kmode
+ * can be exposed through the resctrl filesystem.
+ * RESCTRL_INHERIT_USER is registered by resctrl_kmode_init() and does
+ * not need to be registered again.
+ *
+ * Architectures use this interface during resctrl initialization to
+ * advertise supported kernel modes. Registration of a mode indicates
+ * architectural support only. The final decision to expose and enable
+ * a mode is made by resctrl based on system capabilities and
+ * configuration.
+ */
+void resctrl_set_kmode_support(enum resctrl_kernel_mode kmode);
+
 /**
  * resctrl_arch_configure_kmode() - Program kernel mode association
  * @cpu_mask:	CPUs to assign the kernel mode on.
Signature · 1 line
2.43.0
maintainer
#22 lore raw

Re: [PATCH v5 07/16] fs/resctrl: Introduce resctrl_set_kmode_support() to register supported modes

Hi Babu,

fs/resctrl/rdtgroup.c static int rdtgroup_rmid_show(struct kernfs_open_file *of, · line 897

Quoted 11 lines · Babu Moger
fs/resctrl/rdtgroup.c +3 -0
index 3c53f3f74e5a..3bb0e3a203ac 100644
@@ -892,6 +892,19 @@ static int rdtgroup_rmid_show(struct kernfs_open_file *of,
 	return ret;
 }
 
+/**
+ * resctrl_set_kmode_support() - Register a supported kernel mode
+ * @kmode:	Kernel mode policy supported by the architecture.

How is "Kernel mode" different from "Kernel mode policy"?

fs/resctrl/rdtgroup.c static int rdtgroup_rmid_show(struct kernfs_open_file *of, · line 900

Quoted 3 lines
fs/resctrl/rdtgroup.c +3 -0
+ *
+ * Set the corresponding bit in resctrl_kcfg.caps.kmode_sup so @kmode
+ * is visible to the resctrl file system.

Verbatim description of what can be seen from the code.

Quoted 15 lines
fs/resctrl/rdtgroup.c +7 -0
+ */
+void resctrl_set_kmode_support(enum resctrl_kernel_mode kmode)
+{
+	if (kmode < RESCTRL_NUM_KERNEL_MODES)
+		__set_bit(kmode, resctrl_kcfg.caps.kmode_sup);
+}
+
 #ifdef CONFIG_PROC_CPU_RESCTRL
 /*
  * A task can only be part of one resctrl control group and of one monitor
include/linux/resctrl.h +0 -0
index 8b30eef835aa..051aece77eb9 100644

include/linux/resctrl.h enum resctrl_kernel_mode { · line 736

Quoted 8 lines
include/linux/resctrl.h +5 -0
@@ -729,6 +729,23 @@ enum resctrl_kernel_mode {
 
 #define RESCTRL_NUM_KERNEL_MODES (RESCTRL_KMODE_LAST + 1)
 
+/**
+ * resctrl_set_kmode_support() - Register a supported kernel mode
+ * @kmode: Kernel mode supported by the architecture.
+ *
+ * Set the corresponding bit in resctrl_kcfg.caps.kmode_sup so @kmode

No need to describe resctrl fs internal details here.

Quoted 5 lines
include/linux/resctrl.h +5 -0
+ * can be exposed through the resctrl filesystem.
+ * RESCTRL_INHERIT_USER is registered by resctrl_kmode_init() and does
+ * not need to be registered again.
+ *
+ * Architectures use this interface during resctrl initialization to

include/linux/resctrl.h enum resctrl_kernel_mode { · line 751

Quoted 10 lines
include/linux/resctrl.h +7 -0
+ * advertise supported kernel modes. Registration of a mode indicates
+ * architectural support only. The final decision to expose and enable
+ * a mode is made by resctrl based on system capabilities and
+ * configuration.
+ */
+void resctrl_set_kmode_support(enum resctrl_kernel_mode kmode);
+
 /**
  * resctrl_arch_configure_kmode() - Program kernel mode association
  * @cpu_mask:	CPUs to assign the kernel mode on.

Reinette

author reviewer
#23 lore raw

Re: [PATCH v5 07/16] fs/resctrl: Introduce resctrl_set_kmode_support() to register supported modes

Hi Reinette,

Quoted 12 lines · Reinette Chatre

Hi Babu,

Quoted 8 lines · Babu Moger
fs/resctrl/rdtgroup.c +0 -0
index 3c53f3f74e5a..3bb0e3a203ac 100644
@@ -892,6 +892,19 @@ static int rdtgroup_rmid_show(struct kernfs_open_file *of,
  	return ret;
  }
 
Quoted 5 lines

fs/resctrl/rdtgroup.c static int rdtgroup_rmid_show(struct kernfs_open_file *of, · line 897

Quoted 3 lines
fs/resctrl/rdtgroup.c +3 -0
+/**
+ * resctrl_set_kmode_support() - Register a supported kernel mode
+ * @kmode:	Kernel mode policy supported by the architecture.

How is "Kernel mode" different from "Kernel mode policy"?

It should be just "kernel mode".

Quoted 6 lines

fs/resctrl/rdtgroup.c static int rdtgroup_rmid_show(struct kernfs_open_file *of, · line 900

Quoted 4 lines
fs/resctrl/rdtgroup.c +3 -0
+ *
+ * Set the corresponding bit in resctrl_kcfg.caps.kmode_sup so @kmode
+ * is visible to the resctrl file system.

Verbatim description of what can be seen from the code.

ok.

Quoted 19 lines
Quoted 19 lines
fs/resctrl/rdtgroup.c +7 -0
+ */
+void resctrl_set_kmode_support(enum resctrl_kernel_mode kmode)
+{
+	if (kmode < RESCTRL_NUM_KERNEL_MODES)
+		__set_bit(kmode, resctrl_kcfg.caps.kmode_sup);
+}
+
  #ifdef CONFIG_PROC_CPU_RESCTRL
  /*
   * A task can only be part of one resctrl control group and of one monitor
include/linux/resctrl.h +0 -0
index 8b30eef835aa..051aece77eb9 100644
@@ -729,6 +729,23 @@ enum resctrl_kernel_mode {
 
  #define RESCTRL_NUM_KERNEL_MODES (RESCTRL_KMODE_LAST + 1)
 
Quoted 7 lines

include/linux/resctrl.h enum resctrl_kernel_mode { · line 736

Quoted 5 lines
include/linux/resctrl.h +5 -0
+/**
+ * resctrl_set_kmode_support() - Register a supported kernel mode
+ * @kmode: Kernel mode supported by the architecture.
+ *
+ * Set the corresponding bit in resctrl_kcfg.caps.kmode_sup so @kmode

No need to describe resctrl fs internal details here.

ok.

Thanks
Babu

author reviewer
#24 lore raw

PATCH v5 8/16 x86/resctrl: Expose assign_global_enable_per_cpu when PLZA is available

In reply to Babu Moger

Generic resctrl exposes kernel modes through sysfs only after architectures register them with resctrl_set_kmode_support().

PLZA provides per-CPU kernel mode allocation and monitoring assignment, but assign_global_enable_per_cpu is never registered during x86 initialization.

Register RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU when PLZA is available and resctrl allocation or monitoring resources are present.

---
v5: Update the patch to adapt new data structure and resctrl_set_kmode_support()
changes.

v4: New patch to set the supported features during arch init.

---
 arch/x86/kernel/cpu/resctrl/core.c | 4 ++++
 1 file changed, 4 insertions(+)
arch/x86/kernel/cpu/resctrl/core.c +4 -0
index 4ca8bedeb995..39d6a2a60805 100644
@@ -1021,6 +1021,10 @@ static __init bool get_rdt_resources(void)
 	rdt_alloc_capable = get_rdt_alloc_resources();
 	rdt_mon_capable = get_rdt_mon_resources();
 
+	if (rdt_cpu_has(X86_FEATURE_PLZA) &&
+	    (rdt_alloc_capable || rdt_mon_capable))
+		resctrl_set_kmode_support(RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU);
+
 	return (rdt_mon_capable || rdt_alloc_capable);
 }
 
Signature · 1 line
2.43.0
author reviewer
#25 lore raw

PATCH v5 9/16 fs/resctrl: Add interface to display supported and active kernel modes

In reply to Babu Moger

Resctrl kernel modes define how resource allocation and monitoring associations are applied in kernel mode relative to user mode. Generic resctrl maintains information about supported kernel modes, the currently active mode, and the resource group associated with global assignment mode, but this information is not currently visible to user space.

Add info/kernel_mode to expose kernel mode configuration through the resctrl filesystem. The file lists all supported kernel modes, one per line, identifies the active mode by enclosing it in square brackets, and for assign_global_enable_per_cpu also reports ctrl=, mon=, and group=. Document the read interface in Documentation/filesystems/resctrl.rst.

---
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 |  29 +++++++
 fs/resctrl/rdtgroup.c                 | 115 ++++++++++++++++++++++++++
 2 files changed, 144 insertions(+)
Documentation/filesystems/resctrl.rst +29 -0
index f3e941404967..c6e8cf828e18 100644
@@ -528,6 +528,35 @@ 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" reports
+	supported and active kernel modes available on the system.
+
+	Reading the file lists one mode per line. The active mode is wrapped in
+	square brackets. inherit_user is shown without options.
+	assign_global_enable_per_cpu is shown as::
+
+	  assign_global_enable_per_cpu:ctrl=<assign|inherit>;mon=<assign|inherit>;group=<ctrl>/<mon>/
+
+	- inherit_user: inherit allocation and monitoring from the user task.
+	- assign_global_enable_per_cpu: kernel mode may use separate
+	  allocation and/or monitoring associations. ctrl= and mon= show
+	  whether each is assigned or inherited, and group= identifies the
+	  associated resource group using <CTRL_MON>/<MON>/ path syntax.
+
+	Only supported modes are listed. On an inactive
+	assign_global_enable_per_cpu line, ctrl= and mon= show platform
+	capability defaults rather than the last active assignment, and
+	group=// is shown. When the mode is active, ctrl= and mon= report
+	the current assignment state and group= identifies the associated
+	resource group.
+
+	Example::
+
+	  # cat info/kernel_mode
+	  [inherit_user]
+	  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//
+
 Resource alloc and monitor groups
 =================================
 
fs/resctrl/rdtgroup.c +115 -0

127 lines not on this page · raw message

Signature · 1 line
2.43.0
maintainer
#26 lore raw

Re: [PATCH v5 09/16] fs/resctrl: Add interface to display supported and active kernel modes

Hi Babu,

Quoted 14 lines · Babu Moger
---
 Documentation/filesystems/resctrl.rst |  29 +++++++
 fs/resctrl/rdtgroup.c                 | 115 ++++++++++++++++++++++++++
 2 files changed, 144 insertions(+)
Documentation/filesystems/resctrl.rst +1 -0
index f3e941404967..c6e8cf828e18 100644
@@ -528,6 +528,35 @@ conveyed in the error returns from file operations. E.g.
 	# cat info/last_cmd_status
 	mask f7 has non-consecutive 1-bits
 
+"kernel_mode":

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 541

Quoted 10 lines
Documentation/filesystems/resctrl.rst +10 -0
+	In the top level of the "info" directory, "kernel_mode" reports
+	supported and active kernel modes available on the system.
+
+	Reading the file lists one mode per line. The active mode is wrapped in
+	square brackets. inherit_user is shown without options.
+	assign_global_enable_per_cpu is shown as::
+
+	  assign_global_enable_per_cpu:ctrl=<assign|inherit>;mon=<assign|inherit>;group=<ctrl>/<mon>/
+
+	- inherit_user: inherit allocation and monitoring from the user task.

To make this easier to read, instead of mixing the modes, could you please have text like:

Possible kernel modes are:

<description of inherit_user>

<description of assign_global_enable_per_cpu>

In addition to being easier to read something like above will also be easier to expand.

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 544

Quoted 3 lines
Documentation/filesystems/resctrl.rst +3 -0
+	- assign_global_enable_per_cpu: kernel mode may use separate
+	  allocation and/or monitoring associations. ctrl= and mon= show
+	  whether each is assigned or inherited, and group= identifies the

Earlier is "ctrl=<assign|inherit>;mon=<assign|inherit>" and above is "ctrl= and mon= show whether each is assigned or inherited". This is rewrites the same thing in different ways without helping to explain what the parameters and their values mean.

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 545

Quoted 1 line
Documentation/filesystems/resctrl.rst +1 -0
+	  associated resource group using <CTRL_MON>/<MON>/ path syntax.

This text is difficult to parse. It switches between "assigned" and "associated" *in the same sentence* when referring to the same thing. Please use consistent terms and just be specific about what this actually by avoiding this vague language.

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 549

Quoted 4 lines
Documentation/filesystems/resctrl.rst +4 -0
+
+	Only supported modes are listed. On an inactive
+	assign_global_enable_per_cpu line, ctrl= and mon= show platform
+	capability defaults rather than the last active assignment, and

I find the text to be very vague. Above could be moved to section dedicated to the assign_global_enable_per_cpu mode and be made specific. For example,

When inactive, the parameter values displayed are the default values that will be used when no new value is provided during enabling/activation(*)

(*) pick a term and stick with it

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 552

Quoted 3 lines
Documentation/filesystems/resctrl.rst +3 -0
+	group=// is shown. When the mode is active, ctrl= and mon= report
+	the current assignment state and group= identifies the associated
+	resource group.

Last sentence just repeats the paragraph above, no?

Quoted 15 lines
Documentation/filesystems/resctrl.rst +7 -0
+
+	Example::
+
+	  # cat info/kernel_mode
+	  [inherit_user]
+	  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//
+
 Resource alloc and monitor groups
 =================================
 
fs/resctrl/rdtgroup.c +0 -0
index 3bb0e3a203ac..992af586a194 100644

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1014

Quoted 5 lines
fs/resctrl/rdtgroup.c +2 -0
@@ -1010,6 +1010,114 @@ static int rdt_last_cmd_status_show(struct kernfs_open_file *of,
 	return 0;
 }
 
+/* Sysfs lines for info/kernel_mode; indexed by enum resctrl_kernel_mode */
+static const char * const resctrl_mode_str[] = {

This is incredibly close to resctrl's existing rdtgroup_mode_str while being very high level. Could it be renamed to be more specific to this feature? For example, resctrl_kmode_str[]?

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1016

Quoted 2 lines
fs/resctrl/rdtgroup.c +2 -0
+	[RESCTRL_INHERIT_USER]	=			"inherit_user",
+	[RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU] =	"assign_global_enable_per_cpu"

As mentioned earlier I am starting to think that the "assign" in the name is not necessary and creates confusion with the "assign" values of its parameters.

Quoted 33 lines
fs/resctrl/rdtgroup.c +33 -0
+};
+
+static_assert(ARRAY_SIZE(resctrl_mode_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)
+		return;
+
+	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 set in resctrl_kcfg.caps.kmode_sup. Brackets the

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1059

Quoted 10 lines
fs/resctrl/rdtgroup.c +10 -0
+ * active mode. inherit_user is shown without any options.
+ * assign_global_enable_per_cpu is shown as:
+ *
+ *   assign_global_enable_per_cpu:ctrl=<assign|inherit>;mon=<assign|inherit>;\
+ *					group=<ctrl>/<mon>/
+ *
+ * When assign_global_enable_per_cpu is inactive, ctrl=assign and mon=assign
+ * reflect resctrl_kcfg.caps.ctrl_en and resctrl_kcfg.caps.mon_en, and
+ * group=//. When active, assign state comes from resctrl_kcfg.active.ctrl_mode
+ * and resctrl_kcfg.active.mon_mode.

The code is much easier to read than above summary of it.

Quoted 23 lines
fs/resctrl/rdtgroup.c +23 -0
+ *
+ * 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_state, *mon_state;
+	enum resctrl_kernel_mode mode;
+	struct rdtgroup *rdtgrp;
+	const char *ctrl, *mon;
+	bool active;
+	int ret = 0;
+
+	if (!info_kn_lock(of->kn))
+		return -ENOENT;
+
+	for (mode = 0; mode < RESCTRL_NUM_KERNEL_MODES; mode++) {
+		if (!test_bit(mode, resctrl_kcfg.caps.kmode_sup))
+			continue;
+
+		active = (resctrl_kcfg.active.kmode_cur == mode);
+
+		if (mode == RESCTRL_INHERIT_USER) {

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1092

Quoted 10 lines
fs/resctrl/rdtgroup.c +10 -0
+			seq_printf(seq, active ? "[%s]\n" : "%s\n",
+				   resctrl_mode_str[mode]);
+			continue;
+		}
+
+		if (active) {
+			ctrl_state = resctrl_kmode_state_str(resctrl_kcfg.active.ctrl_mode);
+			mon_state = resctrl_kmode_state_str(resctrl_kcfg.active.mon_mode);
+			rdtgrp = resctrl_kcfg.active.k_rdtgrp;
+			if (WARN_ON(!rdtgrp)) {

Just pr_warn() is sufficient and avoids the discussion about panic_on_warn kernels.

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1099

Quoted 7 lines
fs/resctrl/rdtgroup.c +7 -0
+				rdt_last_cmd_puts("Invalid kernel mode group\n");
+				ret = -ENOENT;
+				goto out_unlock;
+			}
+			resctrl_kmode_group_path(rdtgrp, &ctrl, &mon);
+		} else {
+			ctrl_state = resctrl_kcfg.caps.ctrl_en ? "assign" : "inherit";

This does not look right. As I understand ctrl_en represents whether the system supports allocation or not. So above means that if system supports allocation then the allocation state is "assign" while a system that does *not* support allocation inherits *allocation* association from user space?

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1105

Quoted 6 lines
fs/resctrl/rdtgroup.c +6 -0
+			mon_state = resctrl_kcfg.caps.mon_en ? "assign" : "inherit";
+			ctrl = "";
+			mon = "";
+		}
+
+		if (active) {

Why are there two separate "if (active)" blocks?

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1106

Quoted 1 line
fs/resctrl/rdtgroup.c +1 -0
+			seq_printf(seq, "[%s:ctrl=%s;mon=%s;group=%s/%s/]\n",

This does not look right. The reason why this version moved to a single global mode with parameters is to be able to support systems that do not support allocation or monitoring. Having these separate parameters thus enables resctrl to only show the "ctrl=" parameter on a system that only supports allocation and only show the "mon=" parameter on a system that only supports monitoring. Above just keeps showing both whether system supports allocation/monitoring or not.

Quoted 21 lines
fs/resctrl/rdtgroup.c +14 -0
+				   resctrl_mode_str[mode], ctrl_state, mon_state,
+				   ctrl, mon);
+		} else {
+			seq_printf(seq, "%s:ctrl=%s;mon=%s;group=%s/%s/\n",
+				   resctrl_mode_str[mode], ctrl_state, mon_state,
+				   ctrl, mon);
+		}
+	}
+
+out_unlock:
+	info_kn_unlock(of->kn);
+	return ret;
+}
+
 void *rdt_kn_parent_priv(struct kernfs_node *kn)
 {
 	/*
@@ -1995,6 +2103,13 @@ static struct rftype res_common_files[] = {
 		.seq_show	= rdt_last_cmd_status_show,
 		.fflags		= RFTYPE_TOP_INFO,
 	},

fs/resctrl/rdtgroup.c static struct rftype res_common_files[] = { · line 2115

Quoted 10 lines
fs/resctrl/rdtgroup.c +7 -0
+	{
+		.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,

Reinette

author reviewer
#27 lore raw

Re: [PATCH v5 09/16] fs/resctrl: Add interface to display supported and active kernel modes

Hi Reinette,

Quoted 30 lines · Reinette Chatre

Hi Babu,

Quoted 14 lines · Babu Moger
---
  Documentation/filesystems/resctrl.rst |  29 +++++++
  fs/resctrl/rdtgroup.c                 | 115 ++++++++++++++++++++++++++
  2 files changed, 144 insertions(+)
Documentation/filesystems/resctrl.rst +1 -0
index f3e941404967..c6e8cf828e18 100644
@@ -528,6 +528,35 @@ conveyed in the error returns from file operations. E.g.
  	# cat info/last_cmd_status
  	mask f7 has non-consecutive 1-bits
 
+"kernel_mode":

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 541

Quoted 10 lines
Documentation/filesystems/resctrl.rst +10 -0
+	In the top level of the "info" directory, "kernel_mode" reports
+	supported and active kernel modes available on the system.
+
+	Reading the file lists one mode per line. The active mode is wrapped in
+	square brackets. inherit_user is shown without options.
+	assign_global_enable_per_cpu is shown as::
+
+	  assign_global_enable_per_cpu:ctrl=<assign|inherit>;mon=<assign|inherit>;group=<ctrl>/<mon>/
+
+	- inherit_user: inherit allocation and monitoring from the user task.

To make this easier to read, instead of mixing the modes, could you please have text like:

Quoted 7 lines

Possible kernel modes are:

<description of inherit_user>

<description of assign_global_enable_per_cpu>

In addition to being easier to read something like above will also be easier to expand.

Sure. Will do.

Quoted 9 lines

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 544

Quoted 4 lines
Documentation/filesystems/resctrl.rst +3 -0
+	- assign_global_enable_per_cpu: kernel mode may use separate
+	  allocation and/or monitoring associations. ctrl= and mon= show
+	  whether each is assigned or inherited, and group= identifies the

Earlier is "ctrl=<assign|inherit>;mon=<assign|inherit>" and above is "ctrl= and mon= show whether each is assigned or inherited". This is rewrites the same thing in different ways without helping to explain what the parameters and their values mean.

Will add of the descriptions of "mon" and "ctrl" states.

Quoted 7 lines

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 545

Quoted 3 lines
Documentation/filesystems/resctrl.rst +1 -0
+	  associated resource group using <CTRL_MON>/<MON>/ path syntax.

This text is difficult to parse. It switches between "assigned" and "associated" *in the same sentence* when referring to the same thing. Please use consistent terms and just be specific about what this actually by avoiding this vague language.

Ok. Will rephrase.

Quoted 9 lines

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 549

Quoted 5 lines
Documentation/filesystems/resctrl.rst +4 -0
+
+	Only supported modes are listed. On an inactive
+	assign_global_enable_per_cpu line, ctrl= and mon= show platform
+	capability defaults rather than the last active assignment, and

I find the text to be very vague. Above could be moved to section dedicated to the assign_global_enable_per_cpu mode and be made specific. For example,

Quoted 4 lines

When inactive, the parameter values displayed are the default values that will be used when no new value is provided during enabling/activation(*)

(*) pick a term and stick with it

Ok. Sure.

Quoted 6 lines

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 552

Quoted 4 lines
Documentation/filesystems/resctrl.rst +3 -0
+	group=// is shown. When the mode is active, ctrl= and mon= report
+	the current assignment state and group= identifies the associated
+	resource group.

Last sentence just repeats the paragraph above, no?

Yes. Will rephrase this paragraph.

Quoted 20 lines
Quoted 20 lines
Documentation/filesystems/resctrl.rst +7 -0
+
+	Example::
+
+	  # cat info/kernel_mode
+	  [inherit_user]
+	  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//
+
  Resource alloc and monitor groups
  =================================
 
fs/resctrl/rdtgroup.c +0 -0
index 3bb0e3a203ac..992af586a194 100644
@@ -1010,6 +1010,114 @@ static int rdt_last_cmd_status_show(struct kernfs_open_file *of,
  	return 0;
  }
 
Quoted 6 lines

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1014

Quoted 2 lines
fs/resctrl/rdtgroup.c +2 -0
+/* Sysfs lines for info/kernel_mode; indexed by enum resctrl_kernel_mode */
+static const char * const resctrl_mode_str[] = {

This is incredibly close to resctrl's existing rdtgroup_mode_str while being very high level. Could it be renamed to be more specific to this feature? For example, resctrl_kmode_str[]?

Sure.

Quoted 7 lines

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1016

Quoted 3 lines
fs/resctrl/rdtgroup.c +2 -0
+	[RESCTRL_INHERIT_USER]	=			"inherit_user",
+	[RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU] =	"assign_global_enable_per_cpu"

As mentioned earlier I am starting to think that the "assign" in the name is not necessary and creates confusion with the "assign" values of its parameters.

Sure. Will remove "assign" from the name.

Quoted 38 lines
Quoted 38 lines
fs/resctrl/rdtgroup.c +37 -0
+};
+
+static_assert(ARRAY_SIZE(resctrl_mode_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)
+		return;
+
+	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 set in resctrl_kcfg.caps.kmode_sup. Brackets the
+ * active mode. inherit_user is shown without any options.
+ * assign_global_enable_per_cpu is shown as:
+ *
+ *   assign_global_enable_per_cpu:ctrl=<assign|inherit>;mon=<assign|inherit>;\
Quoted 8 lines

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1059

Quoted 6 lines
fs/resctrl/rdtgroup.c +6 -0
+ *					group=<ctrl>/<mon>/
+ *
+ * When assign_global_enable_per_cpu is inactive, ctrl=assign and mon=assign
+ * reflect resctrl_kcfg.caps.ctrl_en and resctrl_kcfg.caps.mon_en, and
+ * group=//. When active, assign state comes from resctrl_kcfg.active.ctrl_mode
+ * and resctrl_kcfg.active.mon_mode.

The code is much easier to read than above summary of it.

Let me rephrase it briefly.

Quoted 28 lines
Quoted 28 lines
fs/resctrl/rdtgroup.c +27 -0
+ *
+ * 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_state, *mon_state;
+	enum resctrl_kernel_mode mode;
+	struct rdtgroup *rdtgrp;
+	const char *ctrl, *mon;
+	bool active;
+	int ret = 0;
+
+	if (!info_kn_lock(of->kn))
+		return -ENOENT;
+
+	for (mode = 0; mode < RESCTRL_NUM_KERNEL_MODES; mode++) {
+		if (!test_bit(mode, resctrl_kcfg.caps.kmode_sup))
+			continue;
+
+		active = (resctrl_kcfg.active.kmode_cur == mode);
+
+		if (mode == RESCTRL_INHERIT_USER) {
+			seq_printf(seq, active ? "[%s]\n" : "%s\n",
+				   resctrl_mode_str[mode]);
+			continue;
+		}
Quoted 8 lines

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1092

Quoted 6 lines
fs/resctrl/rdtgroup.c +6 -0
+
+		if (active) {
+			ctrl_state = resctrl_kmode_state_str(resctrl_kcfg.active.ctrl_mode);
+			mon_state = resctrl_kmode_state_str(resctrl_kcfg.active.mon_mode);
+			rdtgrp = resctrl_kcfg.active.k_rdtgrp;
+			if (WARN_ON(!rdtgrp)) {

Just pr_warn() is sufficient and avoids the discussion about panic_on_warn kernels.

ok.

Quoted 13 lines

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1099

Quoted 8 lines
fs/resctrl/rdtgroup.c +7 -0
+				rdt_last_cmd_puts("Invalid kernel mode group\n");
+				ret = -ENOENT;
+				goto out_unlock;
+			}
+			resctrl_kmode_group_path(rdtgrp, &ctrl, &mon);
+		} else {
+			ctrl_state = resctrl_kcfg.caps.ctrl_en ? "assign" : "inherit";

This does not look right. As I understand ctrl_en represents whether the system supports allocation or not. So above means that if system supports allocation then the allocation state is "assign" while a system that does *not* support allocation inherits *allocation* association from user space?

When allocation is not supported, we should not print "ctrl". It should just print "<mode>:mon=assign;group=//"

Same way just print "<mode>ctrl=assign;group=//" when monitoring is not supported.

Will take care of it.

Quoted 9 lines

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1105

Quoted 7 lines
fs/resctrl/rdtgroup.c +6 -0
+			mon_state = resctrl_kcfg.caps.mon_en ? "assign" : "inherit";
+			ctrl = "";
+			mon = "";
+		}
+
+		if (active) {

Why are there two separate "if (active)" blocks?

Will merge it.

Quoted 9 lines

fs/resctrl/rdtgroup.c static int rdt_last_cmd_status_show(struct kernfs_open_file *of, · line 1106

Quoted 2 lines
fs/resctrl/rdtgroup.c +1 -0
+			seq_printf(seq, "[%s:ctrl=%s;mon=%s;group=%s/%s/]\n",

This does not look right. The reason why this version moved to a single global mode with parameters is to be able to support systems that do not support allocation or monitoring. Having these separate parameters thus enables resctrl to only show the "ctrl=" parameter on a system that only supports allocation and only show the "mon=" parameter on a system that only supports monitoring. Above just keeps showing both whether system supports allocation/monitoring or not.

Yes. That is correct. It should only print states that are supported. Will change it.

thanks
Babu

author reviewer
#28 lore raw

PATCH v5 10/16 fs/resctrl: Add support for hidden resource group files

In reply to Babu Moger

Some per-group resctrl files are only meaningful once a resource group has an active kernel mode association (for example, kmode_cpus on the associated group).

Creating them only at activation would complicate group setup and teardown, while exposing them on every group would show empty files with no clear purpose.

Add a hidden property to struct rftype to hide files at creation, and resctrl_hidden_files_set_visible() to show or hide them when association state changes.

---
v5: New patch to add support for creating hidden files.

---
 fs/resctrl/internal.h |  4 ++++
 fs/resctrl/rdtgroup.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)
fs/resctrl/internal.h +4 -0
index 4087bf44a06d..b56f95625072 100644
@@ -283,6 +283,7 @@ extern int max_name_width;
  * @kf_ops:	File operations
  * @flags:	File specific RFTYPE_FLAGS_* flags
  * @fflags:	File specific RFTYPE_* flags
+ * @hidden:	Hide file at creation; visibility may be restored later
  * @seq_show:	Show content of the file
  * @write:	Write to the file
  */
@@ -292,6 +293,7 @@ struct rftype {
 	const struct kernfs_ops	*kf_ops;
 	unsigned long		flags;
 	unsigned long		fflags;
+	bool			hidden;
 
 	int (*seq_show)(struct kernfs_open_file *of,
 			struct seq_file *sf, void *v);
@@ -480,6 +482,8 @@ ssize_t resctrl_mbm_assign_mode_write(struct kernfs_open_file *of, char *buf,
 void resctrl_bmec_files_show(struct rdt_resource *r, struct kernfs_node *l3_mon_kn,
 			     bool show);
 
+void resctrl_hidden_files_set_visible(struct kernfs_node *kn, bool show);
+
 int resctrl_num_mbm_cntrs_show(struct kernfs_open_file *of, struct seq_file *s, void *v);
 
 int resctrl_available_mbm_cntrs_show(struct kernfs_open_file *of, struct seq_file *s,
fs/resctrl/rdtgroup.c +30 -0
index 992af586a194..d2fff8adf915 100644
@@ -312,6 +312,9 @@ static int rdtgroup_add_file(struct kernfs_node *parent_kn, struct rftype *rft)
 		return ret;
 	}
 
+	if (rft->hidden)
+		kernfs_show(kn, false);
+
 	return 0;
 }
 
@@ -2377,6 +2380,33 @@ static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags)
 	return ret;
 }
 
+/*
+ * resctrl_hidden_files_set_visible() - Show or hide files marked hidden
+ * @kn: resource group kernfs_node
+ * @show: whether to show or hide
+ *
+ * Iterate res_common_files entries marked hidden and show or hide the
+ * corresponding file under @kn.
+ */
+void resctrl_hidden_files_set_visible(struct kernfs_node *kn, bool show)
+{
+	struct rftype *rft, *rfts = res_common_files;
+	struct kernfs_node *kn_file;
+	int len;
+
+	len = ARRAY_SIZE(res_common_files);
+	for (rft = rfts; rft < rfts + len; rft++) {
+		if (!rft->hidden)
+			continue;
+
+		kn_file = kernfs_find_and_get(kn, rft->name);
+		if (!kn_file)
+			continue;
+		kernfs_show(kn_file, show);
+		kernfs_put(kn_file);
+	}
+}
+
 static struct rftype *rdtgroup_get_rftype_by_name(const char *name)
 {
 	struct rftype *rfts, *rft;
Signature · 1 line
2.43.0
maintainer
#29 lore raw

Re: [PATCH v5 10/16] fs/resctrl: Add support for hidden resource group files

Hi Babu,

fs/resctrl/rdtgroup.c static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags) · line 2389

Quoted 11 lines · Babu Moger
fs/resctrl/rdtgroup.c +7 -0
@@ -2377,6 +2380,33 @@ static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags)
 	return ret;
 }
 
+/*
+ * resctrl_hidden_files_set_visible() - Show or hide files marked hidden
+ * @kn: resource group kernfs_node
+ * @show: whether to show or hide
+ *
+ * Iterate res_common_files entries marked hidden and show or hide the
+ * corresponding file under @kn.

As a generic helper this is not appropriate since it just blindly makes *all* hidden files belonging to a resource group visible or invisible. This pretends to be a generic function but then assumes that only kernel mode related files are ever created with the hidden flag set because as the kernel mode changes all hidden files belonging to the named parent changes visibility.

Reinette

author reviewer
#30 lore raw

Re: [PATCH v5 10/16] fs/resctrl: Add support for hidden resource group files

Hi Reinette,

Quoted 7 lines · Reinette Chatre

Hi Babu,

Quoted 4 lines · Babu Moger
fs/resctrl/rdtgroup.c +0 -0
@@ -2377,6 +2380,33 @@ static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags)
  	return ret;
  }
 
Quoted 14 lines

fs/resctrl/rdtgroup.c static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags) · line 2389

Quoted 7 lines
fs/resctrl/rdtgroup.c +7 -0
+/*
+ * resctrl_hidden_files_set_visible() - Show or hide files marked hidden
+ * @kn: resource group kernfs_node
+ * @show: whether to show or hide
+ *
+ * Iterate res_common_files entries marked hidden and show or hide the
+ * corresponding file under @kn.

As a generic helper this is not appropriate since it just blindly makes *all* hidden files belonging to a resource group visible or invisible. This pretends to be a generic function but then assumes that only kernel mode related files are ever created with the hidden flag set because as the kernel mode changes all hidden files belonging to the named parent changes visibility.

Are you suggesting that I update the code comments to be more specific about the group, or are you suggesting that the code itself should be changed?

Thanks,
Babu

maintainer
#31 lore raw

Re: [PATCH v5 10/16] fs/resctrl: Add support for hidden resource group files

Hi Babu,

Quoted 24 lines · Babu Moger

Hi Reinette,

Quoted 20 lines · Reinette Chatre

Hi Babu,

Quoted 10 lines · Babu Moger
(quoted diff) +0 -0
@@ -2377,6 +2380,33 @@ static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags)
       return ret;
   }

  +/*
+ * resctrl_hidden_files_set_visible() - Show or hide files marked hidden
+ * @kn: resource group kernfs_node
+ * @show: whether to show or hide
+ *
+ * Iterate res_common_files entries marked hidden and show or hide the
+ * corresponding file under @kn.

As a generic helper this is not appropriate since it just blindly makes *all* hidden files belonging to a resource group visible or invisible. This pretends to be a generic function but then assumes that only kernel mode related files are ever created with the hidden flag set because as the kernel mode changes all hidden files belonging to the named parent changes visibility.

Quoted 3 lines

Are you suggesting that I update the code comments to be more specific about the group, or are you suggesting that the code itself should be changed?

Both. The "hidden" flag is *only* about whether a file should be visible at time of creation, whether it is by default "hidden". That is accomplished without this function.

Whether a file is visible or not after initial creation is feature specific. For example, as is done with resctrl_bmec_files_show(). There is no use case for "make all hidden files visible".

resctrl_hidden_files_set_visible() is a hack because it pretends to introduce a generic feature but the implementation only supports two specific files. Consider the scenario when somebody tries to add another resource group file that is by default hidden. Just setting the "hidden" flag will be a reasonable thing to do, but that unrelated file will have its visibility connected to the kernel mode feature!

Please replace resctrl_hidden_files_set_visible() with a kernel mode specific function that only controls visibility of this feature's specific files. That could even be in a separate patch.

Reinette

author reviewer
#32 lore raw

Re: [PATCH v5 10/16] fs/resctrl: Add support for hidden resource group files

Hi Reinette,

Quoted 46 lines · Reinette Chatre

Hi Babu,

Quoted 24 lines · Babu Moger

Hi Reinette,

Quoted 20 lines · Reinette Chatre

Hi Babu,

fs/resctrl/rdtgroup.c static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags) · line 2388

Quoted 10 lines · Babu Moger
fs/resctrl/rdtgroup.c +6 -0
@@ -2377,6 +2380,33 @@ static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags)
       return ret;
   }
   +/*
+ * resctrl_hidden_files_set_visible() - Show or hide files marked hidden
+ * @kn: resource group kernfs_node
+ * @show: whether to show or hide
+ *
+ * Iterate res_common_files entries marked hidden and show or hide the
+ * corresponding file under @kn.

As a generic helper this is not appropriate since it just blindly makes *all* hidden files belonging to a resource group visible or invisible. This pretends to be a generic function but then assumes that only kernel mode related files are ever created with the hidden flag set because as the kernel mode changes all hidden files belonging to the named parent changes visibility.

Quoted 3 lines

Are you suggesting that I update the code comments to be more specific about the group, or are you suggesting that the code itself should be changed?

Both. The "hidden" flag is *only* about whether a file should be visible at time of creation, whether it is by default "hidden". That is accomplished without this function.

Whether a file is visible or not after initial creation is feature specific. For example, as is done with resctrl_bmec_files_show(). There is no use case for "make all hidden files visible".

resctrl_hidden_files_set_visible() is a hack because it pretends to introduce a generic feature but the implementation only supports two specific files. Consider the scenario when somebody tries to add another resource group file that is by default hidden. Just setting the "hidden" flag will be a reasonable thing to do, but that unrelated file will have its visibility connected to the kernel mode feature!

Quoted 4 lines

Please replace resctrl_hidden_files_set_visible() with a kernel mode specific function that only controls visibility of this feature's specific files. That could even be in a separate patch.

I will separate this patch. Will rename it something like.

void resctrl_kmode_global_file_show(kn, "name", true/false);

Thanks
Babu

author reviewer
#33 lore raw

PATCH v5 11/16 fs/resctrl: Introduce kmode_cpus/kmode_cpus_list per rdtgroup

In reply to Babu Moger

Kernel-mode resctrl policies can associate kernel resource allocation and monitoring activity with a specific rdtgroup, optionally on a subset of online CPUs.

While info/kernel_mode exposes the active kernel mode and its associated rdtgroup, there is currently no way for user space to determine which CPUs participate in that association.

Add read-only kmode_cpus and kmode_cpus_list files to each rdtgroup and create them hidden. These files expose rdtgrp->kmode_cpu_mask in bitmap and range-list formats, respectively, matching the existing cpus and cpus_list interfaces.

---
v5: Updated the changelog.
Removed the RDT_MODE_PSEUDO_LOCKED check and added rdtgroup->kmode check. Files are created hidden.

v4: Rewrote the change to be generic.

v3: New patch to add "kmode_cpus" and "kmode_cpus_list" to support
kernel_modes.

---
 fs/resctrl/internal.h |  5 +++++
 fs/resctrl/rdtgroup.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)
fs/resctrl/internal.h +5 -0
index b56f95625072..01f9f596f9b1 100644
@@ -216,6 +216,9 @@ 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 has an active kernel-mode
+ *				association
+ * @kmode_cpu_mask:		CPUs in this group's kernel-mode association
  * @plr:			pseudo-locked region
  */
 struct rdtgroup {
@@ -229,6 +232,8 @@ struct rdtgroup {
 	struct mongroup			mon;
 	enum rdtgrp_mode		mode;
 	enum resctrl_event_id		mba_mbps_event;
+	bool				kmode;
+	struct cpumask			kmode_cpu_mask;
 	struct pseudo_lock_region	*plr;
 };
 
fs/resctrl/rdtgroup.c +43 -0

55 lines not on this page · raw message

Signature · 1 line
2.43.0
maintainer
#34 lore raw

Re: [PATCH v5 11/16] fs/resctrl: Introduce kmode_cpus/kmode_cpus_list per rdtgroup

Hi Babu,

Quoted 9 lines · Babu Moger
 fs/resctrl/internal.h |  5 +++++
 fs/resctrl/rdtgroup.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)
fs/resctrl/internal.h +0 -0
index b56f95625072..01f9f596f9b1 100644

fs/resctrl/internal.h struct mongroup { · line 220

Quoted 5 lines
fs/resctrl/internal.h +2 -0
@@ -216,6 +216,9 @@ 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 has an active kernel-mode
+ *				association

This really just seems specific to the global per-CPU kernel mode. Why is it necessary? Is resctrl_kcfg.active.k_rdtgrp not sufficient by itself? (more below)

Quoted 27 lines
fs/resctrl/internal.h +3 -0
+ * @kmode_cpu_mask:		CPUs in this group's kernel-mode association
  * @plr:			pseudo-locked region
  */
 struct rdtgroup {
@@ -229,6 +232,8 @@ struct rdtgroup {
 	struct mongroup			mon;
 	enum rdtgrp_mode		mode;
 	enum resctrl_event_id		mba_mbps_event;
+	bool				kmode;
+	struct cpumask			kmode_cpu_mask;
 	struct pseudo_lock_region	*plr;
 };
 
fs/resctrl/rdtgroup.c +6 -0
index d2fff8adf915..06e74b027044 100644
@@ -389,6 +389,32 @@ static int rdtgroup_cpus_show(struct kernfs_open_file *of,
 	return ret;
 }
 
+/*
+ * Display CPU masks for the kernel-mode associated resource group.
+ * Supports both "kmode_cpus" (bitmap format) and "kmode_cpus_list"
+ * (range list format); the output format is selected accordingly.
+ *
+ * Returns -ENOENT on error.

fs/resctrl/rdtgroup.c static int rdtgroup_cpus_show(struct kernfs_open_file *of, · line 407

Quoted 10 lines
fs/resctrl/rdtgroup.c +10 -0
+ */
+static int rdtgroup_kmode_cpus_show(struct kernfs_open_file *of,
+				    struct seq_file *s, void *v)
+{
+	struct rdtgroup *rdtgrp;
+	int ret = 0;
+
+	rdtgrp = rdtgroup_kn_lock_live(of->kn);
+
+	if (rdtgrp && rdtgrp->kmode) {

First, it would be helpful to explain why the second test is needed since it is not obvious that a resource group may get re-assigned while a user has this file open.

Second, could a check of rdtgrp->kmode be replaced with a comparison between rdtgrp and resctrl_kcfg.active.k_rdtgrp ? If so, why is rdtgrp::kmode needed? I think one part of this is how this series blurs between a generic "kernel mode" and the specific only-supported global per-CPU kernel mode that makes it difficult to know what state can be used.

Quoted 27 lines
fs/resctrl/rdtgroup.c +20 -0
+		seq_printf(s, is_cpu_list(of) ? "%*pbl\n" : "%*pb\n",
+			   cpumask_pr_args(&rdtgrp->kmode_cpu_mask));
+	} else {
+		ret = -ENOENT;
+	}
+	rdtgroup_kn_unlock(of->kn);
+
+	return ret;
+}
+
 /*
  * Update the PGR_ASSOC MSR on all cpus in @cpu_mask,
  *
@@ -2288,6 +2314,23 @@ static struct rftype res_common_files[] = {
 		.flags		= RFTYPE_FLAGS_CPUS_LIST,
 		.fflags		= RFTYPE_BASE,
 	},
+	{
+		.name		= "kmode_cpus",
+		.mode		= 0444,
+		.hidden		= true,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.seq_show	= rdtgroup_kmode_cpus_show,
+		.fflags		= RFTYPE_BASE,
+	},
+	{
+		.name		= "kmode_cpus_list",

fs/resctrl/rdtgroup.c static struct rftype res_common_files[] = { · line 2336

Quoted 10 lines
fs/resctrl/rdtgroup.c +7 -0
+		.mode		= 0444,
+		.hidden		= true,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.seq_show	= rdtgroup_kmode_cpus_show,
+		.flags		= RFTYPE_FLAGS_CPUS_LIST,
+		.fflags		= RFTYPE_BASE,
+	},
 	{
 		.name		= "tasks",
 		.mode		= 0644,

Reinette

author reviewer
#35 lore raw

Re: [PATCH v5 11/16] fs/resctrl: Introduce kmode_cpus/kmode_cpus_list per rdtgroup

Hi Reinette,

Quoted 7 lines · Reinette Chatre

Hi Babu,

Quoted 4 lines · Babu Moger
  fs/resctrl/internal.h |  5 +++++
  fs/resctrl/rdtgroup.c | 43 +++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 48 insertions(+)
Quoted 13 lines

fs/resctrl/internal.h struct mongroup { · line 220

Quoted 10 lines
fs/resctrl/internal.h +2 -0
index b56f95625072..01f9f596f9b1 100644
@@ -216,6 +216,9 @@ 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 has an active kernel-mode
+ *				association

This really just seems specific to the global per-CPU kernel mode. Why is it necessary? Is resctrl_kcfg.active.k_rdtgrp not sufficient by itself? (more below)

I think we can do it by checking the
rdtgrp == resctrl_kcfg.active.k_rdtgrp

Quoted 43 lines
Quoted 28 lines
fs/resctrl/internal.h +3 -0
+ * @kmode_cpu_mask:		CPUs in this group's kernel-mode association
   * @plr:			pseudo-locked region
   */
  struct rdtgroup {
@@ -229,6 +232,8 @@ struct rdtgroup {
  	struct mongroup			mon;
  	enum rdtgrp_mode		mode;
  	enum resctrl_event_id		mba_mbps_event;
+	bool				kmode;
+	struct cpumask			kmode_cpu_mask;
  	struct pseudo_lock_region	*plr;
  };
 
fs/resctrl/rdtgroup.c +6 -0
index d2fff8adf915..06e74b027044 100644
@@ -389,6 +389,32 @@ static int rdtgroup_cpus_show(struct kernfs_open_file *of,
  	return ret;
  }
 
+/*
+ * Display CPU masks for the kernel-mode associated resource group.
+ * Supports both "kmode_cpus" (bitmap format) and "kmode_cpus_list"
+ * (range list format); the output format is selected accordingly.
+ *
+ * Returns -ENOENT on error.

fs/resctrl/rdtgroup.c static int rdtgroup_cpus_show(struct kernfs_open_file *of, · line 407

Quoted 10 lines
fs/resctrl/rdtgroup.c +10 -0
+ */
+static int rdtgroup_kmode_cpus_show(struct kernfs_open_file *of,
+				    struct seq_file *s, void *v)
+{
+	struct rdtgroup *rdtgrp;
+	int ret = 0;
+
+	rdtgrp = rdtgroup_kn_lock_live(of->kn);
+
+	if (rdtgrp && rdtgrp->kmode) {

First, it would be helpful to explain why the second test is needed since it is not obvious that a resource group may get re-assigned while a user has this file open.

Quoted 5 lines

Second, could a check of rdtgrp->kmode be replaced with a comparison between rdtgrp and resctrl_kcfg.active.k_rdtgrp ? If so, why is rdtgrp::kmode needed? I think one part of this is how this series blurs between a generic "kernel mode" and the specific only-supported global per-CPU kernel mode that makes it difficult to know what state can be used.

ok. We can check rdtgrp == resctrl_kcfg.active.k_rdtgrp

Thanks
Babu

author reviewer
#36 lore raw

PATCH v5 12/16 fs/resctrl: Program kernel mode assignments on CPU hotplug

In reply to Babu Moger

Kernel mode resctrl associations are programmed on a per-CPU basis. When assign_global_enable_per_cpu is selected, the active kernel mode association is applied only to CPUs that are online at the time of configuration. CPUs that come online later are not automatically updated.

As a result, hotplugged CPUs, or CPUs that were offline when the kernel mode was activated, may run without the intended kernel mode association even though the mode remains active system-wide.

Add resctrl_kmode_online_cpu() and resctrl_kmode_offline_cpu() and call them from the existing resctrl_online_cpu() and resctrl_offline_cpu() paths to maintain kmode_cpu_mask and update kernel mode associations as CPUs enter or leave the online state.

---
v5: Added resctrl_kmode_offline_cpu() to disable the kernel mode
association and update kmode_cpu_mask when an associated CPU goes
offline.
This addresses sashiko comments:
https://sashiko.dev/#/patchset/cover.1783461016.git.babu.moger%40amd.com?part=11
https://sashiko.dev/#/patchset/cover.1783461016.git.babu.moger%40amd.com?part=10
Also moved the patch earlier than patch 10.
[RESEND PATCH v4 10/15] fs/resctrl: Reset the kernel mode binding when an rdtgroup is removed That seemed much more clear.

v4: New patch in the series. Patch taken from:
https://lore.kernel.org/lkml/[email protected]/
Updated the code to enable kernel mode by default whenever a CPU comes online when one of global-assign mode is enabled.

---
 fs/resctrl/rdtgroup.c | 59 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)
fs/resctrl/rdtgroup.c +59 -0
index 06e74b027044..97e4176669e5 100644
@@ -4951,11 +4951,67 @@ int resctrl_online_mon_domain(struct rdt_resource *r, struct rdt_domain_hdr *hdr
 	return err;
 }
 
+/*
+ * resctrl_kmode_online_cpu() - Program kernel mode association for @cpu
+ * @cpu: CPU that has just been brought online
+ *
+ * If assign_global_enable_per_cpu is active and the rdtgroup has an active
+ * kernel-mode association, add @cpu to kmode_cpu_mask and program the
+ * corresponding kernel mode association.
+ */
+static void resctrl_kmode_online_cpu(unsigned int cpu)
+{
+	struct rdtgroup *rdtgrp = resctrl_kcfg.active.k_rdtgrp;
+	bool assign_ctrl, assign_mon;
+
+	if (resctrl_kcfg.active.kmode_cur != RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU ||
+	    !rdtgrp || !rdtgrp->kmode)
+		return;
+
+	assign_ctrl = (resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN);
+	assign_mon = (resctrl_kcfg.active.mon_mode == KMODE_ASSIGN);
+
+	cpumask_set_cpu(cpu, &rdtgrp->kmode_cpu_mask);
+
+	resctrl_arch_configure_kmode(cpumask_of(cpu), rdtgrp->closid, assign_ctrl,
+				     rdtgrp->mon.rmid, assign_mon, true);
+}
+
+/*
+ * resctrl_kmode_offline_cpu() - Clear kernel mode association for @cpu
+ * @cpu: CPU being taken offline.
+ *
+ * If assign_global_enable_per_cpu is active, disable the kernel mode
+ * association for @cpu and remove it from kmode_cpu_mask.
+ */
+static void resctrl_kmode_offline_cpu(unsigned int cpu)
+{
+	struct rdtgroup *rdtgrp = resctrl_kcfg.active.k_rdtgrp;
+	bool assign_ctrl, assign_mon;
+
+	if (resctrl_kcfg.active.kmode_cur != RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU ||
+	    !rdtgrp || !rdtgrp->kmode)
+		return;
+
+	if (!cpumask_test_cpu(cpu, &rdtgrp->kmode_cpu_mask))
+		return;
+
+	assign_ctrl = (resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN);
+	assign_mon = (resctrl_kcfg.active.mon_mode == KMODE_ASSIGN);
+
+	cpumask_clear_cpu(cpu, &rdtgrp->kmode_cpu_mask);
+
+	resctrl_arch_configure_kmode(cpumask_of(cpu), rdtgrp->closid, assign_ctrl,
+				     rdtgrp->mon.rmid, assign_mon, false);
+}
+
 void resctrl_online_cpu(unsigned int cpu)
 {
 	mutex_lock(&rdtgroup_mutex);
 	/* The CPU is set in default rdtgroup after online. */
 	cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask);
+	/* Program any active kernel mode association on this CPU. */
+	resctrl_kmode_online_cpu(cpu);
 	mutex_unlock(&rdtgroup_mutex);
 }
 
@@ -4999,6 +5055,9 @@ void resctrl_offline_cpu(unsigned int cpu)
 		}
 	}
 
+	/* Clear any active kernel mode association on this CPU. */
+	resctrl_kmode_offline_cpu(cpu);
+
 	if (!l3->mon_capable)
 		goto out_unlock;
 
Signature · 1 line
2.43.0
maintainer
#37 lore raw

Re: [PATCH v5 12/16] fs/resctrl: Program kernel mode assignments on CPU hotplug

Hi Babu,

Quoted 26 lines · Babu Moger
---
 fs/resctrl/rdtgroup.c | 59 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)
fs/resctrl/rdtgroup.c +14 -0
index 06e74b027044..97e4176669e5 100644
@@ -4951,11 +4951,67 @@ int resctrl_online_mon_domain(struct rdt_resource *r, struct rdt_domain_hdr *hdr
 	return err;
 }
 
+/*
+ * resctrl_kmode_online_cpu() - Program kernel mode association for @cpu
+ * @cpu: CPU that has just been brought online
+ *
+ * If assign_global_enable_per_cpu is active and the rdtgroup has an active
+ * kernel-mode association, add @cpu to kmode_cpu_mask and program the
+ * corresponding kernel mode association.
+ */
+static void resctrl_kmode_online_cpu(unsigned int cpu)
+{
+	struct rdtgroup *rdtgrp = resctrl_kcfg.active.k_rdtgrp;
+	bool assign_ctrl, assign_mon;
+
+	if (resctrl_kcfg.active.kmode_cur != RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU ||

fs/resctrl/rdtgroup.c int resctrl_online_mon_domain(struct rdt_resource *r, struct rdt_domain_hdr *hdr · line 4977

Quoted 10 lines
fs/resctrl/rdtgroup.c +10 -0
+	    !rdtgrp || !rdtgrp->kmode)
+		return;
+
+	assign_ctrl = (resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN);
+	assign_mon = (resctrl_kcfg.active.mon_mode == KMODE_ASSIGN);
+
+	cpumask_set_cpu(cpu, &rdtgrp->kmode_cpu_mask);
+
+	resctrl_arch_configure_kmode(cpumask_of(cpu), rdtgrp->closid, assign_ctrl,
+				     rdtgrp->mon.rmid, assign_mon, true);

If I counted right, at end of this series, resctrl_arch_configure_kmode() is called six times and _every_ call is preceded with the same two line pattern above:

	assign_ctrl = (resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN);
	assign_mon = (resctrl_kcfg.active.mon_mode == KMODE_ASSIGN);

Could this be simplified with a single helper that does something like:

static void resctrl_configure_global_kmode(const struct cpumask *mask,
struct rdtgroup *rdtgrp, bool enable)
{
resctrl_arch_configure_global_kmode(mask, rdtgrp->closid,
resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN,

					    rdtgrp->mon.rmid,
					    resctrl_kcfg.active.mon_mode == KMODE_ASSIGN,
					    enable);
}
Quoted 26 lines
fs/resctrl/rdtgroup.c +26 -0
+}
+
+/*
+ * resctrl_kmode_offline_cpu() - Clear kernel mode association for @cpu
+ * @cpu: CPU being taken offline.
+ *
+ * If assign_global_enable_per_cpu is active, disable the kernel mode
+ * association for @cpu and remove it from kmode_cpu_mask.
+ */
+static void resctrl_kmode_offline_cpu(unsigned int cpu)
+{
+	struct rdtgroup *rdtgrp = resctrl_kcfg.active.k_rdtgrp;
+	bool assign_ctrl, assign_mon;
+
+	if (resctrl_kcfg.active.kmode_cur != RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU ||
+	    !rdtgrp || !rdtgrp->kmode)
+		return;
+
+	if (!cpumask_test_cpu(cpu, &rdtgrp->kmode_cpu_mask))
+		return;
+
+	assign_ctrl = (resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN);
+	assign_mon = (resctrl_kcfg.active.mon_mode == KMODE_ASSIGN);
+
+	cpumask_clear_cpu(cpu, &rdtgrp->kmode_cpu_mask);
+

fs/resctrl/rdtgroup.c int resctrl_online_mon_domain(struct rdt_resource *r, struct rdt_domain_hdr *hdr · line 5013

Quoted 10 lines
fs/resctrl/rdtgroup.c +5 -0
+	resctrl_arch_configure_kmode(cpumask_of(cpu), rdtgrp->closid, assign_ctrl,
+				     rdtgrp->mon.rmid, assign_mon, false);
+}
+
 void resctrl_online_cpu(unsigned int cpu)
 {
 	mutex_lock(&rdtgroup_mutex);
 	/* The CPU is set in default rdtgroup after online. */
 	cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask);
+	/* Program any active kernel mode association on this CPU. */

This comment is not helpful.

Quoted 5 lines
fs/resctrl/rdtgroup.c +1 -0
+	resctrl_kmode_online_cpu(cpu);
 	mutex_unlock(&rdtgroup_mutex);
 }
 

fs/resctrl/rdtgroup.c void resctrl_offline_cpu(unsigned int cpu) · line 5063

Quoted 9 lines
fs/resctrl/rdtgroup.c +3 -0
@@ -4999,6 +5055,9 @@ void resctrl_offline_cpu(unsigned int cpu)
 		}
 	}
 
+	/* Clear any active kernel mode association on this CPU. */
+	resctrl_kmode_offline_cpu(cpu);
+
 	if (!l3->mon_capable)
 		goto out_unlock;
 

Reinette

author reviewer
#38 lore raw

Re: [PATCH v5 12/16] fs/resctrl: Program kernel mode assignments on CPU hotplug

Hi Reinette,

Quoted 52 lines · Reinette Chatre

Hi Babu,

Quoted 26 lines · Babu Moger
---
  fs/resctrl/rdtgroup.c | 59 +++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 59 insertions(+)
fs/resctrl/rdtgroup.c +14 -0
index 06e74b027044..97e4176669e5 100644
@@ -4951,11 +4951,67 @@ int resctrl_online_mon_domain(struct rdt_resource *r, struct rdt_domain_hdr *hdr
  	return err;
  }
 
+/*
+ * resctrl_kmode_online_cpu() - Program kernel mode association for @cpu
+ * @cpu: CPU that has just been brought online
+ *
+ * If assign_global_enable_per_cpu is active and the rdtgroup has an active
+ * kernel-mode association, add @cpu to kmode_cpu_mask and program the
+ * corresponding kernel mode association.
+ */
+static void resctrl_kmode_online_cpu(unsigned int cpu)
+{
+	struct rdtgroup *rdtgrp = resctrl_kcfg.active.k_rdtgrp;
+	bool assign_ctrl, assign_mon;
+
+	if (resctrl_kcfg.active.kmode_cur != RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU ||

fs/resctrl/rdtgroup.c int resctrl_online_mon_domain(struct rdt_resource *r, struct rdt_domain_hdr *hdr · line 4977

Quoted 10 lines
fs/resctrl/rdtgroup.c +10 -0
+	    !rdtgrp || !rdtgrp->kmode)
+		return;
+
+	assign_ctrl = (resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN);
+	assign_mon = (resctrl_kcfg.active.mon_mode == KMODE_ASSIGN);
+
+	cpumask_set_cpu(cpu, &rdtgrp->kmode_cpu_mask);
+
+	resctrl_arch_configure_kmode(cpumask_of(cpu), rdtgrp->closid, assign_ctrl,
+				     rdtgrp->mon.rmid, assign_mon, true);

If I counted right, at end of this series, resctrl_arch_configure_kmode() is called six times and _every_ call is preceded with the same two line pattern above:

	assign_ctrl = (resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN);
	assign_mon = (resctrl_kcfg.active.mon_mode == KMODE_ASSIGN);

Could this be simplified with a single helper that does something like:

static void resctrl_configure_global_kmode(const struct cpumask *mask,
struct rdtgroup *rdtgrp, bool enable)

Quoted 8 lines
{
   	resctrl_arch_configure_global_kmode(mask, rdtgrp->closid,
   					    resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN,
					    rdtgrp->mon.rmid,
					    resctrl_kcfg.active.mon_mode == KMODE_ASSIGN,
					    enable);
}

Sure. That will do. Thanks.

Quoted 31 lines
Quoted 31 lines
fs/resctrl/rdtgroup.c +30 -0
+}
+
+/*
+ * resctrl_kmode_offline_cpu() - Clear kernel mode association for @cpu
+ * @cpu: CPU being taken offline.
+ *
+ * If assign_global_enable_per_cpu is active, disable the kernel mode
+ * association for @cpu and remove it from kmode_cpu_mask.
+ */
+static void resctrl_kmode_offline_cpu(unsigned int cpu)
+{
+	struct rdtgroup *rdtgrp = resctrl_kcfg.active.k_rdtgrp;
+	bool assign_ctrl, assign_mon;
+
+	if (resctrl_kcfg.active.kmode_cur != RESCTRL_ASSIGN_GLOBAL_ENABLE_PER_CPU ||
+	    !rdtgrp || !rdtgrp->kmode)
+		return;
+
+	if (!cpumask_test_cpu(cpu, &rdtgrp->kmode_cpu_mask))
+		return;
+
+	assign_ctrl = (resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN);
+	assign_mon = (resctrl_kcfg.active.mon_mode == KMODE_ASSIGN);
+
+	cpumask_clear_cpu(cpu, &rdtgrp->kmode_cpu_mask);
+
+	resctrl_arch_configure_kmode(cpumask_of(cpu), rdtgrp->closid, assign_ctrl,
+				     rdtgrp->mon.rmid, assign_mon, false);
+}
+
Quoted 8 lines

fs/resctrl/rdtgroup.c int resctrl_online_mon_domain(struct rdt_resource *r, struct rdt_domain_hdr *hdr · line 5013

Quoted 6 lines
fs/resctrl/rdtgroup.c +1 -0
  void resctrl_online_cpu(unsigned int cpu)
  {
  	mutex_lock(&rdtgroup_mutex);
  	/* The CPU is set in default rdtgroup after online. */
  	cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask);
+	/* Program any active kernel mode association on this CPU. */

This comment is not helpful.

Will remove these comments.

Thanks
Babu

author reviewer
#39 lore raw

PATCH v5 13/16 fs/resctrl: Deactivate the kernel mode association when a group is removed

In reply to Babu Moger

Resctrl tracks the rdtgroup associated with the active kernel mode, including the CPU mask used to program kernel mode associations.

When the associated rdtgroup is removed or the filesystem is unmounted, the hardware configuration programmed for its kmode_cpu_mask must be torn down and global kernel-mode state restored to the default.

Call rdtgroup_kmode_detach() from group removal and filesystem teardown paths to disable the active association, hide kmode_cpus files, clear per-group state, and restore RESCTRL_INHERIT_USER.

---
v5: Took care of couple of Sashiko comments on previous patch.
https://sashiko.dev/#/patchset/cover.1783461016.git.babu.moger%40amd.com?part=10
Re-wrote the changelog.
Renamed rdtgroup_config_kmode_reset() to rdtgroup_kmode_deactivate().

v4: Re-wrote the changelog.
Added the call free_all_child_rdtgrp() and rmdir_all_sub() Simplified the code comments.

v3: New patch to handle the kernel_mode clean up.

---
 fs/resctrl/rdtgroup.c | 58 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
fs/resctrl/rdtgroup.c +58 -0
index 97e4176669e5..ed4fedbf2193 100644
@@ -1147,6 +1147,57 @@ static int resctrl_kernel_mode_show(struct kernfs_open_file *of,
 	return ret;
 }
 
+/**
+ * rdtgroup_kmode_deactivate() - Tear down the active kernel mode on @rdtgrp
+ * @rdtgrp:	Resctrl group whose active kernel mode is being released.
+ *
+ * Deactivate the kernel mode association on the CPUs in @rdtgrp's
+ * @kmode_cpu_mask, hide kmode_cpus files, and clear the group's kernel-mode
+ * state.
+ */
+static void rdtgroup_kmode_deactivate(struct rdtgroup *rdtgrp)
+{
+	bool assign_ctrl, assign_mon;
+
+	assign_ctrl = (resctrl_kcfg.active.ctrl_mode == KMODE_ASSIGN);
+	assign_mon = (resctrl_kcfg.active.mon_mode == KMODE_ASSIGN);
+
+	resctrl_arch_configure_kmode(&rdtgrp->kmode_cpu_mask, rdtgrp->closid,
+				     assign_ctrl, rdtgrp->mon.rmid, assign_mon,
+				     false);
+
+	resctrl_hidden_files_set_visible(rdtgrp->kn, false);
+	cpumask_clear(&rdtgrp->kmode_cpu_mask);
+	rdtgrp->kmode = false;
+}
+
+/**
+ * rdtgroup_kmode_detach() - Detach @rdtgrp from a kernel mode association
+ * @rdtgrp: Resctrl group being removed or torn down.
+ *
+ * If @rdtgrp backs the active kernel mode association, disable the
+ * hardware association programmed for the group's kmode_cpu_mask,
+ * clear the associated kernel mode state, and restore
+ * RESCTRL_INHERIT_USER as the active mode.
+ */
+static void rdtgroup_kmode_detach(struct rdtgroup *rdtgrp)
+{
+	if (!rdtgrp || !rdtgrp->kmode)
+		return;
+
+	if (resctrl_kcfg.active.k_rdtgrp != rdtgrp) {
+		pr_warn("resctrl: kernel mode group not valid\n");
+		return;
+	}
+
+	rdtgroup_kmode_deactivate(rdtgrp);
+
+	resctrl_kcfg.active.k_rdtgrp = NULL;
+	resctrl_kcfg.active.kmode_cur = RESCTRL_INHERIT_USER;
+	resctrl_kcfg.active.ctrl_mode = KMODE_INHERIT;
+	resctrl_kcfg.active.mon_mode = KMODE_INHERIT;
+}
+
 void *rdt_kn_parent_priv(struct kernfs_node *kn)
 {
 	/*
@@ -3235,6 +3286,7 @@ static void free_all_child_rdtgrp(struct rdtgroup *rdtgrp)
 
 	head = &rdtgrp->mon.crdtgrp_list;
 	list_for_each_entry_safe(sentry, stmp, head, mon.crdtgrp_list) {
+		rdtgroup_kmode_detach(sentry);
 		rdtgroup_unassign_cntrs(sentry);
 		free_rmid(sentry->closid, sentry->mon.rmid);
 		list_del(&sentry->mon.crdtgrp_list);
@@ -3272,6 +3324,7 @@ static void rmdir_all_sub(void)
 		cpumask_or(&rdtgroup_default.cpu_mask,
 			   &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask);
 
+		rdtgroup_kmode_detach(rdtgrp);
 		rdtgroup_unassign_cntrs(rdtgrp);
 
 		if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP ||
@@ -3367,6 +3420,7 @@ static void resctrl_fs_teardown(void)
 		return;
 
 	rmdir_all_sub();
+	rdtgroup_kmode_detach(&rdtgroup_default);
 	rdtgroup_unassign_cntrs(&rdtgroup_default);
 	mon_put_kn_priv();
 	rdt_pseudo_lock_release();
@@ -4402,6 +4456,8 @@ static int rdtgroup_rmdir_mon(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask)
 	u32 closid, rmid;
 	int cpu;
 
+	rdtgroup_kmode_detach(rdtgrp);
+
 	/* Give any tasks back to the parent group */
 	rdt_move_group_tasks(rdtgrp, prdtgrp, tmpmask);
 
@@ -4452,6 +4508,8 @@ static int rdtgroup_rmdir_ctrl(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask)
 	u32 closid, rmid;
 	int cpu;
 
+	rdtgroup_kmode_detach(rdtgrp);
+
 	/* Give any tasks back to the default group */
 	rdt_move_group_tasks(rdtgrp, &rdtgroup_default, tmpmask);
 
Signature · 1 line
2.43.0
maintainer
#40 lore raw

Re: [PATCH v5 13/16] fs/resctrl: Deactivate the kernel mode association when a group is removed

Hi Babu,

Quoted 8 lines · Babu Moger

+/**
+ * rdtgroup_kmode_detach() - Detach @rdtgrp from a kernel mode association
+ * @rdtgrp: Resctrl group being removed or torn down.
+ *
+ * If @rdtgrp backs the active kernel mode association, disable the
+ * hardware association programmed for the group's kmode_cpu_mask,
+ * clear the associated kernel mode state, and restore
+ * RESCTRL_INHERIT_USER as the active mode.

I am not going to keep pointing these out but please check entire series and remove all these verbatim code descriptions from function comments.

Quoted 2 lines

+ */
+static void rdtgroup_kmode_detach(struct rdtgroup *rdtgrp)

Similar to previous comments this only seems relevant to the global per-CPU kernel mode so function can be made specific to it.

fs/resctrl/rdtgroup.c static int resctrl_kernel_mode_show(struct kernfs_open_file *of, · line 1188

Quoted 5 lines
fs/resctrl/rdtgroup.c +5 -0
+{
+	if (!rdtgrp || !rdtgrp->kmode)
+		return;
+
+	if (resctrl_kcfg.active.k_rdtgrp != rdtgrp) {

Related to comment in previous patch this double check of rdtgrp->kmode and resctrl_kcfg.active.k_rdtgrp seems to support that only one is needed?

fs/resctrl/rdtgroup.c static int resctrl_kernel_mode_show(struct kernfs_open_file *of, · line 1189

Quoted 1 line
fs/resctrl/rdtgroup.c +1 -0
+		pr_warn("resctrl: kernel mode group not valid\n");

Please just fix this file's pr_fmt(fmt) instead.

Quoted 4 lines
fs/resctrl/rdtgroup.c +4 -0
+		return;
+	}
+
+	rdtgroup_kmode_deactivate(rdtgrp);

fs/resctrl/rdtgroup.c static int resctrl_kernel_mode_show(struct kernfs_open_file *of, · line 1203

Quoted 10 lines
fs/resctrl/rdtgroup.c +7 -0
+
+	resctrl_kcfg.active.k_rdtgrp = NULL;
+	resctrl_kcfg.active.kmode_cur = RESCTRL_INHERIT_USER;
+	resctrl_kcfg.active.ctrl_mode = KMODE_INHERIT;
+	resctrl_kcfg.active.mon_mode = KMODE_INHERIT;
+}
+
 void *rdt_kn_parent_priv(struct kernfs_node *kn)
 {
 	/*

Reinette

author reviewer
#41 lore raw

Re: [PATCH v5 13/16] fs/resctrl: Deactivate the kernel mode association when a group is removed

Hi Reinette,

Quoted 12 lines · Reinette Chatre

Hi Babu,

Quoted 8 lines · Babu Moger

+/**
+ * rdtgroup_kmode_detach() - Detach @rdtgrp from a kernel mode association
+ * @rdtgrp: Resctrl group being removed or torn down.
+ *
+ * If @rdtgrp backs the active kernel mode association, disable the
+ * hardware association programmed for the group's kmode_cpu_mask,
+ * clear the associated kernel mode state, and restore
+ * RESCTRL_INHERIT_USER as the active mode.

Quoted 2 lines

I am not going to keep pointing these out but please check entire series and remove all these verbatim code descriptions from function comments.

Ack.

Quoted 6 lines
Quoted 3 lines

+ */
+static void rdtgroup_kmode_detach(struct rdtgroup *rdtgrp)

Similar to previous comments this only seems relevant to the global per-CPU kernel mode so function can be made specific to it.

ok.

Quoted 9 lines

fs/resctrl/rdtgroup.c static int resctrl_kernel_mode_show(struct kernfs_open_file *of, · line 1188

Quoted 6 lines
fs/resctrl/rdtgroup.c +5 -0
+{
+	if (!rdtgrp || !rdtgrp->kmode)
+		return;
+
+	if (resctrl_kcfg.active.k_rdtgrp != rdtgrp) {

Related to comment in previous patch this double check of rdtgrp->kmode and resctrl_kcfg.active.k_rdtgrp seems to support that only one is needed?

Yes. We can remove rdtgrp->kmode field.

Quoted 4 lines

fs/resctrl/rdtgroup.c static int resctrl_kernel_mode_show(struct kernfs_open_file *of, · line 1189

Quoted 2 lines
fs/resctrl/rdtgroup.c +1 -0
+		pr_warn("resctrl: kernel mode group not valid\n");

Please just fix this file's pr_fmt(fmt) instead.

Hmm... It looks like we have a pr_fmt(fmt) inconsistency across multiple files.

Some files use:

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

while others use:

#define pr_fmt(fmt) "resctrl: " fmt

My understanding is that these will produce different log prefixes. For example, KBUILD_MODNAME will typically use the object file name, whereas "resctrl" provides a consistent subsystem-wide prefix.

Do you think we should standardize all files to use the same prefix? If so, I believe that would be better handled as a separate cleanup patch rather than being mixed into this change.

Thanks,
Babu

maintainer
#42 lore raw

Re: [PATCH v5 13/16] fs/resctrl: Deactivate the kernel mode association when a group is removed

Hi Babu,

Quoted 2 lines · Babu Moger
Quoted 1 line · Reinette Chatre

On 8/26/26 12:32 PM, Babu Moger wrote:

...

Quoted 17 lines
Quoted 4 lines
Quoted 2 lines

+        pr_warn("resctrl: kernel mode group not valid\n");

Please just fix this file's pr_fmt(fmt) instead.

Hmm... It looks like we have a pr_fmt(fmt) inconsistency across multiple files.

Some files use:

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

while others use:

#define pr_fmt(fmt) "resctrl: " fmt

Quoted 8 lines
Quoted 1 line

My understanding is that these will produce different log prefixes.

For example, KBUILD_MODNAME will typically use the object file name, whereas "resctrl" provides a consistent subsystem-wide prefix.

Do you think we should standardize all files to use the same prefix? If so, I believe that would be better handled as a separate cleanup patch rather than being mixed into this change.

Thanks for catching this. Yes, I think all files should use the same prefix.

Reinette

author reviewer
#43 lore raw

PATCH v5 14/16 fs/resctrl: Add interface to modify kernel mode via info/kernel_mode

In reply to Babu Moger

info/kernel_mode reports supported and active kernel modes, but it is read-only. User space cannot select a policy, associate a resource group, or configure independent control and monitoring assignment for assign_global_enable_per_cpu.

Add resctrl_kernel_mode_write() to accept the same line format as resctrl_kernel_mode_show(). Parse optional ctrl=, mon=, and group= options, validate the request before changing state, and program the association through rdtgroup_kmode_activate() and rdtgroup_kmode_deactivate().

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

---
v5: Adapt to the resctrl_kcfg caps and active split. Accept
assign_global_enable_per_cpu:ctrl=;mon=;group=<ctrl>/<mon>/ writes. Treat both ctrl=inherit and mon=inherit as a no-op. Use group=// for the default control group. Show associated kmode files through resctrl_hidden_files_set_visible().
Added kmode check in rdtgroup_locksetup_enter(), rdtgroup_mode_write() and rdtgroup_rename().
Simplify kernel-doc for write and activate helpers.

v4: Validate input before tearing down the active association so failures
retain the previous association. Allow assign_mon on CTRL_MON and MON groups; require a control group when control assignment is inherit.

v3: New patch to make info/kernel_mode writable.

---
 Documentation/filesystems/resctrl.rst |  33 +++
 fs/resctrl/pseudo_lock.c              |   5 +
 fs/resctrl/rdtgroup.c                 | 319 +++++++++++++++++++++++++-
 3 files changed, 356 insertions(+), 1 deletion(-)
Documentation/filesystems/resctrl.rst +33 -0
index c6e8cf828e18..490e8f534d37 100644
@@ -557,6 +557,39 @@ conveyed in the error returns from file operations. E.g.
 	  [inherit_user]
 	  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//
 
+	Writes use the same line format as read, without square brackets and
+	with a trailing newline. To select inherit_user, write that mode name
+	alone.
+
+	For assign_global_enable_per_cpu:
+
+	- Writing the mode name alone selects ctrl=assign, mon=assign, and the
+	  default CTRL_MON group.
+	- ctrl=, mon=, and group= are optional, use the same syntax as on read,
+	  and may appear in any order. ctrl= and mon= default to assign;
+	  group= defaults to the default CTRL_MON group.
+	- Empty ctrl=, mon=, or group= values are rejected.
+	- A write with both ctrl=inherit and mon=inherit is a no-op.
+
+	Selecting a new mode, assignment state, or group tears down any active
+	assign_global_enable_per_cpu association before programming the new
+	one. Writing inherit_user clears the active kernel mode association.
+	The mode name must match a supported value exactly. Errors are
+	reported in "info/last_cmd_status". Example::
+
+	  # mkdir ctrl1
+	  # echo "assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=ctrl1//" \
+	         > info/kernel_mode
+
+	  # cat info/kernel_mode
+	  inherit_user
+	  [assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=ctrl1//]
+
+	  # echo "inherit_user" > info/kernel_mode
+	  # cat info/kernel_mode
+	  [inherit_user]
+	  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//
+
 Resource alloc and monitor groups
 =================================
 
fs/resctrl/pseudo_lock.c +5 -0
index dea2b4bf966f..a0b22b95fc08 100644
@@ -536,6 +536,11 @@ int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp)
 		return -EINVAL;
 	}
 
+	if (rdtgrp->kmode) {
+		rdt_last_cmd_puts("Group has an active kernel-mode association\n");
+		return -EINVAL;
+	}
+
 	if (rdtgroup_locksetup_user_restrict(rdtgrp)) {
 		rdt_last_cmd_puts("Unable to modify resctrl permissions\n");
 		return -EIO;
fs/resctrl/rdtgroup.c +318 -1

345 lines not on this page · raw message

Signature · 1 line
2.43.0
maintainer
#44 lore raw

Re: [PATCH v5 14/16] fs/resctrl: Add interface to modify kernel mode via info/kernel_mode

Hi Babu,

Quoted 12 lines · Babu Moger
---
 Documentation/filesystems/resctrl.rst |  33 +++
 fs/resctrl/pseudo_lock.c              |   5 +
 fs/resctrl/rdtgroup.c                 | 319 +++++++++++++++++++++++++-
 3 files changed, 356 insertions(+), 1 deletion(-)
Documentation/filesystems/resctrl.rst +0 -0
index c6e8cf828e18..490e8f534d37 100644
@@ -557,6 +557,39 @@ conveyed in the error returns from file operations. E.g.
 	  [inherit_user]

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 567

Quoted 10 lines
Documentation/filesystems/resctrl.rst +8 -0
 	  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//
 
+	Writes use the same line format as read, without square brackets and
+	with a trailing newline. To select inherit_user, write that mode name
+	alone.
+
+	For assign_global_enable_per_cpu:
+
+	- Writing the mode name alone selects ctrl=assign, mon=assign, and the
+	  default CTRL_MON group.

Please do not commit resctrl to use specific defaults. The documentation can just mention that read of the file provides the defaults.

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 570

Quoted 3 lines
Documentation/filesystems/resctrl.rst +3 -0
+	- ctrl=, mon=, and group= are optional, use the same syntax as on read,
+	  and may appear in any order. ctrl= and mon= default to assign;
+	  group= defaults to the default CTRL_MON group.

This just repeats previous point?

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 572

Quoted 2 lines
Documentation/filesystems/resctrl.rst +2 -0
+	- Empty ctrl=, mon=, or group= values are rejected.
+	- A write with both ctrl=inherit and mon=inherit is a no-op.

... because this assumes there are only two kernel modes that can ever be supported and the other one must be "inherit_user" and thus providing "inherit" for these two parameters imply that "inherit_user" kernel mode? Could you *please* consider other architectures?

fs/resctrl/pseudo_lock.c int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp) · line 543

Quoted 13 lines
fs/resctrl/pseudo_lock.c +5 -0
index dea2b4bf966f..a0b22b95fc08 100644
@@ -536,6 +536,11 @@ int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp)
 		return -EINVAL;
 	}
 
+	if (rdtgrp->kmode) {
+		rdt_last_cmd_puts("Group has an active kernel-mode association\n");
+		return -EINVAL;
+	}
+

These snippets (also the changes to rdtgroup_mode_write() and rdtgroup_rename()) noting when it is and is not ok to make other resctrl changes is not related to support for modifying the kernel mode and should be in a separate patch.

...

fs/resctrl/pseudo_lock.c int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp) · line 546

Quoted 3 lines
fs/resctrl/pseudo_lock.c +3 -0
+
+static int resctrl_kmode_parse_ctrl_mon(char *options, const char *field,
+				    enum kmode_state *state)

run checkpatch.pl --strict as part of your patch prep.

Quoted 9 lines
fs/resctrl/pseudo_lock.c +9 -0
+{
+	char *opt, *val, *end;
+	int ret = 0;
+
+	opt = strstr(options, field);
+	if (!opt)
+		return 0;
+
+	val = opt + strlen(field);

fs/resctrl/pseudo_lock.c int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp)

Quoted 10 lines
fs/resctrl/pseudo_lock.c +10 -0
+	end = strchr(val, ';');
+	if (end)
+		*end = '\0';
+	if (resctrl_kmode_parse_option(val, state))
+		ret = -EINVAL;
+
+	if (end)
+		*end = ';';
+	return ret;
+}

This is an unexpected and new pattern to use a temporary NUL in a buffer then restore the original character. resctrl has a couple of instances where options separated with ";" needs to be parsed - many of them written by you! ctrlmondata.c:parse_line(), ctrlmondata.c:resctrl_io_alloc_parse_line(), monitor.c:resctrl_parse_mbm_assignment() - why invent a new pattern?

sashiko seems to believe there is a issue here. Some of the other sashiko issues look real to me. Please consider the sashiko feedback:

https://sashiko.dev/#/patchset/cover.1787772750.git.babu.moger%40amd.com

Quoted 45 lines
fs/resctrl/pseudo_lock.c +45 -0
+
+static int resctrl_kmode_parse_group(char *options, struct rdtgroup **rdtgrp)
+{
+	const char *ctrl_name, *mon_name;
+	char *group_str, *end, *slash;
+	struct rdtgroup *grp;
+	int ret = 0;
+
+	/* Skip parsing when group= is not present. */
+	group_str = strstr(options, "group=");
+	if (!group_str)
+		return 0;
+
+	/* Isolate the group= value from any following options. */
+	group_str += strlen("group=");
+	end = strchr(group_str, ';');
+	if (end)
+		*end = '\0';
+	group_str = strim(group_str);
+	if (!*group_str) {
+		rdt_last_cmd_puts("group= requires <CTRL_MON>/<MON>/\n");
+		ret = -EINVAL;
+		goto out_parse;
+	}
+	/* Split <CTRL_MON>/<MON>/ at the first slash. */
+	slash = strchr(group_str, '/');
+	if (!slash) {
+		rdt_last_cmd_puts("Group must be <CTRL_MON>/<MON>/\n");
+		ret = -EINVAL;
+		goto out_parse;
+	}
+	*slash = '\0';
+	ctrl_name = group_str;
+	mon_name = slash + 1;
+	/* Require a trailing slash after the monitor group name. */
+	slash = strchr(mon_name, '/');
+	if (!slash || slash[1] != '\0') {
+		rdt_last_cmd_puts("Group must be <CTRL_MON>/<MON>/\n");
+		ret = -EINVAL;
+		goto out_parse;
+	}
+	*slash = '\0';
+	/* Resolve the path to an existing rdtgroup. */
+	grp = rdtgroup_by_kmode_path(ctrl_name, mon_name);
+	if (!grp) {

fs/resctrl/pseudo_lock.c

Quoted 10 lines
fs/resctrl/pseudo_lock.c +10 -0
+		rdt_last_cmd_puts("Group not found\n");
+		ret = -EINVAL;
+		goto out_parse;
+	}
+	*rdtgrp = grp;
+
+out_parse:
+	/* Restore the option string after temporary null termination. */
+	if (end)
+		*end = ';';

same here ... removing characters from buffer and then restoring them is unexpected.

Quoted 12 lines
fs/resctrl/pseudo_lock.c +12 -0
+	return ret;
+}
+
+/**
+ * resctrl_kernel_mode_write() - Set the active kernel mode policy
+ * @of: kernfs open file
+ * @buf: Write buffer; use the resctrl_kernel_mode_show() line format without
+ *	 brackets and with a trailing newline
+ * @nbytes: length of @buf
+ * @off: unused
+ *
+ * Parse and validate the request, then update the active kernel mode

fs/resctrl/pseudo_lock.c

Quoted 10 lines
fs/resctrl/pseudo_lock.c +10 -0
+ * association.
+ *
+ * Return: @nbytes on success, negative errno on error.
+ */
+static ssize_t resctrl_kernel_mode_write(struct kernfs_open_file *of,
+					 char *buf, size_t nbytes, loff_t off)
+{
+	enum kmode_state ctrl_mode = KMODE_ASSIGN, mon_mode = KMODE_ASSIGN;
+	char *mode_str, *options;
+	enum resctrl_kernel_mode mode;

needs reverse fir

Quoted 58 lines
fs/resctrl/pseudo_lock.c +58 -0
+	struct rdtgroup *rdtgrp;
+	int ret = 0;
+
+	if (!info_kn_lock(of->kn))
+		return -ENOENT;
+
+	rdt_last_cmd_clear();
+
+	if (nbytes == 0 || buf[nbytes - 1] != '\n') {
+		rdt_last_cmd_puts("kernel_mode_write: Invalid input\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+	buf[nbytes - 1] = '\0';
+
+	buf = strim(buf);
+	options = strchr(buf, ':');
+	if (options) {
+		*options = '\0';
+		options++;
+	}
+	mode_str = strim(buf);
+
+	for (mode = 0; mode < RESCTRL_NUM_KERNEL_MODES; mode++)
+		if (!strcmp(mode_str, resctrl_mode_str[mode]))
+			break;
+
+	if (mode == RESCTRL_NUM_KERNEL_MODES) {
+		rdt_last_cmd_puts("Unknown kernel mode\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (!test_bit(mode, resctrl_kcfg.caps.kmode_sup)) {
+		rdt_last_cmd_puts("Kernel mode not available\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (mode == RESCTRL_INHERIT_USER) {
+		rdtgrp = NULL;
+		goto update_mode;
+	}
+
+	rdtgrp = &rdtgroup_default;
+
+	if (!options)
+		goto validate_kmode;
+
+	ret = resctrl_kmode_parse_ctrl_mon(options, "ctrl=", &ctrl_mode);
+	if (ret) {
+		rdt_last_cmd_puts("Invalid ctrl= option\n");
+		goto out_unlock;
+	}
+	ret = resctrl_kmode_parse_ctrl_mon(options, "mon=", &mon_mode);
+	if (ret) {
+		rdt_last_cmd_puts("Invalid mon= option\n");
+		goto out_unlock;

fs/resctrl/pseudo_lock.c

Quoted 10 lines
fs/resctrl/pseudo_lock.c +10 -0
+	}
+
+	ret = resctrl_kmode_parse_group(options, &rdtgrp);
+	if (ret)
+		goto out_unlock;
+
+	if (ctrl_mode == KMODE_INHERIT && mon_mode == KMODE_INHERIT)
+		goto out_unlock;
+
+validate_kmode:

This long function is difficult to follow and this usage of goto is a big part of making it difficult to understand since it just jumps to the middle of the function instead of a cleanup label as is custom in the kernel.

Please refactor.

Stopping here. Something is off with this series. It seems to be created without the learnings and patterns accumulated from your previous resctrl contributions while also ignoring x86 (and even kernel) customs.

Reinette

author reviewer
#45 lore raw

Re: [PATCH v5 14/16] fs/resctrl: Add interface to modify kernel mode via info/kernel_mode

Hi Reinette,

Quoted 17 lines · Reinette Chatre

Hi Babu,

Quoted 14 lines · Babu Moger
---
  Documentation/filesystems/resctrl.rst |  33 +++
  fs/resctrl/pseudo_lock.c              |   5 +
  fs/resctrl/rdtgroup.c                 | 319 +++++++++++++++++++++++++-
  3 files changed, 356 insertions(+), 1 deletion(-)
Documentation/filesystems/resctrl.rst +0 -0
index c6e8cf828e18..490e8f534d37 100644
@@ -557,6 +557,39 @@ conveyed in the error returns from file operations. E.g.
  	  [inherit_user]
  	  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//
 
Quoted 11 lines

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 567

Quoted 8 lines
Documentation/filesystems/resctrl.rst +8 -0
+	Writes use the same line format as read, without square brackets and
+	with a trailing newline. To select inherit_user, write that mode name
+	alone.
+
+	For assign_global_enable_per_cpu:
+
+	- Writing the mode name alone selects ctrl=assign, mon=assign, and the
+	  default CTRL_MON group.

Please do not commit resctrl to use specific defaults. The documentation can just mention that read of the file provides the defaults.

Sure.

Quoted 6 lines

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 570

Quoted 4 lines
Documentation/filesystems/resctrl.rst +3 -0
+	- ctrl=, mon=, and group= are optional, use the same syntax as on read,
+	  and may appear in any order. ctrl= and mon= default to assign;
+	  group= defaults to the default CTRL_MON group.

This just repeats previous point?

Yes. Will rephrase this whole text.

Quoted 8 lines

Documentation/filesystems/resctrl.rst conveyed in the error returns from file operations. E.g. · line 572

Quoted 3 lines
Documentation/filesystems/resctrl.rst +2 -0
+	- Empty ctrl=, mon=, or group= values are rejected.
+	- A write with both ctrl=inherit and mon=inherit is a no-op.

... because this assumes there are only two kernel modes that can ever be supported and the other one must be "inherit_user" and thus providing "inherit" for these two parameters imply that "inherit_user" kernel mode? Could you *please* consider other architectures?

We don't know how other architecture's modes going to be. I will remove that line.

Quoted 9 lines
Quoted 9 lines
fs/resctrl/pseudo_lock.c +0 -0
index dea2b4bf966f..a0b22b95fc08 100644
@@ -536,6 +536,11 @@ int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp)
  		return -EINVAL;
  	}
 
Quoted 9 lines

fs/resctrl/pseudo_lock.c int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp) · line 543

Quoted 5 lines
fs/resctrl/pseudo_lock.c +5 -0
+	if (rdtgrp->kmode) {
+		rdt_last_cmd_puts("Group has an active kernel-mode association\n");
+		return -EINVAL;
+	}
+

These snippets (also the changes to rdtgroup_mode_write() and rdtgroup_rename()) noting when it is and is not ok to make other resctrl changes is not related to support for modifying the kernel mode and should be in a separate patch.

Sure. Will do a separate patch. Also, I need to address couple of sashiko reported issue(more below).

Quoted 26 lines

...

fs/resctrl/pseudo_lock.c

Quoted 3 lines
fs/resctrl/pseudo_lock.c +3 -0
+
+static int resctrl_kmode_parse_ctrl_mon(char *options, const char *field,
+				    enum kmode_state *state)

run checkpatch.pl --strict as part of your patch prep.

Quoted 17 lines
fs/resctrl/pseudo_lock.c +17 -0
+{
+	char *opt, *val, *end;
+	int ret = 0;
+
+	opt = strstr(options, field);
+	if (!opt)
+		return 0;
+
+	val = opt + strlen(field);
+	end = strchr(val, ';');
+	if (end)
+		*end = '\0';
+	if (resctrl_kmode_parse_option(val, state))
+		ret = -EINVAL;
+
+	if (end)
+		*end = ';';
Quoted 8 lines

fs/resctrl/pseudo_lock.c

Quoted 2 lines
fs/resctrl/pseudo_lock.c +2 -0
+	return ret;
+}

This is an unexpected and new pattern to use a temporary NUL in a buffer then restore the original character. resctrl has a couple of instances where options separated with ";" needs to be parsed - many of them written by you! ctrlmondata.c:parse_line(), ctrlmondata.c:resctrl_io_alloc_parse_line(), monitor.c:resctrl_parse_mbm_assignment() - why invent a new pattern?

Sure. Will re-write similar along the lines of resctrl_parse_mbm_assignment() and resctrl_io_alloc_parse_line().

Quoted 5 lines

sashiko seems to believe there is a issue here. Some of the other sashiko issues look real to me. Please consider the sashiko feedback:

https://sashiko.dev/#/patchset/cover.1787772750.git.babu.moger%40amd.com

Yes. I need to address couple of issues reported by sashiko.

1. Avoid changing pseudo-lock state of the group when any of it's child monitor group is assigned to kernel mode.

2. Avoid changing the mode (not kernel mode) of the group when any of it's child monitor group is assigned to kernel mode.

3. Avoid changing the monitor group's kernel mode when parent group is in exclusive or pseudo locked state.

Looks like I need to look thru all the children to check on both these cases. It may be another new function.

Quoted 52 lines
Quoted 52 lines
fs/resctrl/pseudo_lock.c +50 -0
+
+static int resctrl_kmode_parse_group(char *options, struct rdtgroup **rdtgrp)
+{
+	const char *ctrl_name, *mon_name;
+	char *group_str, *end, *slash;
+	struct rdtgroup *grp;
+	int ret = 0;
+
+	/* Skip parsing when group= is not present. */
+	group_str = strstr(options, "group=");
+	if (!group_str)
+		return 0;
+
+	/* Isolate the group= value from any following options. */
+	group_str += strlen("group=");
+	end = strchr(group_str, ';');
+	if (end)
+		*end = '\0';
+	group_str = strim(group_str);
+	if (!*group_str) {
+		rdt_last_cmd_puts("group= requires <CTRL_MON>/<MON>/\n");
+		ret = -EINVAL;
+		goto out_parse;
+	}
+	/* Split <CTRL_MON>/<MON>/ at the first slash. */
+	slash = strchr(group_str, '/');
+	if (!slash) {
+		rdt_last_cmd_puts("Group must be <CTRL_MON>/<MON>/\n");
+		ret = -EINVAL;
+		goto out_parse;
+	}
+	*slash = '\0';
+	ctrl_name = group_str;
+	mon_name = slash + 1;
+	/* Require a trailing slash after the monitor group name. */
+	slash = strchr(mon_name, '/');
+	if (!slash || slash[1] != '\0') {
+		rdt_last_cmd_puts("Group must be <CTRL_MON>/<MON>/\n");
+		ret = -EINVAL;
+		goto out_parse;
+	}
+	*slash = '\0';
+	/* Resolve the path to an existing rdtgroup. */
+	grp = rdtgroup_by_kmode_path(ctrl_name, mon_name);
+	if (!grp) {
+		rdt_last_cmd_puts("Group not found\n");
+		ret = -EINVAL;
+		goto out_parse;
+	}
+	*rdtgrp = grp;
Quoted 8 lines

fs/resctrl/pseudo_lock.c

Quoted 5 lines
fs/resctrl/pseudo_lock.c +5 -0
+
+out_parse:
+	/* Restore the option string after temporary null termination. */
+	if (end)
+		*end = ';';

same here ... removing characters from buffer and then restoring them is unexpected.

Will re-write them.

Quoted 17 lines
Quoted 17 lines
fs/resctrl/pseudo_lock.c +16 -0
+	return ret;
+}
+
+/**
+ * resctrl_kernel_mode_write() - Set the active kernel mode policy
+ * @of: kernfs open file
+ * @buf: Write buffer; use the resctrl_kernel_mode_show() line format without
+ *	 brackets and with a trailing newline
+ * @nbytes: length of @buf
+ * @off: unused
+ *
+ * Parse and validate the request, then update the active kernel mode
+ * association.
+ *
+ * Return: @nbytes on success, negative errno on error.
+ */
Quoted 9 lines

fs/resctrl/pseudo_lock.c

Quoted 6 lines
fs/resctrl/pseudo_lock.c +6 -0
+static ssize_t resctrl_kernel_mode_write(struct kernfs_open_file *of,
+					 char *buf, size_t nbytes, loff_t off)
+{
+	enum kmode_state ctrl_mode = KMODE_ASSIGN, mon_mode = KMODE_ASSIGN;
+	char *mode_str, *options;
+	enum resctrl_kernel_mode mode;

needs reverse fir

Sure.

Quoted 73 lines
Quoted 58 lines
fs/resctrl/pseudo_lock.c +58 -0
+	struct rdtgroup *rdtgrp;
+	int ret = 0;
+
+	if (!info_kn_lock(of->kn))
+		return -ENOENT;
+
+	rdt_last_cmd_clear();
+
+	if (nbytes == 0 || buf[nbytes - 1] != '\n') {
+		rdt_last_cmd_puts("kernel_mode_write: Invalid input\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+	buf[nbytes - 1] = '\0';
+
+	buf = strim(buf);
+	options = strchr(buf, ':');
+	if (options) {
+		*options = '\0';
+		options++;
+	}
+	mode_str = strim(buf);
+
+	for (mode = 0; mode < RESCTRL_NUM_KERNEL_MODES; mode++)
+		if (!strcmp(mode_str, resctrl_mode_str[mode]))
+			break;
+
+	if (mode == RESCTRL_NUM_KERNEL_MODES) {
+		rdt_last_cmd_puts("Unknown kernel mode\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (!test_bit(mode, resctrl_kcfg.caps.kmode_sup)) {
+		rdt_last_cmd_puts("Kernel mode not available\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (mode == RESCTRL_INHERIT_USER) {
+		rdtgrp = NULL;
+		goto update_mode;
+	}
+
+	rdtgrp = &rdtgroup_default;
+
+	if (!options)
+		goto validate_kmode;
+
+	ret = resctrl_kmode_parse_ctrl_mon(options, "ctrl=", &ctrl_mode);
+	if (ret) {
+		rdt_last_cmd_puts("Invalid ctrl= option\n");
+		goto out_unlock;
+	}
+	ret = resctrl_kmode_parse_ctrl_mon(options, "mon=", &mon_mode);
+	if (ret) {
+		rdt_last_cmd_puts("Invalid mon= option\n");
+		goto out_unlock;

fs/resctrl/pseudo_lock.c

Quoted 10 lines
fs/resctrl/pseudo_lock.c +10 -0
+	}
+
+	ret = resctrl_kmode_parse_group(options, &rdtgrp);
+	if (ret)
+		goto out_unlock;
+
+	if (ctrl_mode == KMODE_INHERIT && mon_mode == KMODE_INHERIT)
+		goto out_unlock;
+
+validate_kmode:

This long function is difficult to follow and this usage of goto is a big part of making it difficult to understand since it just jumps to the middle of the function instead of a cleanup label as is custom in the kernel.

Quoted 6 lines

Please refactor.

Stopping here. Something is off with this series. It seems to be created without the learnings and patterns accumulated from your previous resctrl contributions while also ignoring x86 (and even kernel) customs.

Will refactor these functions.

Thanks
Babu

author reviewer
#46 lore raw

PATCH v5 15/16 fs/resctrl: Allow user space to write kmode_cpus/kmode_cpus_list

In reply to Babu Moger

Per-CPU kernel mode associates a resource group with kernel-mode allocation and monitoring and records its CPU scope in kmode_cpus and kmode_cpus_list. Administrators may need to add, remove, or clear CPUs after activation without changing the active mode.

The files are read-only, so the CPU mask cannot be changed without deactivating kernel mode.

Make kmode_cpus and kmode_cpus_list writable for the associated group. Validate input, update kmode_cpu_mask, and reprogram kernel-mode association only on CPUs whose assignment changes. Document the interface in Documentation/filesystems/resctrl.rst.

---
v5: Adapt to the resctrl_kcfg caps and active split. Use
resctrl_kcfg.active.ctrl_mode and mon_mode in kmode_cpus_write(). Use full ctrl=/mon= syntax in the kmode_cpus example.

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                 | 131 +++++++++++++++++++++++++-
 2 files changed, 159 insertions(+), 2 deletions(-)
Documentation/filesystems/resctrl.rst +30 -0
index 490e8f534d37..3e886f84315b 100644
@@ -658,6 +658,36 @@ All groups contain the following files:
 "cpus_list":
 	Just like "cpus", only using ranges of CPUs instead of bitmasks.
 
+"kmode_cpus":
+	Accessible only within the resource group currently associated with
+	the active kernel mode (see "info/kernel_mode").
+
+	Bitmask of the logical CPUs associated with the group's kernel mode.
+	When kernel mode is activated through info/kernel_mode, every currently
+	online CPU is included. CPUs that come online later are automatically
+	added to the association.
+
+	Writing a mask reprograms the association: 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 association on all currently online
+	CPUs, but CPUs that come online later are still automatically
+	associated. 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 "assign_global_enable_per_cpu:ctrl=assign;mon=assign;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:
 
fs/resctrl/rdtgroup.c +129 -2

152 lines not on this page · raw message

Signature · 1 line
2.43.0
author reviewer
#47 lore raw

PATCH v5 16/16 fs/resctrl: Add documentation on kernel_mode with example

In reply to Babu Moger

The kernel-mode interface spans info/kernel_mode, kmode_cpus, and kmode_cpus_list, but the per-file descriptions do not walk through a full workflow.

Add an end-to-end example showing how to discover supported policies, associate kernel-mode allocation and/or monitoring with a group.

---
v5: Update the example for the collapsed kernel mode model:
inherit_user and assign_global_enable_per_cpu with ctrl=/mon= association options, and <CTRL_MON group>/<MON group>/ paths.

v4: New patch. Added examples in the documentation.

---
 Documentation/filesystems/resctrl.rst | 100 ++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)
Documentation/filesystems/resctrl.rst +100 -0
index 3e886f84315b..81017858231a 100644
@@ -1873,6 +1873,106 @@ View the llc occupancy snapshot::
   11234000
 
 
+Examples on working with kernel_mode
+====================================
+The kernel-mode interface spans three files:
+
+- ``info/kernel_mode`` - select the global policy and associated group
+- ``kmode_cpus`` / ``kmode_cpus_list`` - view or adjust the CPU scope of the
+  active association (visible only on the associated group)
+
+The walkthrough below covers a typical workflow on a platform with PLZA
+(Privilege Level Zero Association) support:
+
+1. Discover supported policies.
+2. Associate ``assign_global_enable_per_cpu`` with a control group.
+3. Narrow the CPU scope through ``kmode_cpus_list``.
+4. Move the association to a monitor group.
+5. Return to ``inherit_user``.
+
+a. Discover supported kernel mode policies
+::
+
+  # mount -t resctrl resctrl /sys/fs/resctrl/
+
+  # cat /sys/fs/resctrl/info/kernel_mode
+  [inherit_user]
+  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//
+
+``inherit_user`` is the active policy. Kernel work inherits the resource
+allocation and monitoring of the current user-space task. The second line
+shows ``assign_global_enable_per_cpu`` is available; square brackets mark
+the active entry when read back after later steps.
+
+b. Associate kernel mode allocation with a control group
+::
+
+  # mkdir /sys/fs/resctrl/ctrl1
+  # echo "assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//" > \
+        /sys/fs/resctrl/info/kernel_mode
+
+  # cat /sys/fs/resctrl/info/kernel_mode
+  inherit_user
+  [assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//]
+
+This selects ``assign_global_enable_per_cpu`` with control assignment
+(``ctrl=assign``) and inherited monitoring (``mon=inherit``). The group
+path uses ``<CTRL_MON group>/<MON group>/`` syntax; a control group alone
+is written as ``ctrl1//``.
+
+When the mode is active:
+
+- ``ctrl1/kmode_cpus`` and ``ctrl1/kmode_cpus_list`` become visible.
+- All currently online CPUs are associated initially.
+- CPUs that come online later are added to the association automatically.
+
+c. Narrow the association to CPUs 0-3
+::
+
+  # echo 0-3 > /sys/fs/resctrl/ctrl1/kmode_cpus_list
+  # cat /sys/fs/resctrl/ctrl1/kmode_cpus
+  f
+  # cat /sys/fs/resctrl/ctrl1/kmode_cpus_list
+  0-3
+
+The write reprograms the association:
+
+- CPUs added to the mask are enabled.
+- CPUs removed from the mask are disabled.
+- Offline CPUs in the mask are rejected.
+- An empty mask disables the association on all currently online CPUs, but
+  later hotplug CPUs are still associated automatically.
+
+d. Move the association to a monitor group
+::
+
+  # mkdir /sys/fs/resctrl/ctrl1/mon_groups/mon1
+  # echo "assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=ctrl1/mon1/" > \
+        /sys/fs/resctrl/info/kernel_mode
+
+  # cat /sys/fs/resctrl/info/kernel_mode
+  inherit_user
+  [assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=ctrl1/mon1/]
+
+Both control and monitoring are now assigned for kernel work. Changing the
+associated group through ``info/kernel_mode``:
+
+- Resets the CPU scope to all currently online CPUs.
+- Hides ``kmode_cpus`` and ``kmode_cpus_list`` on the previous group.
+- Shows them under ``ctrl1/mon_groups/mon1/``.
+
+e. Return to the default inherit policy
+::
+
+  # echo "inherit_user" > /sys/fs/resctrl/info/kernel_mode
+  # cat /sys/fs/resctrl/info/kernel_mode
+  [inherit_user]
+  assign_global_enable_per_cpu:ctrl=assign;mon=assign;group=//
+
+Writing ``inherit_user`` clears the active kernel-mode association and
+hides ``kmode_cpus`` and ``kmode_cpus_list`` because no group is
+associated with kernel mode.
+
 Examples on working with mbm_assign_mode
 ========================================
 
Signature · 1 line
2.43.0
maintainer
#48 lore raw

Re: [PATCH v5 16/16] fs/resctrl: Add documentation on kernel_mode with example

On Wed, Aug 26, 2026 at 02:32:30PM -0500, Babu Moger wrote:

I fake enabled PLZA on my test system, replacing the wrmsrq() with some console logging. Tried out several of the examples in the documentation and the ones I tried all worked.

Documentation/filesystems/resctrl.rst View the llc occupancy snapshot:: · line 1941

Quoted 13 lines
Documentation/filesystems/resctrl.rst +13 -0
+c. Narrow the association to CPUs 0-3
+::
+
+  # echo 0-3 > /sys/fs/resctrl/ctrl1/kmode_cpus_list
+  # cat /sys/fs/resctrl/ctrl1/kmode_cpus
+  f
+  # cat /sys/fs/resctrl/ctrl1/kmode_cpus_list
+  0-3
+
+The write reprograms the association:
+
+- CPUs added to the mask are enabled.
+- CPUs removed from the mask are disabled.

More precise to say:

PLZA is enabled on CPUs added to the mask.
PLZA is disabled on CPUs removed from the mask.

Or perhaps
PLZA reverts to "inherit_user" mode on CPUs removed from the mask.

Quoted 3 lines
+- Offline CPUs in the mask are rejected.
+- An empty mask disables the association on all currently online CPUs, but
+  later hotplug CPUs are still associated automatically.

Is there a use case for only enabling PLZA on some subset of CPUs?

The special case for:

# echo "" > ctrl1/kmode_cpus

seems particularly strange. It reads to me as:

"I want this PLZA feature enabled, but don't use it on any CPUs".

-Tony

#49 lore raw

Re: [PATCH v5 16/16] fs/resctrl: Add documentation on kernel_mode with example

Hi Tony,

Quoted 5 lines · Tony

On Wed, Aug 26, 2026 at 02:32:30PM -0500, Babu Moger wrote:

I fake enabled PLZA on my test system, replacing the wrmsrq() with some console logging. Tried out several of the examples in the documentation and the ones I tried all worked.

Thank you. Appreciated.

Quoted 20 lines
Quoted 4 lines
Documentation/filesystems/resctrl.rst +3 -0
+c. Narrow the association to CPUs 0-3
+::
+

Documentation/filesystems/resctrl.rst View the llc occupancy snapshot:: · line 1941

Quoted 10 lines
Documentation/filesystems/resctrl.rst +10 -0
+  # echo 0-3 > /sys/fs/resctrl/ctrl1/kmode_cpus_list
+  # cat /sys/fs/resctrl/ctrl1/kmode_cpus
+  f
+  # cat /sys/fs/resctrl/ctrl1/kmode_cpus_list
+  0-3
+
+The write reprograms the association:
+
+- CPUs added to the mask are enabled.
+- CPUs removed from the mask are disabled.

More precise to say:

PLZA is enabled on CPUs added to the mask.
PLZA is disabled on CPUs removed from the mask.

Quoted 8 lines

Or perhaps
PLZA reverts to "inherit_user" mode on CPUs removed from the mask.

Quoted 3 lines
+- Offline CPUs in the mask are rejected.
+- An empty mask disables the association on all currently online CPUs, but
+  later hotplug CPUs are still associated automatically.

Is there a use case for only enabling PLZA on some subset of CPUs?

Probably not. The current use case we know of is enabled either on all CPUs or on none of them. However, I think it's best to keep the option open.

Quoted 9 lines

The special case for:

# echo "" > ctrl1/kmode_cpus

seems particularly strange. It reads to me as:

"I want this PLZA feature enabled, but don't use it on any CPUs".

Yeah, that's true. However, it is consistent with our current cpus and cpus_list interface

Thanks
Babu

#50 lore raw
In reply to Babu Moger

Hi Babu,

Quoted 10 lines · Babu Moger

# Create a CTRL_MON group and associate kernel-mode allocation with it.

  # mkdir ctrl1
  # echo "assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//" \
          > info/kernel_mode
  # cat info/kernel_mode
  inherit_user
  [assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//]
Quoted 4 lines
  # kmode_cpus and kmode_cpus_list are visible only on the associated group.
  # ls ctrl1/kmode_cpus*
  ctrl1/kmode_cpus  ctrl1/kmode_cpus_list

Just curious, would the other existing files like "tasks" be exposed under ctrl1? If this ctrl1 is used only for "kernel space" mode, would the schemata of ctrl1 be shared by all tasks in the system? That is to say, it seems that there is no need to expose "tasks" under ctrl1. Should we hide "tasks" for the kernel group? Please correct me if I misunderstood.

thanks,
Chenyu

author reviewer
#51 lore raw

Hi Chenyu,

Quoted 18 lines · Chen Yu

Hi Babu,

Quoted 10 lines · Babu Moger

# Create a CTRL_MON group and associate kernel-mode allocation with it.

   # mkdir ctrl1
   # echo "assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//" \
           > info/kernel_mode
   # cat info/kernel_mode
   inherit_user
   [assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//]
Quoted 4 lines
   # kmode_cpus and kmode_cpus_list are visible only on the associated group.
   # ls ctrl1/kmode_cpus*
   ctrl1/kmode_cpus  ctrl1/kmode_cpus_list
Quoted 5 lines

Just curious, would the other existing files like "tasks" be exposed under ctrl1? If this ctrl1 is used only for "kernel space" mode, would the schemata of ctrl1 be shared by all tasks in the system? That is to say, it seems that there is no need to expose "tasks" under ctrl1. Should we hide "tasks" for the kernel group? Please correct me if I misunderstood.

No, I don't think we should hide the tasks interface here. It provides the option to use a group in a mixed mode.

# mkdir ctrl1
# cd ctrl1
# echo "1,2,3" > tasks

At this point, PIDs 1, 2, and 3 will use the schemata from ctrl1, regardless of which CPU they are running on. They will use the same limits in both user and kernel mode.

# echo "assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//" \
          > info/kernel_mode

After this, all CPUs in the system will use the schemata from ctrl1 while running in kernel mode, including when executing on behalf of PIDs 1, 2, and 3.

Essentially, this provides the flexibility to run in a mixed mode.

Thanks
Babu

#52 lore raw

Hi Babu,

Quoted 43 lines · Babu Moger

Hi Chenyu,

Quoted 18 lines · Chen Yu

Hi Babu,

Quoted 10 lines · Babu Moger

# Create a CTRL_MON group and associate kernel-mode allocation with it.

   # mkdir ctrl1
   # echo "assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//" \
           > info/kernel_mode
   # cat info/kernel_mode
   inherit_user
   [assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//]
Quoted 4 lines
   # kmode_cpus and kmode_cpus_list are visible only on the associated group.
   # ls ctrl1/kmode_cpus*
   ctrl1/kmode_cpus  ctrl1/kmode_cpus_list
Quoted 5 lines

Just curious, would the other existing files like "tasks" be exposed under ctrl1? If this ctrl1 is used only for "kernel space" mode, would the schemata of ctrl1 be shared by all tasks in the system? That is to say, it seems that there is no need to expose "tasks" under ctrl1. Should we hide "tasks" for the kernel group? Please correct me if I misunderstood.

No, I don't think we should hide the tasks interface here. It provides the option to use a group in a mixed mode.

# mkdir ctrl1
# cd ctrl1
# echo "1,2,3" > tasks

At this point, PIDs 1, 2, and 3 will use the schemata from ctrl1, regardless of which CPU they are running on. They will use the same limits in both user and kernel mode.

# echo "assign_global_enable_per_cpu:ctrl=assign;mon=inherit;group=ctrl1//"
\
          > info/kernel_mode
Quoted 6 lines

After this, all CPUs in the system will use the schemata from ctrl1 while running in kernel mode, including when executing on behalf of PIDs 1, 2, and 3.

Essentially, this provides the flexibility to run in a mixed mode.

I see, a single group can be used both for regular resource control and global kernel resource control. Thanks for this explanation.

thanks,
Chenyu