[RFC PATCH v2 17/19] arm_mpam: resctrl: Allow monitoring on resources other than the L3

Jinjie Ruan ruanjinjie at huawei.com
Thu Oct 29 05:36:09 PDT 2026


The MPAM driver assumes only the L3 monitors. resctrl_arch_mon_capable()
looks at the L3 only, a CPU's monitor-only domain is found with the L3
cache-id, and mpam_resctrl_monitor_init() always names the resource L3.

Check every resource for monitoring, find a monitor domain by the id its
component reports, and set the name and scope from the resource.

No functional change as only the L3 has monitors so far.

Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
---
 drivers/resctrl/mpam_resctrl.c | 85 +++++++++++++++++-----------------
 1 file changed, 42 insertions(+), 43 deletions(-)

diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index b5416f589698..b9487f3c648d 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -99,11 +99,12 @@ bool resctrl_arch_alloc_capable(void)
 
 bool resctrl_arch_mon_capable(void)
 {
-	struct mpam_resctrl_res *res = &mpam_resctrl_controls[RDT_RESOURCE_L3];
-	struct rdt_resource *l3 = &res->resctrl_res;
+	struct rdt_resource *r;
+
+	for_each_mon_capable_rdt_resource(r)
+		return true;
 
-	/* All monitors are presented as being on the L3 cache */
-	return l3->mon_capable;
+	return false;
 }
 
 bool resctrl_arch_is_evt_configurable(enum resctrl_event_id evt)
@@ -1332,35 +1333,39 @@ static int mpam_resctrl_monitor_init(struct rdt_resource *r,
 	struct mpam_resctrl_res *res = container_of(r, struct mpam_resctrl_res,
 						    resctrl_res);
 	struct mpam_resctrl_mon *mon = mpam_resctrl_mon(r, type);
+	unsigned int level;
 
 	lockdep_assert_cpus_held();
 
+	/* Called once per event. The name is needed on monitor only platforms. */
+	if (r->rid == RDT_RESOURCE_L2) {
+		level = 2;
+		r->name = "L2";
+		r->mon_scope = RESCTRL_L2_CACHE;
+	} else {
+		level = 3;
+		r->name = "L3";
+		r->mon_scope = RESCTRL_L3_CACHE;
+	}
+
 	/*
-	 * There also needs to be an L3 cache present.
+	 * There also needs to be a cache at this level present.
 	 * The check just requires any online CPU and it can't go offline as we
 	 * hold the cpu lock.
 	 */
-	if (get_cpu_cacheinfo_id(raw_smp_processor_id(), 3) == -1)
+	if (get_cpu_cacheinfo_id(raw_smp_processor_id(), level) == -1)
 		return 0;
 
 	/*
-	 * If there are no MPAM resources on L3, force it into existence.
-	 * topology_matches_l3() already ensures this looks like the L3.
-	 * The domain-ids will be fixed up by mpam_resctrl_domain_hdr_init().
+	 * If there are no MPAM resources on this cache level, force it into
+	 * existence. The domain-ids will be fixed up by
+	 * mpam_resctrl_domain_hdr_init().
 	 */
 	if (!res->class) {
-		pr_warn_once("Faking L3 MSC to enable counters.\n");
+		pr_warn_once("Faking L%u MSC to enable counters.\n", level);
 		res->class = mon->class;
 	}
 
-	/*
-	 * Called multiple times!, once per event type that has a
-	 * monitoring class.
-	 * Setting name is necessary on monitor only platforms.
-	 */
-	r->name = "L3";
-	r->mon_scope = RESCTRL_L3_CACHE;
-
 	/*
 	 * num-rmid is the upper bound for the number of monitoring groups that
 	 * can exist simultaneously, including the default monitoring group for
@@ -1638,9 +1643,9 @@ static struct mpam_component *find_component(struct mpam_class *class, int cpu)
 }
 
 /*
- * Find the domain ID for @cpu from the monitoring components of @r. Also
- * fill @mon_comp, if not NULL, with the component that covers @cpu for each
- * event. A negative ID means no component covers this CPU.
+ * Fill @mon_comp, if not NULL, with the component that covers @cpu for each
+ * of the resource's events, and return the domain ID of the first one found.
+ * A negative ID means no component covers this CPU.
  */
 static int mpam_resctrl_domain_id(int cpu, struct rdt_resource *r,
 				  struct mpam_component **mon_comp)
@@ -1656,7 +1661,7 @@ static int mpam_resctrl_domain_id(int cpu, struct rdt_resource *r,
 		int comp_id;
 
 		if (!mon->class)
-			continue;	// dummy resource
+			continue;
 
 		comp = find_component(mon->class, cpu);
 		if (mon_comp)
@@ -1725,9 +1730,8 @@ mpam_resctrl_alloc_domain(unsigned int cpu, struct mpam_resctrl_res *res)
 		int id;
 
 		/*
-		 * Even if the monitor domain is backed by a different
-		 * component, the L3 component IDs need to be used... only
-		 * there may be no ctrl_comp for the L3.
+		 * The monitor domain ID comes from the monitor components, as
+		 * there may be no ctrl_comp for this resource.
 		 * Search each event's class list for a component with
 		 * overlapping CPUs and set up the dom->mon_comp array.
 		 */
@@ -1764,28 +1768,26 @@ mpam_resctrl_alloc_domain(unsigned int cpu, struct mpam_resctrl_res *res)
 }
 
 /*
- * We know all the monitors are associated with the L3, even if there are no
- * controls and therefore no control component. Find the cache-id for the CPU
- * and use that to search for existing resctrl domains.
- * This relies on mpam_resctrl_pick_domain_id() using the L3 cache-id
- * for anything that is not a cache.
+ * There may be no control component to search, for example on monitor only
+ * platforms. Find the domain-id the monitors' component would report for
+ * this CPU and use that to search the resource's monitor domains.
+ * This relies on mpam_resctrl_pick_domain_id() giving the same id for every
+ * CPU that shares the component.
  */
-static struct mpam_resctrl_dom *mpam_resctrl_get_mon_domain_from_cpu(int cpu)
+static struct mpam_resctrl_dom *
+mpam_resctrl_get_mon_domain_from_cpu(int cpu, struct rdt_resource *r)
 {
-	int cache_id;
 	struct mpam_resctrl_dom *dom;
-	struct mpam_resctrl_res *l3 = &mpam_resctrl_controls[RDT_RESOURCE_L3];
+	int id;
 
 	lockdep_assert_cpus_held();
 
-	if (!l3->class)
-		return NULL;
-	cache_id = get_cpu_cacheinfo_id(cpu, 3);
-	if (cache_id < 0)
+	id = mpam_resctrl_domain_id(cpu, r, NULL);
+	if (id < 0)
 		return NULL;
 
-	list_for_each_entry_rcu(dom, &l3->resctrl_res.mon_domains, resctrl_mon_dom.hdr.list) {
-		if (dom->resctrl_mon_dom.hdr.id == cache_id)
+	list_for_each_entry_rcu(dom, &r->mon_domains, resctrl_mon_dom.hdr.list) {
+		if (dom->resctrl_mon_dom.hdr.id == id)
 			return dom;
 	}
 
@@ -1805,11 +1807,8 @@ mpam_resctrl_get_domain_from_cpu(int cpu, struct mpam_resctrl_res *res)
 			return dom;
 	}
 
-	if (r->rid != RDT_RESOURCE_L3)
-		return NULL;
-
 	/* Search the mon domain list too - needed on monitor only platforms. */
-	return mpam_resctrl_get_mon_domain_from_cpu(cpu);
+	return mpam_resctrl_get_mon_domain_from_cpu(cpu, r);
 }
 
 int mpam_resctrl_online_cpu(unsigned int cpu)
-- 
2.34.1




More information about the linux-arm-kernel mailing list