public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: Zeng Heng <zengheng4@huawei.com>
To: <ben.horgan@arm.com>, <Dave.Martin@arm.com>,
	<james.morse@arm.com>, <tan.shaopeng@jp.fujitsu.com>,
	<reinette.chatre@intel.com>, <fenghuay@nvidia.com>,
	<tglx@kernel.org>, <will@kernel.org>, <hpa@zytor.com>,
	<bp@alien8.de>, <babu.moger@amd.com>,
	<dave.hansen@linux.intel.com>, <mingo@redhat.com>,
	<tony.luck@intel.com>, <gshan@redhat.com>,
	<catalin.marinas@arm.com>
Cc: <linux-arm-kernel@lists.infradead.org>, <x86@kernel.org>,
	<linux-kernel@vger.kernel.org>, <wangkefeng.wang@huawei.com>
Subject: [PATCH v8 next 04/10] arm_mpam: Refactor rmid to reqPARTID/PMG mapping
Date: Mon, 13 Apr 2026 16:53:59 +0800	[thread overview]
Message-ID: <20260413085405.1166412-5-zengheng4@huawei.com> (raw)
In-Reply-To: <20260413085405.1166412-1-zengheng4@huawei.com>

The Narrow-PARTID feature allows the MPAM driver to statically or
dynamically allocate request PARTIDs (reqPARTIDs) to internal
PARTIDs (intPARTIDs). This enables expanding the number of monitoring
groups beyond the hardware PMG limit.

For systems with mixed MSCs (Memory System Components), MSCs that do
not support Narrow-PARTID use PARTIDs exceeding the minimum number of
intPARTIDs as reqPARTIDs to expand monitoring groups.

Expand RMID to include reqPARTID information:

  RMID = reqPARTID * NUM_PMG + PMG

To maintain compatibility with the existing resctrl layer, reqPARTIDs
are allocated statically with a linear mapping to intPARTIDs via
req2intpartid().

Mapping relationships (n = intPARTID count, m = reqPARTIDs per intPARTID):

P - Partition group
M - Monitoring group

Group  closid rmid.reqPARTID  MSCs w/ Narrow-PARTID  MSCs w/o Narrow-PARTID
P1     0                      intPARTID_1            PARTID_1
M1_1   0      0               ├── reqPARTID_1_1      ├── PARTID_1
M1_2   0      0+n             ├── reqPARTID_1_2      ├── PARTID_1_2
M1_3   0      0+n*2           ├── reqPARTID_1_3      ├── PARTID_1_3
...                           ├── ...                ├── ...
M1_m   0      0+n*(m-1)       └── reqPARTID_1_m      └── PARTID_1_m

P2     1                      intPARTID_2            PARTID_2
M2_1   1      1               ├── reqPARTID_2_1      ├── PARTID_2
M2_2   1      1+n             ├── reqPARTID_2_2      ├── PARTID_2_2
M2_3   1      1+n*2           ├── reqPARTID_2_3      ├── PARTID_2_3
...                           ├── ...                ├── ...
M2_m   1      1+n*(m-1)       └── reqPARTID_2_m      └── PARTID_2_m

Pn     n-1                    intPARTID_n            PARTID_n
Mn_1   n-1    n-1             ├── reqPARTID_n_1      ├── PARTID_n
Mn_2   n-1    n-1+n           ├── reqPARTID_n_2      ├── PARTID_n_2
Mn_3   n-1    n-1+n*2         ├── reqPARTID_n_3      ├── PARTID_n_3
...                           ├── ...                ├── ...
Mn_m   n-1    n*m-1           └── reqPARTID_n_m      └── PARTID_n_m

Refactor the glue layer between resctrl abstractions (rmid) and MPAM
hardware registers (reqPARTID/PMG) to support Narrow-PARTID. The resctrl
layer uses rmid2reqpartid() and rmid2pmg() to extract components from
rmid. The closid-to-intPARTID translation remains unchanged via
resctrl_get_config_index().

Since Narrow-PARTID is a monitoring enhancement, reqPARTID is only
used in monitoring paths while configuration paths maintain the original
semantics of closid.

Signed-off-by: Zeng Heng <zengheng4@huawei.com>
---
 arch/arm64/include/asm/mpam.h  |  12 +++-
 drivers/resctrl/mpam_resctrl.c | 101 +++++++++++++++++++++++----------
 2 files changed, 82 insertions(+), 31 deletions(-)

diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h
index 70d396e7b6da..40d60b0ab0fd 100644
--- a/arch/arm64/include/asm/mpam.h
+++ b/arch/arm64/include/asm/mpam.h
@@ -63,6 +63,15 @@ static inline void mpam_set_task_partid_pmg(struct task_struct *tsk,
 	WRITE_ONCE(task_thread_info(tsk)->mpam_partid_pmg, regval);
 }
 
+u16 req2intpartid(u16 reqpartid);
+
+static inline u16 mpam_get_regval_partid(u64 regval)
+{
+	u16 reqpartid = (regval & MPAMSM_EL1_PARTID_D_MASK) >> MPAMSM_EL1_PARTID_D_SHIFT;
+
+	return req2intpartid(reqpartid);
+}
+
 static inline void mpam_thread_switch(struct task_struct *tsk)
 {
 	u64 oldregval;
@@ -72,7 +81,8 @@ static inline void mpam_thread_switch(struct task_struct *tsk)
 	if (!static_branch_likely(&mpam_enabled))
 		return;
 
-	if (regval == READ_ONCE(arm64_mpam_global_default))
+	if (regval == READ_ONCE(arm64_mpam_global_default) ||
+	   !mpam_get_regval_partid(regval))
 		regval = READ_ONCE(per_cpu(arm64_mpam_default, cpu));
 
 	oldregval = READ_ONCE(per_cpu(arm64_mpam_current, cpu));
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index 56859f354efa..9d0a7a4dffd1 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -303,15 +303,60 @@ u32 resctrl_arch_system_num_rmid_idx(void)
 	return (mpam_pmg_max + 1) * get_num_reqpartid();
 }
 
+static u16 rmid2reqpartid(u32 rmid)
+{
+	rmid /= (mpam_pmg_max + 1);
+
+	if (cdp_enabled)
+		return resctrl_get_config_index(rmid, CDP_DATA);
+
+	return resctrl_get_config_index(rmid, CDP_NONE);
+}
+
+static u8 rmid2pmg(u32 rmid)
+{
+	return rmid % (mpam_pmg_max + 1);
+}
+
+u16 req2intpartid(u16 reqpartid)
+{
+	return reqpartid % (mpam_intpartid_max + 1);
+}
+
+/*
+ * To avoid the reuse of rmid across multiple control groups, check
+ * the incoming closid to prevent rmid from being reallocated by
+ * resctrl_find_free_rmid().
+ *
+ * If the closid and rmid do not match upon inspection, immediately
+ * returns an invalid rmid. A valid rmid must not exceed 24 bits.
+ */
 u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid)
 {
-	return closid * (mpam_pmg_max + 1) + rmid;
+	u32 reqpartid = rmid2reqpartid(rmid);
+	u32 intpartid = req2intpartid(reqpartid);
+
+	if (cdp_enabled)
+		intpartid >>= 1;
+
+	if (closid != intpartid)
+		return U32_MAX;
+
+	return rmid;
 }
 
 void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid)
 {
-	*closid = idx / (mpam_pmg_max + 1);
-	*rmid = idx % (mpam_pmg_max + 1);
+	u32 reqpartid = rmid2reqpartid(idx);
+	u32 intpartid = req2intpartid(reqpartid);
+
+	if (rmid)
+		*rmid = idx;
+	if (closid) {
+		if (cdp_enabled)
+			intpartid >>= 1;
+		*closid = intpartid;
+	}
 }
 
 void resctrl_arch_sched_in(struct task_struct *tsk)
@@ -323,21 +368,17 @@ void resctrl_arch_sched_in(struct task_struct *tsk)
 
 void resctrl_arch_set_cpu_default_closid_rmid(int cpu, u32 closid, u32 rmid)
 {
-	WARN_ON_ONCE(closid > U16_MAX);
-	WARN_ON_ONCE(rmid > U8_MAX);
+	u32 reqpartid = rmid2reqpartid(rmid);
+	u8 pmg = rmid2pmg(rmid);
 
-	if (!cdp_enabled) {
-		mpam_set_cpu_defaults(cpu, closid, closid, rmid, rmid);
-	} else {
+	if (!cdp_enabled)
+		mpam_set_cpu_defaults(cpu, reqpartid, reqpartid, pmg, pmg);
+	else
 		/*
 		 * When CDP is enabled, resctrl halves the closid range and we
 		 * use odd/even partid for one closid.
 		 */
-		u32 partid_d = resctrl_get_config_index(closid, CDP_DATA);
-		u32 partid_i = resctrl_get_config_index(closid, CDP_CODE);
-
-		mpam_set_cpu_defaults(cpu, partid_d, partid_i, rmid, rmid);
-	}
+		mpam_set_cpu_defaults(cpu, reqpartid, reqpartid + 1, pmg, pmg);
 }
 
 void resctrl_arch_sync_cpu_closid_rmid(void *info)
@@ -356,17 +397,16 @@ void resctrl_arch_sync_cpu_closid_rmid(void *info)
 
 void resctrl_arch_set_closid_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
 {
-	WARN_ON_ONCE(closid > U16_MAX);
-	WARN_ON_ONCE(rmid > U8_MAX);
+	u32 reqpartid = rmid2reqpartid(rmid);
+	u8 pmg = rmid2pmg(rmid);
 
-	if (!cdp_enabled) {
-		mpam_set_task_partid_pmg(tsk, closid, closid, rmid, rmid);
-	} else {
-		u32 partid_d = resctrl_get_config_index(closid, CDP_DATA);
-		u32 partid_i = resctrl_get_config_index(closid, CDP_CODE);
+	WARN_ON_ONCE(reqpartid > U16_MAX);
+	WARN_ON_ONCE(pmg > U8_MAX);
 
-		mpam_set_task_partid_pmg(tsk, partid_d, partid_i, rmid, rmid);
-	}
+	if (!cdp_enabled)
+		mpam_set_task_partid_pmg(tsk, reqpartid, reqpartid, pmg, pmg);
+	else
+		mpam_set_task_partid_pmg(tsk, reqpartid, reqpartid + 1, pmg, pmg);
 }
 
 bool resctrl_arch_match_closid(struct task_struct *tsk, u32 closid)
@@ -374,6 +414,8 @@ bool resctrl_arch_match_closid(struct task_struct *tsk, u32 closid)
 	u64 regval = mpam_get_regval(tsk);
 	u32 tsk_closid = FIELD_GET(MPAM0_EL1_PARTID_D, regval);
 
+	tsk_closid = req2intpartid(tsk_closid);
+
 	if (cdp_enabled)
 		tsk_closid >>= 1;
 
@@ -384,13 +426,11 @@ bool resctrl_arch_match_closid(struct task_struct *tsk, u32 closid)
 bool resctrl_arch_match_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
 {
 	u64 regval = mpam_get_regval(tsk);
-	u32 tsk_closid = FIELD_GET(MPAM0_EL1_PARTID_D, regval);
-	u32 tsk_rmid = FIELD_GET(MPAM0_EL1_PMG_D, regval);
-
-	if (cdp_enabled)
-		tsk_closid >>= 1;
+	u32 tsk_partid = FIELD_GET(MPAM0_EL1_PARTID_D, regval);
+	u32 tsk_pmg = FIELD_GET(MPAM0_EL1_PMG_D, regval);
 
-	return (tsk_closid == closid) && (tsk_rmid == rmid);
+	return (tsk_partid == rmid2reqpartid(rmid)) &&
+	       (tsk_pmg == rmid2pmg(rmid));
 }
 
 struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l)
@@ -478,6 +518,7 @@ static int __read_mon(struct mpam_resctrl_mon *mon, struct mpam_component *mon_c
 		      enum resctrl_conf_type cdp_type, u32 closid, u32 rmid, u64 *val)
 {
 	struct mon_cfg cfg;
+	u32 reqpartid = rmid2reqpartid(rmid);
 
 	if (!mpam_is_enabled())
 		return -EINVAL;
@@ -493,8 +534,8 @@ static int __read_mon(struct mpam_resctrl_mon *mon, struct mpam_component *mon_c
 	cfg = (struct mon_cfg) {
 		.mon = mon_idx,
 		.match_pmg = true,
-		.partid = closid,
-		.pmg = rmid,
+		.partid = (cdp_type == CDP_CODE) ? reqpartid + 1 : reqpartid,
+		.pmg = rmid2pmg(rmid),
 	};
 
 	return mpam_msmon_read(mon_comp, &cfg, mon_type, val);
-- 
2.25.1



  parent reply	other threads:[~2026-04-13  8:55 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-13  8:53 [PATCH v8 next 00/10] arm_mpam: Introduce Narrow-PARTID feature Zeng Heng
2026-04-13  8:53 ` [PATCH v8 next 01/10] fs/resctrl: Fix MPAM Partid parsing errors by preserving CDP state during umount Zeng Heng
2026-04-13  8:53 ` [PATCH v8 next 02/10] arm_mpam: Add intPARTID and reqPARTID support for Narrow-PARTID feature Zeng Heng
2026-04-13  8:53 ` [PATCH v8 next 03/10] arm_mpam: Disable reqPARTID expansion when Narrow-PARTID is unavailable Zeng Heng
2026-04-13  8:53 ` Zeng Heng [this message]
2026-04-13  8:54 ` [PATCH v8 next 05/10] arm_mpam: Propagate control group config to sub-monitoring groups Zeng Heng
2026-04-13  8:54 ` [PATCH v8 next 06/10] arm_mpam: Add boot parameter to limit mpam_intpartid_max Zeng Heng
2026-04-13  8:54 ` [PATCH v8 next 07/10] fs/resctrl: Add rmid_entry state helpers Zeng Heng
2026-04-13  8:54 ` [PATCH v8 next 08/10] arm_mpam: Implement dynamic reqPARTID allocation for monitoring groups Zeng Heng
2026-04-13  8:54 ` [PATCH v8 next 09/10] fs/resctrl: Wire up rmid expansion and reclaim functions Zeng Heng
2026-04-13  8:54 ` [PATCH v8 next 10/10] arm_mpam: Add mpam_sync_config() for dynamic rmid expansion Zeng Heng
2026-04-16  6:29 ` [PATCH v8 next 00/10] arm_mpam: Introduce Narrow-PARTID feature Shaopeng Tan (Fujitsu)
2026-04-20  7:31 ` Zeng Heng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260413085405.1166412-5-zengheng4@huawei.com \
    --to=zengheng4@huawei.com \
    --cc=Dave.Martin@arm.com \
    --cc=babu.moger@amd.com \
    --cc=ben.horgan@arm.com \
    --cc=bp@alien8.de \
    --cc=catalin.marinas@arm.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=fenghuay@nvidia.com \
    --cc=gshan@redhat.com \
    --cc=hpa@zytor.com \
    --cc=james.morse@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=reinette.chatre@intel.com \
    --cc=tan.shaopeng@jp.fujitsu.com \
    --cc=tglx@kernel.org \
    --cc=tony.luck@intel.com \
    --cc=wangkefeng.wang@huawei.com \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox