[PATCH v9 7/9] arm_mpam: Map resctrl RMIDs onto the request PARTIDs
From: Jinjie Ruan
Date: Mon Oct 12 2026 - 04:30:46 EST
From: Zeng Heng <zengheng4@xxxxxxxxxx>
The current resctrl RMID allocation assumes a rigid 2D encoding, which
limits the total number of monitoring groups to the hardware CLOSID count.
To decouple control and monitoring, redefine resctrl_arch_rmid_idx_encode()
as a flat, global monitoring index. When extra request PARTIDs are active,
the task's hardware PARTID and PMG are derived directly from this global
RMID via modulo division. Otherwise, legacy 1:1 behavior is preserved.
CDP halves the CLOSID range and uses two PARTIDs per control group,
which conflicts with the grouping, so it is refused while the extra
PARTIDs are in use.
No functional change for now as resctrl_using_extra_partids
remains false.
Cc: James Morse <james.morse@xxxxxxx>
Cc: Ben Horgan <ben.horgan@xxxxxxx>
Cc: Reinette Chatre <reinette.chatre@xxxxxxxxx>
Cc: Fenghua Yu <fenghuay@xxxxxxxxxx>
Suggested-by: James Morse <james.morse@xxxxxxx>
Signed-off-by: Zeng Heng <zengheng4@xxxxxxxxxx>
Signed-off-by: Jinjie Ruan <ruanjinjie@xxxxxxxxxx>
---
drivers/resctrl/mpam_resctrl.c | 63 +++++++++++++++++++++++++++++++---
1 file changed, 59 insertions(+), 4 deletions(-)
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index 0edededdf7a5..8479fdd7f713 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -62,6 +62,9 @@ static DEFINE_MUTEX(domain_list_lock);
*/
static bool cdp_enabled;
+/* If resctrl is leveraging extra request PARTIDs for monitoring. */
+static bool resctrl_using_extra_partids;
+
/*
* We use cacheinfo to discover the size of the caches and their id. cacheinfo
* populates this from a device_initcall(). mpam_resctrl_setup() must wait.
@@ -205,6 +208,16 @@ int resctrl_arch_set_cdp_enabled(enum resctrl_res_level rid, bool enable)
if (enable)
pr_warn("CDP is an expert feature and may cause MPAM to malfunction.\n");
+ /*
+ * CDP halves the CLOSID range and uses two PARTIDs per control group.
+ * That conflicts with the PARTID grouping used to provide the extra
+ * monitoring groups.
+ */
+ if (enable && resctrl_using_extra_partids) {
+ pr_warn("CDP is not supported with PARTID narrowing\n");
+ return -EOPNOTSUPP;
+ }
+
/*
* resctrl_arch_set_cdp_enabled() is only called with enable set to
* false on error and unmount.
@@ -274,8 +287,28 @@ u32 resctrl_arch_system_num_rmid_idx(void)
return (mpam_pmg_max + 1) * (mpam_partid_max + 1);
}
+/* The request PARTID and PMG a resctrl RMID maps onto. */
+static u16 resctrl_rmid_to_partid(u32 rmid)
+{
+ return rmid / (mpam_pmg_max + 1);
+}
+
+static u8 resctrl_rmid_to_pmg(u32 rmid)
+{
+ return rmid % (mpam_pmg_max + 1);
+}
+
+/* The control group that owns a request PARTID. */
+static u16 resctrl_partid_to_closid(u16 partid)
+{
+ return mpam_partid_to_intpartid(partid);
+}
+
u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid)
{
+ if (resctrl_using_extra_partids)
+ return rmid;
+
return closid * (mpam_pmg_max + 1) + rmid;
}
@@ -287,6 +320,14 @@ bool resctrl_arch_rmid_idx_match(u32 closid, u32 rmid_closid)
void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid)
{
+ if (resctrl_using_extra_partids) {
+ if (rmid)
+ *rmid = idx;
+ if (closid)
+ *closid = resctrl_partid_to_closid(resctrl_rmid_to_partid(idx));
+ return;
+ }
+
*closid = idx / (mpam_pmg_max + 1);
*rmid = idx % (mpam_pmg_max + 1);
}
@@ -303,11 +344,23 @@ static void resctrl_closid_rmid_to_partid_pmg(u32 closid, u32 rmid,
u8 *pmg_d, u8 *pmg_i)
{
WARN_ON_ONCE(closid > U16_MAX);
- WARN_ON_ONCE(rmid > U8_MAX);
+ WARN_ON_ONCE(!resctrl_using_extra_partids && rmid > U8_MAX);
if (!cdp_enabled) {
- *partid_d = *partid_i = closid;
- *pmg_d = *pmg_i = rmid;
+ u16 partid;
+ u8 pmg;
+
+ if (resctrl_using_extra_partids) {
+ partid = resctrl_rmid_to_partid(rmid);
+ WARN_ON_ONCE(partid > U16_MAX);
+ pmg = resctrl_rmid_to_pmg(rmid);
+ } else {
+ partid = closid;
+ pmg = rmid;
+ }
+
+ *partid_d = *partid_i = partid;
+ *pmg_d = *pmg_i = pmg;
} else {
/*
* When CDP is enabled, resctrl halves the closid range and we
@@ -356,7 +409,9 @@ void resctrl_arch_set_closid_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
/* Does the request PARTID belong to this control group? */
static bool resctrl_partid_in_closid(u16 partid, u32 closid)
{
- if (cdp_enabled)
+ if (resctrl_using_extra_partids)
+ partid = resctrl_partid_to_closid(partid);
+ else if (cdp_enabled)
partid >>= 1;
return partid == closid;
--
2.34.1