Commit 931c0972 authored by James Morse's avatar James Morse Committed by Zeng Heng
Browse files

arm_mpam: Merge supported features during mpam_enable() into mpam_class

maillist inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8T2RT

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git/log/?h=mpam/snapshot/v6.7-rc2



---------------------------

To make a decision about whether to expose an mpam class as
a resctrl resource we need to know its overall supported
features and properties.

Once we've probed all the resources, we can walk the tree
and produced overall values by merging the bitmaps. This
eliminates features that are only supported by some MSC
that make up a component or class.

If bitmap properties are mismatched within a component we
cannot support the mismatched feature.

Signed-off-by: default avatarJames Morse <james.morse@arm.com>
Signed-off-by: default avatarZeng Heng <zengheng4@huawei.com>
parent 051d021d
Loading
Loading
Loading
Loading
+87 −0
Original line number Diff line number Diff line
@@ -938,8 +938,95 @@ static int mpam_msc_drv_probe(struct platform_device *pdev)
	return err;
}

/*
 * If a resource doesn't match class feature/configuration, do the right thing.
 * For 'num' properties we can just take the minimum.
 * For properties where the mismatched unused bits would make a difference, we
 * nobble the class feature, as we can't configure all the resources.
 * e.g. The L3 cache is composed of two resources with 13 and 17 portion
 * bitmaps respectively.
 */
static void
__resource_props_mismatch(struct mpam_msc_ris *ris, struct mpam_class *class)
{
	struct mpam_props *cprops = &class->props;
	struct mpam_props *rprops = &ris->props;

	lockdep_assert_held(&mpam_list_lock); /* we modify class */

	/* Clear missing features */
	cprops->features &= rprops->features;

	/* Clear incompatible features */
	if (cprops->cpbm_wd != rprops->cpbm_wd)
		mpam_clear_feature(mpam_feat_cpor_part, &cprops->features);
	if (cprops->mbw_pbm_bits != rprops->mbw_pbm_bits)
		mpam_clear_feature(mpam_feat_mbw_part, &cprops->features);

	/* bwa_wd is a count of bits, fewer bits means less precision */
	if (cprops->bwa_wd != rprops->bwa_wd)
		cprops->bwa_wd = min(cprops->bwa_wd, rprops->bwa_wd);

	/* For num properties, take the minimum */
	if (cprops->num_csu_mon != rprops->num_csu_mon)
		cprops->num_csu_mon = min(cprops->num_csu_mon, rprops->num_csu_mon);
	if (cprops->num_mbwu_mon != rprops->num_mbwu_mon)
		cprops->num_mbwu_mon = min(cprops->num_mbwu_mon, rprops->num_mbwu_mon);
}

/*
 * Copy the first component's first resources's properties and features to the
 * class. __resource_props_mismatch() will remove conflicts.
 * It is not possible to have a class with no components, or a component with
 * no resources.
 */
static void mpam_enable_init_class_features(struct mpam_class *class)
{
	struct mpam_msc_ris *ris;
	struct mpam_component *comp;

	comp = list_first_entry_or_null(&class->components,
					struct mpam_component, class_list);
	if (WARN_ON(!comp))
		return;

	ris = list_first_entry_or_null(&comp->ris,
				       struct mpam_msc_ris, comp_list);
	if (WARN_ON(!ris))
		return;

	class->props = ris->props;
}

/* Merge all the common resource features into class. */
static void mpam_enable_merge_features(void)
{
	struct mpam_msc_ris *ris;
	struct mpam_class *class;
	struct mpam_component *comp;

	lockdep_assert_held(&mpam_list_lock);

	list_for_each_entry(class, &mpam_classes, classes_list) {
		mpam_enable_init_class_features(class);

		list_for_each_entry(comp, &class->components, class_list) {
			list_for_each_entry(ris, &comp->ris, comp_list) {
				__resource_props_mismatch(ris, class);

				class->nrdy_usec = max(class->nrdy_usec,
						     ris->msc->nrdy_usec);
			}
		}
	}
}

static void mpam_enable_once(void)
{
	mutex_lock(&mpam_list_lock);
	mpam_enable_merge_features();
	mutex_unlock(&mpam_list_lock);

	mutex_lock(&mpam_cpuhp_state_lock);
	cpuhp_remove_state(mpam_cpuhp_state);
	mpam_cpuhp_state = 0;
+8 −0
Original line number Diff line number Diff line
@@ -97,6 +97,12 @@ static inline void mpam_set_feature(enum mpam_device_features feat,
	props->features |= (1<<feat);
}

static inline void mpam_clear_feature(enum mpam_device_features feat,
				      mpam_features_t *supported)
{
	*supported &= ~(1<<feat);
}

struct mpam_class
{
	/* mpam_components in this class */
@@ -104,6 +110,8 @@ struct mpam_class

	cpumask_t		affinity;

	struct mpam_props	props;
	u32			nrdy_usec;
	u8			level;
	enum mpam_class_types	type;