[RFC PATCH 08/38] arm_mpam: resctrl: Pick the caches we will use as resctrl resources

Ben Horgan ben.horgan at arm.com
Fri Dec 19 04:04:10 PST 2025


Hi Jonathan,

On 12/18/25 11:38, Jonathan Cameron wrote:
> On Fri, 5 Dec 2025 21:58:31 +0000
> James Morse <james.morse at arm.com> wrote:
> 
>> Systems with MPAM support may have a variety of control types at any
>> point of their system layout. We can only expose certain types of
>> control, and only if they exist at particular locations.
>>
>> Start with the well-know caches. These have to be depth 2 or 3
>> and support MPAM's cache portion bitmap controls, with a number
>> of portions fewer than resctrl's limit.
> 
> Another one that is a bit random on wrap point.  Probably worth tidying
> up formatting of all the commit messages so fussy people like me stop
> moaning ;)

Will do.

> 
> Otherwise trivial stuff inline.
>>
>> Signed-off-by: James Morse <james.morse at arm.com>
>> ---
>>  drivers/resctrl/mpam_resctrl.c | 91 +++++++++++++++++++++++++++++++++-
>>  1 file changed, 89 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
>> index 320cebbd37ce..ceaf11af4fc1 100644
>> --- a/drivers/resctrl/mpam_resctrl.c
>> +++ b/drivers/resctrl/mpam_resctrl.c
>> @@ -60,10 +60,96 @@ struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l)
>>  	return &mpam_resctrl_controls[l].resctrl_res;
>>  }
>>  
>> +static bool cache_has_usable_cpor(struct mpam_class *class)
>> +{
>> +	struct mpam_props *cprops = &class->props;
>> +
>> +	if (!mpam_has_feature(mpam_feat_cpor_part, cprops))
>> +		return false;
>> +
>> +	/* resctrl uses u32 for all bitmap configurations */
>> +	return (class->props.cpbm_wd <= 32);
> 
> For me those brackets aren't adding anything. It's not like
> anyone forgets precedence wrt return vs operators.
> 
>> +}
>> +
>> +/* Test whether we can export MPAM_CLASS_CACHE:{2,3}? */
>> +static void mpam_resctrl_pick_caches(void)
>> +{
>> +	struct mpam_class *class;
>> +	struct mpam_resctrl_res *res;
>> +
>> +	lockdep_assert_cpus_held();
>> +
>> +	guard(srcu)(&mpam_srcu);
>> +	list_for_each_entry_srcu(class, &mpam_classes, classes_list,
>> +				 srcu_read_lock_held(&mpam_srcu)) {
>> +		if (class->type != MPAM_CLASS_CACHE) {
>> +			pr_debug("class %u is not a cache\n", class->level);
> 
> Lots of things aren't caches and seems unlikely that is a case that will
> make people wonder why pick caches didn't happen. So maybe this debug
> print is excessive?

Only memory or cache so far. I'll leave it here for now.

> 
>> +			continue;
>> +		}
>> +
>> +		if (class->level != 2 && class->level != 3) {
>> +			pr_debug("class %u is not L2 or L3\n", class->level);
>> +			continue;
>> +		}
>> +
>> +		if (!cache_has_usable_cpor(class)) {
>> +			pr_debug("class %u cache misses CPOR\n", class->level);
>> +			continue;
>> +		}
>> +
>> +		if (!cpumask_equal(&class->affinity, cpu_possible_mask)) {
>> +			pr_debug("class %u has missing CPUs\n", class->level);
>> +			pr_debug("class %u mask %*pb != %*pb\n", class->level,
>> +				 cpumask_pr_args(&class->affinity),
>> +				 cpumask_pr_args(cpu_possible_mask));
> 
> Unless this is getting more complex in later patches, doesn't seem like
> 			pr_debug("class %u has missing CPUs, mask %*pb != %*pb\n",
> is too much to put on one line.

Done.

> 
> 					 
>> +			continue;
>> +		}
>> +
>> +		if (class->level == 2)
>> +			res = &mpam_resctrl_controls[RDT_RESOURCE_L2];
>> +		else
>> +			res = &mpam_resctrl_controls[RDT_RESOURCE_L3];
>> +		res->class = class;
>> +		exposed_alloc_capable = true;
>> +	}
>> +}
>> +
>>  static int mpam_resctrl_control_init(struct mpam_resctrl_res *res,
>>  				     enum resctrl_res_level type)
>>  {
>> -	/* TODO: initialise the resctrl resources */
>> +	struct mpam_class *class = res->class;
>> +	struct rdt_resource *r = &res->resctrl_res;
>> +
>> +	switch (res->resctrl_res.rid) {
> 
> 	switch (r->rid) { ?
> 
>> +	case RDT_RESOURCE_L2:
>> +	case RDT_RESOURCE_L3:
>> +		r->alloc_capable = true;
>> +		r->schema_fmt = RESCTRL_SCHEMA_BITMAP;
>> +		r->cache.arch_has_sparse_bitmasks = true;
>> +
>> +		r->cache.cbm_len = class->props.cpbm_wd;
>> +		/* mpam_devices will reject empty bitmaps */
>> +		r->cache.min_cbm_bits = 1;
>> +
>> +		if (r->rid == RDT_RESOURCE_L2) {
>> +			r->name = "L2";
>> +			r->ctrl_scope = RESCTRL_L2_CACHE;
>> +		} else {
>> +			r->name = "L3";
>> +			r->ctrl_scope = RESCTRL_L3_CACHE;
>> +		}
>> +
>> +		/*
>> +		 * Which bits are shared with other ...things...
>> +		 * Unknown devices use partid-0 which uses all the bitmap
>> +		 * fields. Until we configured the SMMU and GIC not to do this
>> +		 * 'all the bits' is the correct answer here.
>> +		 */
>> +		r->cache.shareable_bits = resctrl_get_default_ctrl(r);
>> +		break;
>> +	default:
>> +		break;
>> +	}
>>  
>>  	return 0;
>>  }
>> @@ -286,7 +372,8 @@ int mpam_resctrl_setup(void)
>>  		res->resctrl_res.rid = i;
>>  	}
>>  
>> -	/* TODO: pick MPAM classes to map to resctrl resources */
>> +	/* Find some classes to use for controls */
>> +	mpam_resctrl_pick_caches();
>>  
>>  	/* Initialise the resctrl structures from the classes */
>>  	for (i = 0; i < RDT_NUM_RESOURCES; i++) {
> 

Thanks,

Ben




More information about the linux-arm-kernel mailing list