[RFC PATCH 13/31] x86/resctrl: Add per-control and per-resource flags

From: Chen Yu

Date: Sun Aug 02 2026 - 12:16:48 EST


Introduce a 'flags' field in both struct rdt_resource and struct
resctrl_ctrl to expose control properties via the resource_schemata
info directory. Define two flags:

RESCTRL_CTRL_FLAG_LINEAR - scalar control uses linear delay
RESCTRL_CTRL_FLAG_SPARSE_BITMASKS - bitmap control supports sparse masks

The resource-level flags (rdt_resource::flags) serve as the source of
truth for properties shared by all controls of a resource. Each control
duplicates these flags into its own resctrl_ctrl::flags field for
per-control visibility in the info/<resource>/resource_schemata/<ctrl>/
directory.

The existing fields (bw_delay_linear, arch_has_sparse_bitmasks) are
preserved for backward compatibility with the legacy info directory
files (delay_linear, sparse_masks).

Signed-off-by: Chen Yu <yu.c.chen@xxxxxxxxx>
---
arch/x86/kernel/cpu/resctrl/core.c | 12 ++++++++++++
drivers/resctrl/mpam_resctrl.c | 4 ++++
include/linux/resctrl.h | 11 +++++++++++
3 files changed, 27 insertions(+)

diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 896906f86da2..f0e30f22576c 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -171,6 +171,8 @@ static inline void cache_alloc_hsw_probe(void)
hw_ctrl->r_ctrl.bitmap.shareable_bits = 0xc0000;
hw_ctrl->r_ctrl.bitmap.min_cbm_bits = 2;
hw_ctrl->r_ctrl.bitmap.arch_has_sparse_bitmasks = false;
+ r->flags = 0;
+ hw_ctrl->r_ctrl.flags = 0;
list_add(&hw_ctrl->r_ctrl.entry, &r->controls);

hw_res->num_closid = 4;
@@ -209,6 +211,8 @@ static __init bool __get_mem_config_intel(struct rdt_resource *r)
hw_ctrl->r_ctrl.scalar.bw_gran = MAX_MBA_BW - max_delay;

r->bw_delay_linear = true;
+ r->flags = RESCTRL_CTRL_FLAG_LINEAR;
+ hw_ctrl->r_ctrl.flags = RESCTRL_CTRL_FLAG_LINEAR;
if (boot_cpu_has(X86_FEATURE_PER_THREAD_MBA))
r->bw_throttle_mode = THREAD_THROTTLE_PER_THREAD;
else
@@ -261,6 +265,8 @@ static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r)

/* AMD does not use delay */
r->bw_delay_linear = false;
+ r->flags = 0;
+ hw_ctrl->r_ctrl.flags = 0;

/*
* AMD does not use memory delay throttle model to control
@@ -313,10 +319,16 @@ static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r)
hw_ctrl->r_ctrl.bitmap.shareable_bits = ebx & default_ctrl;
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
hw_ctrl->r_ctrl.bitmap.arch_has_sparse_bitmasks = ecx.split.noncont;
+ if (ecx.split.noncont) {
+ r->flags = RESCTRL_CTRL_FLAG_SPARSE_BITMASKS;
+ hw_ctrl->r_ctrl.flags = RESCTRL_CTRL_FLAG_SPARSE_BITMASKS;
+ }
hw_ctrl->r_ctrl.bitmap.min_cbm_bits = 1;
} else if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
hw_ctrl->r_ctrl.bitmap.arch_has_sparse_bitmasks = true;
+ r->flags = RESCTRL_CTRL_FLAG_SPARSE_BITMASKS;
+ hw_ctrl->r_ctrl.flags = RESCTRL_CTRL_FLAG_SPARSE_BITMASKS;
hw_ctrl->r_ctrl.bitmap.min_cbm_bits = 0;
} else {
return;
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index be3bd3d38ef1..d675f1c948c4 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -1010,6 +1010,8 @@ static int mpam_resctrl_control_init(struct mpam_resctrl_res *res)
INIT_LIST_HEAD_RCU(&mpam_ctrl->r_ctrl.domains);

mpam_ctrl->r_ctrl.bitmap.arch_has_sparse_bitmasks = true;
+ r->flags = RESCTRL_CTRL_FLAG_SPARSE_BITMASKS;
+ mpam_ctrl->r_ctrl.flags = RESCTRL_CTRL_FLAG_SPARSE_BITMASKS;

mpam_ctrl->r_ctrl.bitmap.cbm_len = class->props.cpbm_wd;
/* mpam_devices will reject empty bitmaps */
@@ -1042,6 +1044,8 @@ static int mpam_resctrl_control_init(struct mpam_resctrl_res *res)
INIT_LIST_HEAD_RCU(&mpam_ctrl->r_ctrl.domains);

r->bw_delay_linear = true;
+ r->flags = RESCTRL_CTRL_FLAG_LINEAR;
+ mpam_ctrl->r_ctrl.flags = RESCTRL_CTRL_FLAG_LINEAR;
r->bw_throttle_mode = THREAD_THROTTLE_UNDEFINED;
mpam_ctrl->r_ctrl.scalar.min_bw = get_mba_min(cprops);
mpam_ctrl->r_ctrl.scalar.max_bw = MAX_MBA_BW;
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index c23c2f8bf2d1..b2af0664cce7 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -356,6 +356,10 @@ enum resctrl_ctrl_name {
RESCTRL_CTRL_NAME_LAST = RESCTRL_CTRL_NAME_MAX
};

+/* Flags for rdt_resource::flags and resctrl_ctrl::flags */
+#define RESCTRL_CTRL_FLAG_LINEAR BIT(0)
+#define RESCTRL_CTRL_FLAG_SPARSE_BITMASKS BIT(1)
+
/**
* struct resctrl_ctrl - A resource control
* @entry: List entry of rdt_resource::controls
@@ -369,6 +373,9 @@ enum resctrl_ctrl_name {
* Specifically, "rdt_resource_final::name"_"resctrl_ctrl::name".
* For example, with resource name "MB" and control name "MAX" the
* schema entry will be "MB_MAX".
+ * @flags: Optional flags describing properties of the control.
+ * Duplicated from resource-level properties for per-control
+ * visibility via the resource_schemata info directory.
* @bitmap: Bitmap control properties.
* @scalar: Scalar control properties.
*/
@@ -378,6 +385,7 @@ struct resctrl_ctrl {
struct list_head domains;
enum resctrl_ctrl_type type;
enum resctrl_ctrl_name name;
+ unsigned long flags;
union {
struct resctrl_ctrl_bitmap bitmap;
struct resctrl_ctrl_scalar scalar;
@@ -399,6 +407,8 @@ struct resctrl_ctrl {
* different memory bandwidths
* @cache_io_alloc_capable:True if portion of the cache can be configured
* for I/O traffic.
+ * @flags: Resource-level flags (RESCTRL_CTRL_FLAG_*). Duplicated
+ * into each control's flags field for per-control visibility.
* @controls: List of controls of an alloc_capable resource
*/
struct rdt_resource {
@@ -413,6 +423,7 @@ struct rdt_resource {
bool bw_delay_linear;
enum membw_throttle_mode bw_throttle_mode;
bool cache_io_alloc_capable;
+ unsigned long flags;
struct list_head controls;
};

--
2.43.0