Re: [PATCH 15/23] arm_mpam: Refine L3 topology and class selection
From: Ben Horgan
Date: Fri Jul 17 2026 - 05:23:55 EST
Hi Fenghua,
On 7/16/26 22:03, Fenghua Yu wrote:
> After enabling memory-level MSCs, the existing class-picking heuristics
> still treat every candidate like an L3 cache MSC. That rejects valid
> memory classes for MBWU counters and applies L3 egress checks to MBA
> classes on CPU-less or system-wide affinities, leaving no monitor or
> control class selected on affected platforms.
>
> Adjust the heuristics
I think we have to live with what we've got. We don't want to change the resctrl monitor events or
schemata files for existing platforms.
so memory classes can back MBWU directly, L3
> topology matching is only required for level-3 MBA candidates, and
> traffic matching is skipped when the class already spans all CPUs.
I think we can keep the existing checks the same and if they match go with what we've got and if
they don't then you can go ahead and use MBWU/MBA at NUMA scope when appropriate.
> Also tolerate components with no online CPUs once at least one
> component has matched.
Ok, new support for unexposed features can be added but if we've already got support for something
in the specific setup then we shouldn't change how it is exposed to the user.
THanks,
Ben
>
> Signed-off-by: Shanker Donthineni <sdonthineni@xxxxxxxxxx>
> Signed-off-by: Fenghua Yu <fenghuay@xxxxxxxxxx>
> ---
> drivers/resctrl/mpam_resctrl.c | 22 +++++++++++++++++-----
> 1 file changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
> index 953412f11995..86458a56a526 100644
> --- a/drivers/resctrl/mpam_resctrl.c
> +++ b/drivers/resctrl/mpam_resctrl.c
> @@ -854,10 +854,12 @@ static bool topology_matches_l3(struct mpam_class *victim)
> {
> int cpu, err;
> struct mpam_component *victim_iter;
> + bool matched_once = false;
>
> lockdep_assert_cpus_held();
>
> cpumask_var_t __free(free_cpumask_var) tmp_cpumask = CPUMASK_VAR_NULL;
> +
> if (!alloc_cpumask_var(&tmp_cpumask, GFP_KERNEL))
> return false;
>
> @@ -871,8 +873,11 @@ static bool topology_matches_l3(struct mpam_class *victim)
> }
>
> cpu = cpumask_any_and(&victim_iter->affinity, cpu_online_mask);
> - if (WARN_ON_ONCE(cpu >= nr_cpu_ids))
> + if (WARN_ON_ONCE(cpu >= nr_cpu_ids)) {
> + if (matched_once)
> + continue;
> return false;
> + }
>
> cpumask_clear(tmp_cpumask);
> err = find_l3_equivalent_bitmask(cpu, tmp_cpumask);
> @@ -892,6 +897,7 @@ static bool topology_matches_l3(struct mpam_class *victim)
>
> return false;
> }
> + matched_once = true;
> }
>
> return true;
> @@ -1030,13 +1036,15 @@ static void mpam_resctrl_pick_mba(void)
> continue;
> }
>
> - if (!topology_matches_l3(class)) {
> + if (class->level == 3 && !topology_matches_l3(class)) {
> pr_debug("class %u topology doesn't match L3\n",
> class->level);
> continue;
> }
>
> - if (!traffic_matches_l3(class)) {
> + /* Check memory at egress from L3 for MSC with L3 */
> + if (!cpumask_equal(&class->affinity, cpu_possible_mask) &&
> + !traffic_matches_l3(class)) {
> pr_debug("class %u traffic doesn't match L3 egress\n",
> class->level);
> continue;
> @@ -1164,8 +1172,9 @@ static void mpam_resctrl_pick_counters(void)
> }
>
> if (class_has_usable_mbwu(class) &&
> - topology_matches_l3(class) &&
> - traffic_matches_l3(class)) {
> + ((class->type == MPAM_CLASS_MEMORY) ||
> + (topology_matches_l3(class) &&
> + traffic_matches_l3(class)))) {
> pr_debug("class %u has usable MBWU, and matches L3 topology and traffic\n",
> class->level);
>
> @@ -1302,6 +1311,9 @@ static int mpam_resctrl_pick_domain_id(int cpu, struct mpam_component *comp)
> if (class->type == MPAM_CLASS_CACHE)
> return comp->comp_id;
>
> + if (mpam_class_memory(class))
> + return comp->comp_id;
> +
> if (topology_matches_l3(class)) {
> /* Use the corresponding L3 component ID as the domain ID */
> int id = get_cpu_cacheinfo_id(cpu, 3);