[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