[PATCH v12 12/25] arm,x86,fs/resctrl: Allocate maximum needed rmid_ptrs[]

From: Tony Luck

Date: Wed Sep 16 2026 - 19:15:27 EST


File system code allocates the rmid_ptrs[] array once during
initialization. The number of entries needed in this array is currently
constant. When changes are made to allow Application Energy Telemetry
(AET) to run with the pmt_telemetry driver as a module, then number of
entries needed may change from one mount to the next.

Allocate rmid_ptrs[] with enough entries for any future mount.

Signed-off-by: Tony Luck <tony.luck@xxxxxxxxx>
---
v12:
New patch. Split out from old patch 12.
New global pqr_assoc_num_rmid to avoid repeat CPUID calls.
---
include/linux/resctrl.h | 1 +
arch/x86/kernel/cpu/resctrl/core.c | 27 +++++++++++++++++++++++++++
drivers/resctrl/mpam_resctrl.c | 9 +++++++++
fs/resctrl/monitor.c | 2 +-
4 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index fbf737e884db..5535bde7b925 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -447,6 +447,7 @@ static inline u32 resctrl_get_default_ctrl(struct rdt_resource *r)
/* The number of closid supported by this resource regardless of CDP */
u32 resctrl_arch_get_num_closid(struct rdt_resource *r);
u32 resctrl_arch_system_num_rmid_idx(void);
+u32 resctrl_arch_system_max_rmid_idx(void);
int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid);

/**
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 2e3b9c16cbda..a9109f2bc43e 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -45,6 +45,9 @@ static DEFINE_MUTEX(domain_list_lock);
*/
DEFINE_PER_CPU(struct resctrl_pqr_state, pqr_state);

+/* Number of RMIDS values that can be written to IA32_PQR_ASSOC.RMID */
+static u32 pqr_assoc_num_rmid;
+
static void mba_wrmsr_intel(struct msr_param *m);
static void cat_wrmsr(struct msr_param *m);
static void mba_wrmsr_amd(struct msr_param *m);
@@ -124,6 +127,28 @@ u32 resctrl_arch_system_num_rmid_idx(void)
return num_rmids == U32_MAX ? 0 : num_rmids;
}

+/**
+ * resctrl_arch_system_max_rmid_idx - Largest possible number of RMIDs
+ *
+ * Return: Maximum possible number of RMIDs used for boot time allocations.
+ */
+u32 resctrl_arch_system_max_rmid_idx(void)
+{
+ struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+ u32 num_rmid = pqr_assoc_num_rmid;
+
+ /*
+ * If the system is capable of L3 monitoring the maximum RMID value may
+ * be lower than the system maximum. Either because the L3 monitoring
+ * feature supports fewer RMIDs, or because SNC (Sub-NUMA Cluster)
+ * is enabled and divides RMIDs per cluster.
+ */
+ if (r->mon_capable)
+ num_rmid = r->mon.num_rmid;
+
+ return num_rmid;
+}
+
struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l)
{
if (l >= RDT_NUM_RESOURCES)
@@ -967,6 +992,8 @@ static __init bool get_rdt_mon_resources(void)
if (!cpu_feature_enabled(X86_FEATURE_CQM))
return false;

+ pqr_assoc_num_rmid = cpuid_ebx(0xf) + 1;
+
/* Any of the L3 monitoring features? */
if (!cpu_feature_enabled(X86_FEATURE_CQM_LLC))
return false;
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index 0db62dd2a71c..0ffa25199f74 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -252,6 +252,15 @@ u32 resctrl_arch_system_num_rmid_idx(void)
return (mpam_pmg_max + 1) * (mpam_partid_max + 1);
}

+/*
+ * File system calls this for one-time allocation of structures
+ * during initialization. Return the largest possible value.
+ */
+u32 resctrl_arch_system_max_rmid_idx(void)
+{
+ return resctrl_arch_system_num_rmid_idx();
+}
+
u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid)
{
return closid * (mpam_pmg_max + 1) + rmid;
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index 2a28fe04284b..e8775e08aa18 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -978,7 +978,7 @@ int setup_rmid_lru_list(void)
if (rmid_ptrs)
return 0;

- idx_limit = resctrl_arch_system_num_rmid_idx();
+ idx_limit = resctrl_arch_system_max_rmid_idx();
rmid_ptrs = kzalloc_objs(struct rmid_entry, idx_limit);
if (!rmid_ptrs)
return -ENOMEM;
--
2.55.0