* [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation
@ 2026-10-26 21:57 Tony Luck
2026-10-26 21:57 ` [RFC PATCH 1/8] fs/resctrl: Change UI of "max" file (merge back into earlier patches) Tony Luck
` (8 more replies)
0 siblings, 9 replies; 12+ messages in thread
From: Tony Luck @ 2026-10-26 21:57 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu
Cc: x86, linux-kernel, patches, Tony Luck
RFC patch series built on top of Reinette's multiple control series[1]
The goal is to support L2 cache allocation on hybrid Intel CPUs such as
Panther Lake[2] where the P-core and E-core CPUs have different number
of supported bits for L2 cache bit mask controls. N.B. it is assumned
that the only point of asymmetry is the cache bit mask length. Other
parameters must be the same (but code doesn't check).
Overall approach is to add the per-L2 cache bitmask length to the domain
and use that everywhere instead of using a single value from the control.
Patch 1 changes the format of the per-control "max" file and should be
merged back into Reinette's multi-control series so this file can have
a consistent format from first upstream introduction.
Patches 2-5 are enumeration and preperation.
Patch 6 introduces, initializes, and uses the per-domain cache bit mask
length field (arm/MPAM change needs careful scrutiny).
Patch 7 enables asymmetric L2 for x86 CPUs that enumerate it. N.B. it
renammes the resource from "L2" to "L2A" to avoid user interface issues
with tools that expect L2 cache allocation to be symmetric.
Patch 8 suppresses creation of the "cbm_mask" file for asymmetric caches.
[1] git://git.kernel.org/pub/scm/linux/kernel/git/reinette/linux.git resctrl/controls_rfc_v2.4
[2] Typical desktop/laptop CPUs do not enumerate RDT L2 cache allocation.
This feature is found on SKUs intended for industrial applications.
Tony Luck (8):
fs/resctrl: Change UI of "max" file (merge back into earlier patches)
x86/resctrl: Add L2CAT quirk for Intel Panther Lake
x86/cpuid: Add and use defines for Intel RDT enumeration leaves
x86/resctrl: Add X86_FEATURE bits for asymmetric L2
x86/resctrl: Refactor rdt_get_cache_alloc_cfg()
arm,x86,fs/resctrl: Prepare for asymmetric caches
x86/resctrl: Check for and enable asymmetric L2 cache allocation
fs/resctrl: Suppress creation of cbm_mask info file on asymmetric
systems
Documentation/filesystems/resctrl.rst | 9 +++-
include/linux/resctrl.h | 12 ++++-
arch/x86/include/asm/cpufeatures.h | 3 ++
arch/x86/include/asm/cpuid/types.h | 4 ++
fs/resctrl/internal.h | 2 +
arch/x86/kernel/cpu/cpuid-deps.c | 2 +
arch/x86/kernel/cpu/resctrl/core.c | 64 +++++++++++++++++++++-----
arch/x86/kernel/cpu/resctrl/rdtgroup.c | 2 +-
arch/x86/kernel/cpu/scattered.c | 3 ++
drivers/resctrl/mpam_resctrl.c | 19 +++++---
fs/resctrl/ctrlmondata.c | 9 ++--
fs/resctrl/pseudo_lock.c | 2 +-
fs/resctrl/rdtgroup.c | 61 +++++++++++++++---------
13 files changed, 145 insertions(+), 47 deletions(-)
--
2.56.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC PATCH 1/8] fs/resctrl: Change UI of "max" file (merge back into earlier patches)
2026-10-26 21:57 [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Tony Luck
@ 2026-10-26 21:57 ` Tony Luck
2026-10-26 21:57 ` [RFC PATCH 2/8] x86/resctrl: Add L2CAT quirk for Intel Panther Lake Tony Luck
` (7 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Tony Luck @ 2026-10-26 21:57 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu
Cc: x86, linux-kernel, patches, Tony Luck
Make the UI of the "max" file show values per-domain so no changes
in UI are needed when support for asymmetric controls (L2 on hybrid
CPUs) is added later.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
Documentation/filesystems/resctrl.rst | 5 ++++-
fs/resctrl/rdtgroup.c | 27 ++++++++++++++++++++-------
2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/Documentation/filesystems/resctrl.rst b/Documentation/filesystems/resctrl.rst
index 434e6f42db4a..de162280a0fe 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -397,12 +397,15 @@ with individual files:
the schemata file.
"max":
+ Maximum values per domain in the same format as the schemata file.
+ Format of values depends on the type of the control:
+
When "type" == "scalar":
The maximum value that can be written to the control when writing
the schemata file.
When "type" == "bitmap":
- The supported bitmap (in hexadecimal with 0x prefix) with
+ The supported bitmap (in hexadecimal without 0x prefix) with
all bits set.
"tolerance":
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 416b73c57016..7119ad0029c1 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -2465,15 +2465,28 @@ static int resctrl_ctrl_max_show(struct kernfs_open_file *of,
struct seq_file *seq, void *v)
{
struct resctrl_ctrl *ctrl = rdt_kn_parent_priv(of->kn);
+ struct rdt_ctrl_domain *d;
+ bool sep = false;
- switch (ctrl->type) {
- case RESCTRL_CTRL_SCALAR:
- seq_printf(seq, "%u\n", ctrl->scalar.max);
- break;
- case RESCTRL_CTRL_BITMAP:
- seq_printf(seq, "0x%lx\n", BIT_MASK(ctrl->bitmap.cbm_len) - 1);
- break;
+ if (!info_kn_lock(of->kn))
+ return -ENOENT;
+
+ list_for_each_entry_rcu(d, &ctrl->domains, hdr.list, lockdep_is_cpus_held()) {
+ if (sep)
+ seq_putc(seq, ';');
+ switch (ctrl->type) {
+ case RESCTRL_CTRL_SCALAR:
+ seq_printf(seq, "%d=%u", d->hdr.id, ctrl->scalar.max);
+ break;
+ case RESCTRL_CTRL_BITMAP:
+ seq_printf(seq, "%d=%lx", d->hdr.id, BIT_MASK(ctrl->bitmap.cbm_len) - 1);
+ break;
+ }
+ sep = true;
}
+ seq_putc(seq, '\n');
+
+ info_kn_unlock(of->kn);
return 0;
}
--
2.56.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC PATCH 2/8] x86/resctrl: Add L2CAT quirk for Intel Panther Lake
2026-10-26 21:57 [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Tony Luck
2026-10-26 21:57 ` [RFC PATCH 1/8] fs/resctrl: Change UI of "max" file (merge back into earlier patches) Tony Luck
@ 2026-10-26 21:57 ` Tony Luck
2026-10-26 21:57 ` [RFC PATCH 3/8] x86/cpuid: Add and use defines for Intel RDT enumeration leaves Tony Luck
` (6 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Tony Luck @ 2026-10-26 21:57 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu
Cc: x86, linux-kernel, patches, Tony Luck
Intel CPUs enumerate Resource Director Technology (RDT) allocation
features in CPUID leaf 0x10 if the feature is symmetric across all CPUs
and in CPUID leaf 0x28 if the feature is asymmetric.
But the P-core on Panther Lake enumerates L2 cache allocation in leaf
0x10, even though the feature is asymmetric between P-core and E-core.
Use set_rdt_options() to disable the symmetric enumeration.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
arch/x86/kernel/cpu/resctrl/core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 7951cfd20da4..709075ffc706 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -1128,6 +1128,9 @@ static __init void __check_quirks_intel(void)
case INTEL_BROADWELL_X:
intel_rdt_mbm_apply_quirk();
break;
+ case INTEL_PANTHERLAKE_L:
+ set_rdt_options("!l2cat");
+ break;
}
}
--
2.56.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC PATCH 3/8] x86/cpuid: Add and use defines for Intel RDT enumeration leaves
2026-10-26 21:57 [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Tony Luck
2026-10-26 21:57 ` [RFC PATCH 1/8] fs/resctrl: Change UI of "max" file (merge back into earlier patches) Tony Luck
2026-10-26 21:57 ` [RFC PATCH 2/8] x86/resctrl: Add L2CAT quirk for Intel Panther Lake Tony Luck
@ 2026-10-26 21:57 ` Tony Luck
2026-10-26 21:57 ` [RFC PATCH 4/8] x86/resctrl: Add X86_FEATURE bits for asymmetric L2 Tony Luck
` (5 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Tony Luck @ 2026-10-26 21:57 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu
Cc: x86, linux-kernel, patches, Tony Luck
Intel Resource Director Technology (RDT) parameters are enumerated
in four leaves for (monitoring, allocation) * (symmetric, asymmetric).
Add defines for all four leaves.
Update code that hard-codes numerical values for the symmetric leaves.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
arch/x86/include/asm/cpuid/types.h | 4 ++++
arch/x86/kernel/cpu/resctrl/core.c | 8 ++++----
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/cpuid/types.h b/arch/x86/include/asm/cpuid/types.h
index 3d0e611c97ba..9594965a54e7 100644
--- a/arch/x86/include/asm/cpuid/types.h
+++ b/arch/x86/include/asm/cpuid/types.h
@@ -28,9 +28,13 @@ enum cpuid_regs_idx {
#define CPUID_LEAF_MWAIT 0x05
#define CPUID_LEAF_DCA 0x09
#define CPUID_LEAF_XSTATE 0x0d
+#define CPUID_LEAF_RDT_M 0x0f
+#define CPUID_LEAF_RDT_A 0x10
#define CPUID_LEAF_TSC 0x15
#define CPUID_LEAF_FREQ 0x16
#define CPUID_LEAF_TILE 0x1d
+#define CPUID_LEAF_RDT_M_ASYM 0x27
+#define CPUID_LEAF_RDT_A_ASYM 0x28
#define CPUID_RANGE(idx) ((idx) & 0xffff0000)
#define CPUID_RANGE_MAX(idx) (CPUID_RANGE(idx) + 0xffff)
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 709075ffc706..c66ff4cdd84b 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -235,7 +235,7 @@ static __init bool __get_mem_config_intel(struct rdt_resource *r)
union cpuid_0x10_x_edx edx;
u32 ebx, ecx, max_delay;
- cpuid_count(0x00000010, 3, &eax.full, &ebx, &ecx, &edx.full);
+ cpuid_count(CPUID_LEAF_RDT_A, 3, &eax.full, &ebx, &ecx, &edx.full);
hw_res->num_closid = edx.split.cos_max + 1;
max_delay = eax.split.max_delay + 1;
@@ -357,7 +357,7 @@ static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r)
union cpuid_0x10_x_edx edx;
u32 ebx, default_ctrl;
- cpuid_count(0x00000010, idx, &eax.full, &ebx, &ecx.full, &edx.full);
+ cpuid_count(CPUID_LEAF_RDT_A, idx, &eax.full, &ebx, &ecx.full, &edx.full);
hw_res->num_closid = edx.split.cos_max + 1;
hw_ctrl = kzalloc_obj(*hw_ctrl);
if (!hw_ctrl)
@@ -1196,7 +1196,7 @@ void resctrl_cpu_detect(struct cpuinfo_x86 *c)
}
/* will be overridden if occupancy monitoring exists */
- c->x86_cache_max_rmid = cpuid_ebx(0xf);
+ c->x86_cache_max_rmid = cpuid_ebx(CPUID_LEAF_RDT_M);
if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC) ||
cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL) ||
@@ -1205,7 +1205,7 @@ void resctrl_cpu_detect(struct cpuinfo_x86 *c)
u32 eax, ebx, ecx, edx;
/* QoS sub-leaf, EAX=0Fh, ECX=1 */
- cpuid_count(0xf, 1, &eax, &ebx, &ecx, &edx);
+ cpuid_count(CPUID_LEAF_RDT_M, 1, &eax, &ebx, &ecx, &edx);
c->x86_cache_max_rmid = ecx;
c->x86_cache_occ_scale = ebx;
--
2.56.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC PATCH 4/8] x86/resctrl: Add X86_FEATURE bits for asymmetric L2
2026-10-26 21:57 [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Tony Luck
` (2 preceding siblings ...)
2026-10-26 21:57 ` [RFC PATCH 3/8] x86/cpuid: Add and use defines for Intel RDT enumeration leaves Tony Luck
@ 2026-10-26 21:57 ` Tony Luck
2026-10-26 21:57 ` [RFC PATCH 5/8] x86/resctrl: Refactor rdt_get_cache_alloc_cfg() Tony Luck
` (4 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Tony Luck @ 2026-10-26 21:57 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu
Cc: x86, linux-kernel, patches, Tony Luck
CPUID(0x7,0x1).ECX[1] enumerates that a CPU may have some asymmetric
allocation features. These are enumerated in CPUID leaf 0x28 in a
parallel manner to CPUID leaf 0x10.
Create new #defines, add dependencies, and initialize from CPUID.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
arch/x86/include/asm/cpufeatures.h | 3 +++
arch/x86/kernel/cpu/cpuid-deps.c | 2 ++
arch/x86/kernel/cpu/scattered.c | 3 +++
3 files changed, 8 insertions(+)
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index f70ee74b5f92..8a800964c100 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -430,6 +430,9 @@
#define X86_FEATURE_SUCCOR (17*32+ 1) /* "succor" Uncorrectable error containment and recovery */
#define X86_FEATURE_CPPC_PERF_PRIO (17*32+ 2) /* CPPC Floor Perf support */
#define X86_FEATURE_SMCA (17*32+ 3) /* "smca" Scalable MCA */
+#define X86_FEATURE_RDT_A_ASYM (17*32+ 4) /* Asymmetric allocation features */
+#define X86_FEATURE_ASYM_CAT_L2 (17*32+ 5) /* Asymmetric Cache Allocation Technology L2 */
+#define X86_FEATURE_ASYM_CDP_L2 (17*32+ 6) /* Asymmetric Code and Data Prioritization L2 */
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* "avx512_4vnniw" AVX-512 Neural Network Instructions */
diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c
index 99801e844b30..b5d44cf12df6 100644
--- a/arch/x86/kernel/cpu/cpuid-deps.c
+++ b/arch/x86/kernel/cpu/cpuid-deps.c
@@ -73,6 +73,8 @@ static const struct cpuid_dep cpuid_deps[] = {
{ X86_FEATURE_BMEC, X86_FEATURE_CQM_MBM_TOTAL },
{ X86_FEATURE_BMEC, X86_FEATURE_CQM_MBM_LOCAL },
{ X86_FEATURE_SDCIAE, X86_FEATURE_CAT_L3 },
+ { X86_FEATURE_ASYM_CAT_L2, X86_FEATURE_RDT_A_ASYM },
+ { X86_FEATURE_ASYM_CDP_L2, X86_FEATURE_RDT_A_ASYM },
{ X86_FEATURE_AVX512_BF16, X86_FEATURE_AVX512VL },
{ X86_FEATURE_AVX512_FP16, X86_FEATURE_AVX512BW },
{ X86_FEATURE_ENQCMD, X86_FEATURE_XSAVES },
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
index 8665a6474806..02e405a95dbd 100644
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -28,6 +28,7 @@ static const struct cpuid_bit cpuid_bits[] = {
{ X86_FEATURE_APERFMPERF, CPUID_ECX, 0, 0x00000006, 0 },
{ X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 },
{ X86_FEATURE_INTEL_PPIN, CPUID_EBX, 0, 0x00000007, 1 },
+ { X86_FEATURE_RDT_A_ASYM, CPUID_ECX, 1, 0x00000007, 1 },
{ X86_FEATURE_MSR_IMM, CPUID_ECX, 5, 0x00000007, 1 },
{ X86_FEATURE_APX, CPUID_EDX, 21, 0x00000007, 1 },
{ X86_FEATURE_RRSBA_CTRL, CPUID_EDX, 2, 0x00000007, 2 },
@@ -46,6 +47,8 @@ static const struct cpuid_bit cpuid_bits[] = {
{ X86_FEATURE_SGX2, CPUID_EAX, 1, 0x00000012, 0 },
{ X86_FEATURE_SGX_EUPDATESVN, CPUID_EAX, 10, 0x00000012, 0 },
{ X86_FEATURE_SGX_EDECCSSA, CPUID_EAX, 11, 0x00000012, 0 },
+ { X86_FEATURE_ASYM_CAT_L2, CPUID_EBX, 2, 0x00000028, 0 },
+ { X86_FEATURE_ASYM_CDP_L2, CPUID_ECX, 2, 0x00000028, 2 },
{ X86_FEATURE_OVERFLOW_RECOV, CPUID_EBX, 0, 0x80000007, 0 },
{ X86_FEATURE_SUCCOR, CPUID_EBX, 1, 0x80000007, 0 },
{ X86_FEATURE_SMCA, CPUID_EBX, 3, 0x80000007, 0 },
--
2.56.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC PATCH 5/8] x86/resctrl: Refactor rdt_get_cache_alloc_cfg()
2026-10-26 21:57 [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Tony Luck
` (3 preceding siblings ...)
2026-10-26 21:57 ` [RFC PATCH 4/8] x86/resctrl: Add X86_FEATURE bits for asymmetric L2 Tony Luck
@ 2026-10-26 21:57 ` Tony Luck
2026-10-26 21:57 ` [RFC PATCH 6/8] arm,x86,fs/resctrl: Prepare for asymmetric caches Tony Luck
` (3 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Tony Luck @ 2026-10-26 21:57 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu
Cc: x86, linux-kernel, patches, Tony Luck
Enumeration of the parameters for L2 and L3 cache allocation is in
a common format in separate sub-leaves of CPUID leaf 0x10. A helper
function is used to process both L2 and L3.
Asymmetric enumeration is in leaf 0x28 in the same format as leaf 0x10.
In preparation to support asymmetric L2 configurations make the leaf
a parameter to rdt_get_cache_alloc_cfg().
No functional change.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
arch/x86/kernel/cpu/resctrl/core.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index c66ff4cdd84b..c26fc75ccc07 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -348,7 +348,7 @@ static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r)
return true;
}
-static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r)
+static void rdt_get_cache_alloc_cfg(int leaf, int idx, struct rdt_resource *r)
{
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
struct resctrl_hw_ctrl *hw_ctrl;
@@ -357,7 +357,7 @@ static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r)
union cpuid_0x10_x_edx edx;
u32 ebx, default_ctrl;
- cpuid_count(CPUID_LEAF_RDT_A, idx, &eax.full, &ebx, &ecx.full, &edx.full);
+ cpuid_count(leaf, idx, &eax.full, &ebx, &ecx.full, &edx.full);
hw_res->num_closid = edx.split.cos_max + 1;
hw_ctrl = kzalloc_obj(*hw_ctrl);
if (!hw_ctrl)
@@ -1061,7 +1061,7 @@ static __init bool get_rdt_alloc_resources(void)
if (rdt_cpu_has(X86_FEATURE_CAT_L3)) {
r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
- rdt_get_cache_alloc_cfg(1, r);
+ rdt_get_cache_alloc_cfg(CPUID_LEAF_RDT_A, 1, r);
if (rdt_cpu_has(X86_FEATURE_CDP_L3))
rdt_get_cdp_l3_config();
if (rdt_cpu_has(X86_FEATURE_SDCIAE))
@@ -1071,7 +1071,7 @@ static __init bool get_rdt_alloc_resources(void)
if (rdt_cpu_has(X86_FEATURE_CAT_L2)) {
/* CPUID 0x10.2 fields are same format at 0x10.1 */
r = &rdt_resources_all[RDT_RESOURCE_L2].r_resctrl;
- rdt_get_cache_alloc_cfg(2, r);
+ rdt_get_cache_alloc_cfg(CPUID_LEAF_RDT_A, 2, r);
if (rdt_cpu_has(X86_FEATURE_CDP_L2))
rdt_get_cdp_l2_config();
ret = true;
--
2.56.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC PATCH 6/8] arm,x86,fs/resctrl: Prepare for asymmetric caches
2026-10-26 21:57 [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Tony Luck
` (4 preceding siblings ...)
2026-10-26 21:57 ` [RFC PATCH 5/8] x86/resctrl: Refactor rdt_get_cache_alloc_cfg() Tony Luck
@ 2026-10-26 21:57 ` Tony Luck
2026-10-26 21:57 ` [RFC PATCH 7/8] x86/resctrl: Check for and enable asymmetric L2 cache allocation Tony Luck
` (2 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Tony Luck @ 2026-10-26 21:57 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu
Cc: x86, linux-kernel, patches, Tony Luck
Each struct resctrl_ctrl carries a struct resctrl_ctrl_bitmap that describes
properties (cbm_len, min_cbm_bits, shareable_bits, flags) shared by every
control domain using that control. This assumes all domains of a control are
symmetric. Future asymmetric systems may have control domains with differing
bitmap properties, in particular a @cbm_len that varies by cache instance.
Add a field to the rdt_ctrl_domain structure to store per-domain cache
bitmap lengths.
Update code that reads cbm_len to use the per-domain copy instead of the
resctrl_ctrl copy, so that domain-specific values will be picked up when
asymmetric domains are enumerated.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
include/linux/resctrl.h | 10 +++++++--
arch/x86/kernel/cpu/resctrl/core.c | 23 ++++++++++++++++---
arch/x86/kernel/cpu/resctrl/rdtgroup.c | 2 +-
drivers/resctrl/mpam_resctrl.c | 19 +++++++++++-----
fs/resctrl/ctrlmondata.c | 9 ++++----
fs/resctrl/pseudo_lock.c | 2 +-
fs/resctrl/rdtgroup.c | 31 ++++++++++++++------------
7 files changed, 65 insertions(+), 31 deletions(-)
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index f58a9e773ff6..8ac799d1feff 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -184,12 +184,15 @@ static inline bool domain_header_is_valid(struct rdt_domain_hdr *hdr,
* @mbps_val: When mba_sc is enabled, this holds the array of user
* specified control values for mba_sc in MBps, indexed
* by closid
+ * @cbm_len: Length of cache bitmask for a cache control in this
+ * domain
*/
struct rdt_ctrl_domain {
struct rdt_domain_hdr hdr;
struct pseudo_lock_region *plr;
struct resctrl_staged_config staged_config[CDP_NUM_TYPES];
u32 *mbps_val;
+ unsigned int cbm_len;
};
/**
@@ -597,8 +600,11 @@ void resctrl_arch_sync_cpu_closid_rmid(void *info);
* resctrl_get_default_ctrlval() - Return the default control value for this
* control.
* @ctrl: The control whose default control type is queried.
+ * @d: The control domain to query, or NULL if @ctrl's properties
+ * should be used instead (e.g. when no domain exists yet).
*/
-static inline u32 resctrl_get_default_ctrlval(struct resctrl_ctrl *ctrl)
+static inline u32 resctrl_get_default_ctrlval(struct resctrl_ctrl *ctrl,
+ struct rdt_ctrl_domain *d)
{
switch (ctrl->type) {
case RESCTRL_CTRL_BITMAP:
@@ -606,7 +612,7 @@ static inline u32 resctrl_get_default_ctrlval(struct resctrl_ctrl *ctrl)
* Should map to 100% allocation as exposed to user space
* via "cbm_mask".
*/
- return BIT_MASK(ctrl->bitmap.cbm_len) - 1;
+ return BIT_MASK(d ? d->cbm_len : ctrl->bitmap.cbm_len) - 1;
case RESCTRL_CTRL_SCALAR:
return ctrl->scalar.reset_val;
}
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index c26fc75ccc07..f6b7358e50d7 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -485,14 +485,14 @@ void rdt_ctrl_update(void *arg)
}
static void setup_default_ctrlval(struct rdt_resource *r, struct resctrl_ctrl *ctrl,
- u32 *dc)
+ u32 *dc, struct rdt_ctrl_domain *d)
{
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
int i;
/* Initialize the control MSRs to their reset values. */
for (i = 0; i < hw_res->num_closid; i++, dc++)
- *dc = resctrl_get_default_ctrlval(ctrl);
+ *dc = resctrl_get_default_ctrlval(ctrl, d);
}
static void ctrl_domain_free(struct rdt_hw_ctrl_domain *hw_dom)
@@ -525,7 +525,7 @@ static int domain_setup_ctrlval(struct rdt_resource *r, struct resctrl_ctrl *ctr
return -ENOMEM;
hw_dom->ctrl_val = dc;
- setup_default_ctrlval(r, ctrl, dc);
+ setup_default_ctrlval(r, ctrl, dc, d);
m.res = r;
m.ctrl = ctrl;
@@ -585,6 +585,22 @@ static int get_domain_id_from_scope(int cpu, enum resctrl_scope scope)
return -EINVAL;
}
+/*
+ * Take a snapshot of the cache bitmask length for cache controls (with
+ * the assumption that there is only one cache control for a resource).
+ */
+static void rdt_sync_ctrl_bitmap(struct rdt_resource *r, struct rdt_ctrl_domain *d)
+{
+ struct resctrl_ctrl *ctrl;
+
+ for_each_resource_ctrl(ctrl, r) {
+ if (ctrl->type != RESCTRL_CTRL_BITMAP)
+ continue;
+ d->cbm_len = ctrl->bitmap.cbm_len;
+ break;
+ }
+}
+
static void domain_add_cpu_ctrl(int cpu, struct rdt_resource *r,
struct resctrl_ctrl *ctrl)
{
@@ -625,6 +641,7 @@ static void domain_add_cpu_ctrl(int cpu, struct rdt_resource *r,
d->hdr.type = RESCTRL_CTRL_DOMAIN;
d->hdr.rid = r->rid;
cpumask_set_cpu(cpu, &d->hdr.cpu_mask);
+ rdt_sync_ctrl_bitmap(r, d);
rdt_domain_reconfigure_cdp(r);
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index edf42c59d7c1..691cd9fb1687 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -257,7 +257,7 @@ void resctrl_arch_reset_all_ctrls(struct rdt_resource *r)
hw_dom = resctrl_to_arch_ctrl_dom(d);
for (i = 0; i < hw_res->num_closid; i++)
- hw_dom->ctrl_val[i] = resctrl_get_default_ctrlval(ctrl);
+ hw_dom->ctrl_val[i] = resctrl_get_default_ctrlval(ctrl, d);
msr_param.dom = d;
smp_call_function_any(&d->hdr.cpu_mask, rdt_ctrl_update, &msr_param, 1);
}
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index 7a3afb6a411e..e420ca81434b 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -1246,7 +1246,7 @@ static int mpam_resctrl_control_init(struct mpam_resctrl_res *res)
* we have configured the SMMU and GIC not to do this 'all the
* bits' is the correct answer here.
*/
- mpam_ctrl->r_ctrl.bitmap.shareable_bits = resctrl_get_default_ctrlval(&mpam_ctrl->r_ctrl);
+ mpam_ctrl->r_ctrl.bitmap.shareable_bits = resctrl_get_default_ctrlval(&mpam_ctrl->r_ctrl, NULL);
list_add(&mpam_ctrl->r_ctrl.entry, &r->controls);
r->alloc_capable = true;
break;
@@ -1411,7 +1411,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct resctrl_ctrl *ctrl,
lockdep_assert_cpus_held();
if (!mpam_is_enabled())
- return resctrl_get_default_ctrlval(ctrl);
+ return resctrl_get_default_ctrlval(ctrl, d);
res = container_of(r, struct mpam_resctrl_res, resctrl_res);
dom = container_of(d, struct mpam_resctrl_dom, resctrl_ctrl_dom);
@@ -1440,12 +1440,12 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct resctrl_ctrl *ctrl,
}
fallthrough;
default:
- return resctrl_get_default_ctrlval(ctrl);
+ return resctrl_get_default_ctrlval(ctrl, d);
}
if (!r->alloc_capable || partid >= resctrl_arch_get_num_closid(r) ||
!mpam_has_feature(configured_by, cfg))
- return resctrl_get_default_ctrlval(ctrl);
+ return resctrl_get_default_ctrlval(ctrl, d);
switch (configured_by) {
case mpam_feat_cpor_part:
@@ -1453,7 +1453,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct resctrl_ctrl *ctrl,
case mpam_feat_mbw_max:
return mbw_max_to_percent(cfg->mbw_max, cprops);
default:
- return resctrl_get_default_ctrlval(ctrl);
+ return resctrl_get_default_ctrlval(ctrl, d);
}
}
@@ -1864,16 +1864,23 @@ int mpam_resctrl_online_cpu(unsigned int cpu)
if (r->alloc_capable) {
for_each_resource_ctrl(ctrl, r) {
+ struct rdt_ctrl_domain *ctrl_d;
+
dom = mpam_resctrl_get_ctrl_domain_from_cpu(cpu, ctrl);
if (!dom) {
dom = mpam_resctrl_alloc_ctrl_domain(cpu, res, ctrl);
if (IS_ERR(dom))
return PTR_ERR(dom);
} else {
- struct rdt_ctrl_domain *ctrl_d = &dom->resctrl_ctrl_dom;
+ ctrl_d = &dom->resctrl_ctrl_dom;
mpam_resctrl_online_domain_hdr(cpu, &ctrl_d->hdr);
}
+
+ if (ctrl->type == RESCTRL_CTRL_BITMAP) {
+ ctrl_d = &dom->resctrl_ctrl_dom;
+ ctrl_d->cbm_len = ctrl->bitmap.cbm_len;
+ }
}
}
if (r->mon_capable) {
diff --git a/fs/resctrl/ctrlmondata.c b/fs/resctrl/ctrlmondata.c
index 627998fed555..90274fdb0364 100644
--- a/fs/resctrl/ctrlmondata.c
+++ b/fs/resctrl/ctrlmondata.c
@@ -189,10 +189,11 @@ static int parse_bw(struct rdt_parse_data *data, struct rdt_resource_final *f,
* requires at least two bits set.
* AMD allows non-contiguous bitmasks.
*/
-static bool cbm_validate(char *buf, u32 *data, struct resctrl_ctrl *ctrl)
+static bool cbm_validate(char *buf, u32 *data, struct rdt_ctrl_domain *d,
+ struct resctrl_ctrl *ctrl)
{
- u32 supported_bits = BIT_MASK(ctrl->bitmap.cbm_len) - 1;
- unsigned int cbm_len = ctrl->bitmap.cbm_len;
+ u32 supported_bits = BIT_MASK(d->cbm_len) - 1;
+ unsigned int cbm_len = d->cbm_len;
unsigned long first_bit, zero_bit, val;
int ret;
@@ -255,7 +256,7 @@ static int parse_cbm(struct rdt_parse_data *data, struct rdt_resource_final *f,
return -EINVAL;
}
- if (!cbm_validate(data->buf, &cbm_val, ctrl))
+ if (!cbm_validate(data->buf, &cbm_val, d, ctrl))
return -EINVAL;
if ((mode == RDT_MODE_EXCLUSIVE || mode == RDT_MODE_SHAREABLE) &&
diff --git a/fs/resctrl/pseudo_lock.c b/fs/resctrl/pseudo_lock.c
index 17b99a075eaf..1f2e2da28bc5 100644
--- a/fs/resctrl/pseudo_lock.c
+++ b/fs/resctrl/pseudo_lock.c
@@ -637,7 +637,7 @@ bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_ctrl_domain *d, unsigned lon
return false;
}
- cbm_len = ctrl->bitmap.cbm_len;
+ cbm_len = d->cbm_len;
cbm_b = d->plr->cbm;
if (bitmap_intersects(&cbm, &cbm_b, cbm_len))
return true;
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 7119ad0029c1..46d39332706e 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -1106,7 +1106,7 @@ static int rdt_default_ctrl_show(struct kernfs_open_file *of,
if (!ctrl)
goto out_unlock;
- seq_printf(seq, "%x\n", resctrl_get_default_ctrlval(ctrl));
+ seq_printf(seq, "%x\n", resctrl_get_default_ctrlval(ctrl, NULL));
out_unlock:
info_kn_unlock(of->kn);
@@ -1250,7 +1250,7 @@ static int rdt_bit_usage_show(struct kernfs_open_file *of,
hw_shareable |= ctrl_val;
}
- for (i = ctrl->bitmap.cbm_len - 1; i >= 0; i--) {
+ for (i = dom->cbm_len - 1; i >= 0; i--) {
pseudo_locked = dom->plr ? dom->plr->cbm : 0;
hwb = test_bit(i, &hw_shareable);
swb = test_bit(i, &sw_shareable);
@@ -1546,7 +1546,7 @@ static bool __rdtgroup_cbm_overlaps(struct rdt_resource *r, struct rdt_ctrl_doma
/* Check for any overlap with regions used by hardware directly */
if (!exclusive) {
ctrl_b = ctrl->bitmap.shareable_bits;
- if (bitmap_intersects(&cbm, &ctrl_b, ctrl->bitmap.cbm_len))
+ if (bitmap_intersects(&cbm, &ctrl_b, d->cbm_len))
return true;
}
@@ -1556,7 +1556,7 @@ static bool __rdtgroup_cbm_overlaps(struct rdt_resource *r, struct rdt_ctrl_doma
mode = rdtgroup_mode_by_closid(i);
if (closid_allocated(i) && i != closid &&
mode != RDT_MODE_PSEUDO_LOCKSETUP) {
- if (bitmap_intersects(&cbm, &ctrl_b, ctrl->bitmap.cbm_len)) {
+ if (bitmap_intersects(&cbm, &ctrl_b, d->cbm_len)) {
if (exclusive) {
if (mode == RDT_MODE_EXCLUSIVE)
return true;
@@ -1761,10 +1761,10 @@ unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r, struct resctrl_ctrl *c
if (WARN_ON_ONCE(r->ctrl_scope != RESCTRL_L2_CACHE && r->ctrl_scope != RESCTRL_L3_CACHE))
return size;
- num_b = bitmap_weight(&cbm, ctrl->bitmap.cbm_len);
+ num_b = bitmap_weight(&cbm, d->cbm_len);
ci = get_cpu_cacheinfo_level(cpumask_any(&d->hdr.cpu_mask), r->ctrl_scope);
if (ci)
- size = ci->size / ctrl->bitmap.cbm_len * num_b;
+ size = ci->size / d->cbm_len * num_b;
return size;
}
@@ -2479,7 +2479,7 @@ static int resctrl_ctrl_max_show(struct kernfs_open_file *of,
seq_printf(seq, "%d=%u", d->hdr.id, ctrl->scalar.max);
break;
case RESCTRL_CTRL_BITMAP:
- seq_printf(seq, "%d=%lx", d->hdr.id, BIT_MASK(ctrl->bitmap.cbm_len) - 1);
+ seq_printf(seq, "%d=%lx", d->hdr.id, BIT_MASK(d->cbm_len) - 1);
break;
}
sep = true;
@@ -4227,6 +4227,9 @@ static int mkdir_mondata_all(struct kernfs_node *parent_kn,
* cbm_ensure_valid - Enforce validity on provided CBM
* @_val: Candidate CBM
* @r: RDT resource to which the CBM belongs
+ * @d: RDT domain to which the CBM belongs. Its bitmap properties
+ * (e.g. @cbm_len) are used since these may differ from
+ * @ctrl's on asymmetric systems.
* @ctrl: Properties of the bitmap control CBM should be tested against.
*
* The provided CBM represents all cache portions available for use. This
@@ -4241,10 +4244,10 @@ static int mkdir_mondata_all(struct kernfs_node *parent_kn,
*
* Return: A CBM that is valid for resource @r.
*/
-static u32 cbm_ensure_valid(u32 _val, struct rdt_resource *r,
+static u32 cbm_ensure_valid(u32 _val, struct rdt_resource *r, struct rdt_ctrl_domain *d,
struct resctrl_ctrl *ctrl)
{
- unsigned int cbm_len = ctrl->bitmap.cbm_len;
+ unsigned int cbm_len = d->cbm_len;
unsigned long first_bit, zero_bit;
unsigned long val;
@@ -4312,20 +4315,20 @@ static int __init_one_rdt_domain(struct rdt_ctrl_domain *d, struct rdt_resource_
}
if (d->plr && d->plr->cbm > 0)
used_b |= d->plr->cbm;
- unused_b = used_b ^ (BIT_MASK(ctrl->bitmap.cbm_len) - 1);
- unused_b &= BIT_MASK(ctrl->bitmap.cbm_len) - 1;
+ unused_b = used_b ^ (BIT_MASK(d->cbm_len) - 1);
+ unused_b &= BIT_MASK(d->cbm_len) - 1;
cfg->new_ctrl |= unused_b;
/*
* Force the initial CBM to be valid, user can
* modify the CBM based on system availability.
*/
- cfg->new_ctrl = cbm_ensure_valid(cfg->new_ctrl, r, ctrl);
+ cfg->new_ctrl = cbm_ensure_valid(cfg->new_ctrl, r, d, ctrl);
/*
* Assign the u32 CBM to an unsigned long to ensure that
* bitmap_weight() does not access out-of-bound memory.
*/
tmp_cbm = cfg->new_ctrl;
- if (bitmap_weight(&tmp_cbm, ctrl->bitmap.cbm_len) < ctrl->bitmap.min_cbm_bits) {
+ if (bitmap_weight(&tmp_cbm, d->cbm_len) < ctrl->bitmap.min_cbm_bits) {
rdt_last_cmd_printf("No space on %s:%d\n", f->name, d->hdr.id);
return -ENOSPC;
}
@@ -4373,7 +4376,7 @@ static void rdtgroup_init_mba(struct rdt_resource *r, struct resctrl_ctrl *ctrl,
}
cfg = &d->staged_config[CDP_NONE];
- cfg->new_ctrl = resctrl_get_default_ctrlval(ctrl);
+ cfg->new_ctrl = resctrl_get_default_ctrlval(ctrl, d);
cfg->have_new_ctrl = true;
}
}
--
2.56.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC PATCH 7/8] x86/resctrl: Check for and enable asymmetric L2 cache allocation
2026-10-26 21:57 [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Tony Luck
` (5 preceding siblings ...)
2026-10-26 21:57 ` [RFC PATCH 6/8] arm,x86,fs/resctrl: Prepare for asymmetric caches Tony Luck
@ 2026-10-26 21:57 ` Tony Luck
2026-10-26 21:57 ` [RFC PATCH 8/8] fs/resctrl: Suppress creation of cbm_mask info file on asymmetric systems Tony Luck
2026-10-26 22:30 ` [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Reinette Chatre
8 siblings, 0 replies; 12+ messages in thread
From: Tony Luck @ 2026-10-26 21:57 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu
Cc: x86, linux-kernel, patches, Tony Luck
Systems with asymmetric L2 allocation do not enumerate using CPUID
leaf 0x10, they use leaf 0x28 instead.
Add a check for asymmetric allocation support (and update the check
for symmetric support to use cpu_feature_enabled()).
Enumerate the per-domain cache bit mask length for asymmetric L2
cache implementations. Rename the resource to "L2A" to avoid
confusing legacy code that only understands symmetric L2 cache.
The only asymmetric L2 feature of note is the cache bit mask length.
Other features are assumed to be symmetric.
Flag the resource as asymmetric for use by file system code.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
include/linux/resctrl.h | 2 ++
arch/x86/kernel/cpu/resctrl/core.c | 26 ++++++++++++++++++++++++--
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 8ac799d1feff..ef1c96b8f679 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -495,6 +495,7 @@ enum resctrl_ctrl_mode {
* @mon_domains: RCU list of all monitor domains for this resource
* @name: Name to use in "schemata" file.
* @cdp_capable: Is the CDP feature available on this resource
+ * @asymmetric: Are domains in the resource asymmetric
* @bw_throttle_mode: Bandwidth throttling mode when threads request
* different memory bandwidths
* @cache_io_alloc_capable:True if portion of the cache can be configured
@@ -513,6 +514,7 @@ struct rdt_resource {
struct list_head mon_domains;
char *name;
bool cdp_capable;
+ bool asymmetric;
enum membw_throttle_mode bw_throttle_mode;
bool cache_io_alloc_capable;
enum resctrl_ctrl_mode ctrl_mode;
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index f6b7358e50d7..4e2fdc7e9fe9 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -348,6 +348,16 @@ static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r)
return true;
}
+static int rdt_get_l2_asym_cbm_len(void)
+{
+ union cpuid_0x10_1_eax eax;
+ u32 ebx, ecx, edx;
+
+ cpuid_count(CPUID_LEAF_RDT_A_ASYM, 2, &eax.full, &ebx, &ecx, &edx);
+
+ return eax.split.cbm_len + 1;
+}
+
static void rdt_get_cache_alloc_cfg(int leaf, int idx, struct rdt_resource *r)
{
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
@@ -596,7 +606,10 @@ static void rdt_sync_ctrl_bitmap(struct rdt_resource *r, struct rdt_ctrl_domain
for_each_resource_ctrl(ctrl, r) {
if (ctrl->type != RESCTRL_CTRL_BITMAP)
continue;
- d->cbm_len = ctrl->bitmap.cbm_len;
+ if (r->asymmetric)
+ d->cbm_len = rdt_get_l2_asym_cbm_len();
+ else
+ d->cbm_len = ctrl->bitmap.cbm_len;
break;
}
}
@@ -1073,7 +1086,7 @@ static __init bool get_rdt_alloc_resources(void)
if (rdt_alloc_capable)
return true;
- if (!boot_cpu_has(X86_FEATURE_RDT_A))
+ if (!cpu_feature_enabled(X86_FEATURE_RDT_A) && !cpu_feature_enabled(X86_FEATURE_RDT_A_ASYM))
return false;
if (rdt_cpu_has(X86_FEATURE_CAT_L3)) {
@@ -1092,6 +1105,15 @@ static __init bool get_rdt_alloc_resources(void)
if (rdt_cpu_has(X86_FEATURE_CDP_L2))
rdt_get_cdp_l2_config();
ret = true;
+ } else if (rdt_cpu_has(X86_FEATURE_ASYM_CAT_L2)) {
+ /* CPUID 0x28.2 fields are same format as 0x10.1 */
+ r = &rdt_resources_all[RDT_RESOURCE_L2].r_resctrl;
+ rdt_get_cache_alloc_cfg(CPUID_LEAF_RDT_A_ASYM, 2, r);
+ if (rdt_cpu_has(X86_FEATURE_ASYM_CDP_L2))
+ rdt_get_cdp_l2_config();
+ r->asymmetric = true;
+ r->name = "L2A";
+ ret = true;
}
if (get_mem_config())
--
2.56.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC PATCH 8/8] fs/resctrl: Suppress creation of cbm_mask info file on asymmetric systems
2026-10-26 21:57 [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Tony Luck
` (6 preceding siblings ...)
2026-10-26 21:57 ` [RFC PATCH 7/8] x86/resctrl: Check for and enable asymmetric L2 cache allocation Tony Luck
@ 2026-10-26 21:57 ` Tony Luck
2026-10-26 22:30 ` [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Reinette Chatre
8 siblings, 0 replies; 12+ messages in thread
From: Tony Luck @ 2026-10-26 21:57 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu
Cc: x86, linux-kernel, patches, Tony Luck
Hybrid CPUs with a mix of P-cores and E-cores may support different
cache allocation bit masks. The per-domain masks are described in the
info/L2A/schemata/L2A/max file.
The cbm_mask file contains a single value and cannot describe an
asymmetric system.
Skip creating cbm_mask in the info/L2A directory.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
Documentation/filesystems/resctrl.rst | 4 ++++
fs/resctrl/internal.h | 2 ++
fs/resctrl/rdtgroup.c | 5 ++++-
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/Documentation/filesystems/resctrl.rst b/Documentation/filesystems/resctrl.rst
index de162280a0fe..25e9e5e5e738 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -91,6 +91,10 @@ related to allocation:
"cbm_mask":
The bitmask which is valid for this resource.
This mask is equivalent to 100%.
+ Not present for asymmetric L2 allocation (L2A), where
+ valid masks can differ between domains. Use the bitmap
+ control's "max" file under "info/L2A/schemata/" to obtain
+ the per-domain masks.
"min_cbm_bits":
The minimum number of consecutive bits which
must be set when writing a mask.
diff --git a/fs/resctrl/internal.h b/fs/resctrl/internal.h
index 4bd09b1541c7..d93d349db08b 100644
--- a/fs/resctrl/internal.h
+++ b/fs/resctrl/internal.h
@@ -261,6 +261,8 @@ struct rdtgroup {
#define RFTYPE_RES_PERF_PKG BIT(12)
+#define RFTYPE_RES_COMMON_CBM BIT(13)
+
#define RFTYPE_CTRL_INFO (RFTYPE_INFO | RFTYPE_CTRL)
#define RFTYPE_MON_INFO (RFTYPE_INFO | RFTYPE_MON)
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 46d39332706e..5cf6a257bea8 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -2196,7 +2196,8 @@ static struct rftype res_common_files[] = {
.mode = 0444,
.kf_ops = &rdtgroup_kf_single_ops,
.seq_show = rdt_default_ctrl_show,
- .fflags = RFTYPE_CTRL_INFO | RFTYPE_RES_CACHE,
+ .fflags = RFTYPE_CTRL_INFO | RFTYPE_RES_CACHE |
+ RFTYPE_RES_COMMON_CBM,
},
{
.name = "num_mbm_cntrs",
@@ -3024,6 +3025,8 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn)
list_for_each_entry(f, &rdt_resource_final_all, list) {
r = f->res;
fflags = fflags_from_resource(r) | RFTYPE_CTRL_INFO;
+ if ((fflags & RFTYPE_RES_CACHE) && !r->asymmetric)
+ fflags |= RFTYPE_RES_COMMON_CBM;
kn_res = rdtgroup_mkdir_info_resdir(f, f->name, fflags);
if (IS_ERR(kn_res)) {
ret = PTR_ERR(kn_res);
--
2.56.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation
2026-10-26 21:57 [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Tony Luck
` (7 preceding siblings ...)
2026-10-26 21:57 ` [RFC PATCH 8/8] fs/resctrl: Suppress creation of cbm_mask info file on asymmetric systems Tony Luck
@ 2026-10-26 22:30 ` Reinette Chatre
2026-10-27 17:41 ` Luck, Tony
8 siblings, 1 reply; 12+ messages in thread
From: Reinette Chatre @ 2026-10-26 22:30 UTC (permalink / raw)
To: Tony Luck, Fenghua Yu, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu
Cc: x86, linux-kernel, patches
Hi Tony,
On 10/26/26 2:57 PM, Tony Luck wrote:
> RFC patch series built on top of Reinette's multiple control series[1]
>
> The goal is to support L2 cache allocation on hybrid Intel CPUs such as
> Panther Lake[2] where the P-core and E-core CPUs have different number
> of supported bits for L2 cache bit mask controls. N.B. it is assumned
> that the only point of asymmetry is the cache bit mask length. Other
> parameters must be the same (but code doesn't check).
>
> Overall approach is to add the per-L2 cache bitmask length to the domain
> and use that everywhere instead of using a single value from the control.
>
> Patch 1 changes the format of the per-control "max" file and should be
> merged back into Reinette's multi-control series so this file can have
> a consistent format from first upstream introduction.
>
> Patches 2-5 are enumeration and preperation.
>
> Patch 6 introduces, initializes, and uses the per-domain cache bit mask
> length field (arm/MPAM change needs careful scrutiny).
>
> Patch 7 enables asymmetric L2 for x86 CPUs that enumerate it. N.B. it
> renammes the resource from "L2" to "L2A" to avoid user interface issues
> with tools that expect L2 cache allocation to be symmetric.
I did a quick scan and it seems to ignore the the distinction between a resource
and control as highlighted the previous time you brought up this work. Specifically,
please see:
https://lore.kernel.org/lkml/eaeb4259-46d6-4656-8354-669ad32654b5@intel.com/
Also, why does patch #1 drop the 0x prefix from new control interface when displaying hex
values to user space? This is a significant change for which patch #1 does not provide
a motivation.
Reinette
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation
2026-10-26 22:30 ` [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Reinette Chatre
@ 2026-10-27 17:41 ` Luck, Tony
2026-10-27 18:30 ` Reinette Chatre
0 siblings, 1 reply; 12+ messages in thread
From: Luck, Tony @ 2026-10-27 17:41 UTC (permalink / raw)
To: Reinette Chatre
Cc: Fenghua Yu, Maciej Wieczor-Retman, Peter Newman, James Morse,
Babu Moger, Drew Fustini, Dave Martin, Chen Yu, x86,
linux-kernel, patches
On Mon, Oct 26, 2026 at 03:30:57PM -0700, Reinette Chatre wrote:
> Hi Tony,
>
> On 10/26/26 2:57 PM, Tony Luck wrote:
> > RFC patch series built on top of Reinette's multiple control series[1]
> >
> > The goal is to support L2 cache allocation on hybrid Intel CPUs such as
> > Panther Lake[2] where the P-core and E-core CPUs have different number
> > of supported bits for L2 cache bit mask controls. N.B. it is assumned
> > that the only point of asymmetry is the cache bit mask length. Other
> > parameters must be the same (but code doesn't check).
> >
> > Overall approach is to add the per-L2 cache bitmask length to the domain
> > and use that everywhere instead of using a single value from the control.
> >
> > Patch 1 changes the format of the per-control "max" file and should be
> > merged back into Reinette's multi-control series so this file can have
> > a consistent format from first upstream introduction.
> >
> > Patches 2-5 are enumeration and preperation.
> >
> > Patch 6 introduces, initializes, and uses the per-domain cache bit mask
> > length field (arm/MPAM change needs careful scrutiny).
> >
> > Patch 7 enables asymmetric L2 for x86 CPUs that enumerate it. N.B. it
> > renammes the resource from "L2" to "L2A" to avoid user interface issues
> > with tools that expect L2 cache allocation to be symmetric.
>
> I did a quick scan and it seems to ignore the the distinction between a resource
> and control as highlighted the previous time you brought up this work. Specifically,
> please see:
>
> https://lore.kernel.org/lkml/eaeb4259-46d6-4656-8354-669ad32654b5@intel.com/
I think I see now. You want the "asymmetry" to be a property of the
control, not of the resource.
So the resource name stays as "L2" but the control gets a suffix (e.g. "_ASYM")
File system looks like this:
# tree
.
├── cpus
├── cpus_list
├── info
│ ├── L2
│ │ ├── bit_usage
│ │ ├── control_mode
│ │ ├── min_cbm_bits
│ │ ├── num_closids
│ │ ├── schemata
│ │ │ └── L2_ASYM
│ │ │ ├── max
│ │ │ ├── min_bits
│ │ │ └── type
│ │ ├── shareable_bits
│ │ └── sparse_masks
│ └── last_cmd_status
├── mode
├── schemata
├── size
└── tasks
and the schemata file:
# cat schemata
L2_ASYM:0=fff;1=fff;2=fff;3=fff;4=ffff;5=ffff;8=ffff
>
> Also, why does patch #1 drop the 0x prefix from new control interface when displaying hex
> values to user space? This is a significant change for which patch #1 does not provide
> a motivation.
Sorry for missing out the justification. I thought that matching the
format of the schemata file would be more useful. Then someone could
reset a group to maximum values with:
# echo L2_ASYM:$(cat /sys/fs/resctrl/info/L2/schemata/L2_ASYM/max) > schemata
But if you like the "0x" prefixes I'm OK with that too. Just need to
replace "cat" with "sed -e s/0x//g" to reset to maximum values.
>
> Reinette
-Tony
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation
2026-10-27 17:41 ` Luck, Tony
@ 2026-10-27 18:30 ` Reinette Chatre
0 siblings, 0 replies; 12+ messages in thread
From: Reinette Chatre @ 2026-10-27 18:30 UTC (permalink / raw)
To: Luck, Tony
Cc: Fenghua Yu, Maciej Wieczor-Retman, Peter Newman, James Morse,
Babu Moger, Drew Fustini, Dave Martin, Chen Yu, x86,
linux-kernel, patches
Hi Tony,
On 10/27/26 10:41 AM, Luck, Tony wrote:
> On Mon, Oct 26, 2026 at 03:30:57PM -0700, Reinette Chatre wrote:
>> Hi Tony,
>>
>> On 10/26/26 2:57 PM, Tony Luck wrote:
>>> RFC patch series built on top of Reinette's multiple control series[1]
>>>
>>> The goal is to support L2 cache allocation on hybrid Intel CPUs such as
>>> Panther Lake[2] where the P-core and E-core CPUs have different number
>>> of supported bits for L2 cache bit mask controls. N.B. it is assumned
>>> that the only point of asymmetry is the cache bit mask length. Other
>>> parameters must be the same (but code doesn't check).
>>>
>>> Overall approach is to add the per-L2 cache bitmask length to the domain
>>> and use that everywhere instead of using a single value from the control.
>>>
>>> Patch 1 changes the format of the per-control "max" file and should be
>>> merged back into Reinette's multi-control series so this file can have
>>> a consistent format from first upstream introduction.
>>>
>>> Patches 2-5 are enumeration and preperation.
>>>
>>> Patch 6 introduces, initializes, and uses the per-domain cache bit mask
>>> length field (arm/MPAM change needs careful scrutiny).
>>>
>>> Patch 7 enables asymmetric L2 for x86 CPUs that enumerate it. N.B. it
>>> renammes the resource from "L2" to "L2A" to avoid user interface issues
>>> with tools that expect L2 cache allocation to be symmetric.
>>
>> I did a quick scan and it seems to ignore the the distinction between a resource
>> and control as highlighted the previous time you brought up this work. Specifically,
>> please see:
>>
>> https://lore.kernel.org/lkml/eaeb4259-46d6-4656-8354-669ad32654b5@intel.com/
>
> I think I see now. You want the "asymmetry" to be a property of the
> control, not of the resource.
Asymmetry could be a property of the resource but this is not what this proposal
does. This proposal creates a new L2 resource under a different name when resctrl
already has an L2 resource.
>
> So the resource name stays as "L2" but the control gets a suffix (e.g. "_ASYM")
For a new control this is reasonable, but since L2 is a legacy resource it is
expected to have a control with the same name as the resource to not break
user space. This is what I aimed to highlighted in the previous thread.
>
> File system looks like this:
>
> # tree
> .
> ├── cpus
> ├── cpus_list
> ├── info
> │ ├── L2
> │ │ ├── bit_usage
> │ │ ├── control_mode
> │ │ ├── min_cbm_bits
> │ │ ├── num_closids
> │ │ ├── schemata
This needs an L2 control. As I highlighted in
https://lore.kernel.org/lkml/22ecec13-a703-414e-9f5e-75c89173e845@intel.com/
when considering pqos utility user space expects an L2 schemata file entry
when there is an L2 resource.
Since L2_ASYM is the native interface it could be used to emulate the legacy L2 control
albeit with poor performance. By default the schemata file only contains the L2 control
and a user space familiar with new interface can enable L2_ASYM to replace L2 control
in schemata file.
When I mentioned this before you referred to it as:
"I'm not seeing a market for the legacy behavior, so implementing it
would just add complexity to resctrl without any benefit to users."
https://lore.kernel.org/lkml/as6Y72SbiXcJh6Ei@agluck-desk3/
I aimed to highlight in that discussion that users depend on this behavior.
> │ │ │ └── L2_ASYM
> │ │ │ ├── max
> │ │ │ ├── min_bits
> │ │ │ └── type
> │ │ ├── shareable_bits
> │ │ └── sparse_masks
> │ └── last_cmd_status
> ├── mode
> ├── schemata
> ├── size
> └── tasks
>
> and the schemata file:
>
> # cat schemata
> L2_ASYM:0=fff;1=fff;2=fff;3=fff;4=ffff;5=ffff;8=ffff
If there is a L2 resource then schemata file should only contain L2_ASYM if user space
indicates familiarity with new interface.
>
>>
>> Also, why does patch #1 drop the 0x prefix from new control interface when displaying hex
>> values to user space? This is a significant change for which patch #1 does not provide
>> a motivation.
>
> Sorry for missing out the justification. I thought that matching the
> format of the schemata file would be more useful. Then someone could
> reset a group to maximum values with:
>
> # echo L2_ASYM:$(cat /sys/fs/resctrl/info/L2/schemata/L2_ASYM/max) > schemata
>
> But if you like the "0x" prefixes I'm OK with that too. Just need to
> replace "cat" with "sed -e s/0x//g" to reset to maximum values.
CBM writes to schemata file accepts 0x prefix, no?
The 0x prefix is from the original interface proposal that aims support
generic parsing:
https://lore.kernel.org/lkml/aPtfMFfLV1l%2FRB0L@e133380.arm.com/
I see your point about matching the schemata file though. Now that the max is
per domain it really does resemble the schemata entry more closely. The bitmap
max could thus be expected to match the schemata entry more closely, forcing us to
carry this display decision into the new interface.
Reinette
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-10-27 18:30 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-26 21:57 [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Tony Luck
2026-10-26 21:57 ` [RFC PATCH 1/8] fs/resctrl: Change UI of "max" file (merge back into earlier patches) Tony Luck
2026-10-26 21:57 ` [RFC PATCH 2/8] x86/resctrl: Add L2CAT quirk for Intel Panther Lake Tony Luck
2026-10-26 21:57 ` [RFC PATCH 3/8] x86/cpuid: Add and use defines for Intel RDT enumeration leaves Tony Luck
2026-10-26 21:57 ` [RFC PATCH 4/8] x86/resctrl: Add X86_FEATURE bits for asymmetric L2 Tony Luck
2026-10-26 21:57 ` [RFC PATCH 5/8] x86/resctrl: Refactor rdt_get_cache_alloc_cfg() Tony Luck
2026-10-26 21:57 ` [RFC PATCH 6/8] arm,x86,fs/resctrl: Prepare for asymmetric caches Tony Luck
2026-10-26 21:57 ` [RFC PATCH 7/8] x86/resctrl: Check for and enable asymmetric L2 cache allocation Tony Luck
2026-10-26 21:57 ` [RFC PATCH 8/8] fs/resctrl: Suppress creation of cbm_mask info file on asymmetric systems Tony Luck
2026-10-26 22:30 ` [RFC PATCH 0/8] arm,x86,fs/resctrl: Support asymmetric L2 cache allocation Reinette Chatre
2026-10-27 17:41 ` Luck, Tony
2026-10-27 18:30 ` Reinette Chatre
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®