Commit fb481ec0 authored by James Morse's avatar James Morse
Browse files

arm_mpam: resctrl: Call resctrl_init() on platforms that can support resctrl



Now that MPAM links against resctrl, call resctrl_init() to register the
filesystem and setup resctrl's structures.

Tested-by: default avatarGavin Shan <gshan@redhat.com>
Tested-by: default avatarShaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Tested-by: default avatarPeter Newman <peternewman@google.com>
Tested-by: default avatarZeng Heng <zengheng4@huawei.com>
Tested-by: default avatarPunit Agrawal <punit.agrawal@oss.qualcomm.com>
Tested-by: default avatarJesse Chick <jessechick@os.amperecomputing.com>
Reviewed-by: default avatarZeng Heng <zengheng4@huawei.com>
Reviewed-by: default avatarShaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Reviewed-by: default avatarJonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: default avatarGavin Shan <gshan@redhat.com>
Co-developed-by: default avatarBen Horgan <ben.horgan@arm.com>
Signed-off-by: default avatarBen Horgan <ben.horgan@arm.com>
Signed-off-by: default avatarJames Morse <james.morse@arm.com>
parent 4aab135b
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -73,6 +73,14 @@ static DECLARE_WORK(mpam_broken_work, &mpam_disable);
/* When mpam is disabled, the printed reason to aid debugging */
static char *mpam_disable_reason;

/*
 * Whether resctrl has been setup. Used by cpuhp in preference to
 * mpam_is_enabled(). The disable call after an error interrupt makes
 * mpam_is_enabled() false before the cpuhp callbacks are made.
 * Reads/writes should hold mpam_cpuhp_state_lock, (or be cpuhp callbacks).
 */
static bool mpam_resctrl_enabled;

/*
 * An MSC is a physical container for controls and monitors, each identified by
 * their RIS index. These share a base-address, interrupts and some MMIO
@@ -1619,7 +1627,7 @@ static int mpam_cpu_online(unsigned int cpu)
			mpam_reprogram_msc(msc);
	}

	if (mpam_is_enabled())
	if (mpam_resctrl_enabled)
		return mpam_resctrl_online_cpu(cpu);

	return 0;
@@ -1665,7 +1673,7 @@ static int mpam_cpu_offline(unsigned int cpu)
{
	struct mpam_msc *msc;

	if (mpam_is_enabled())
	if (mpam_resctrl_enabled)
		mpam_resctrl_offline_cpu(cpu);

	guard(srcu)(&mpam_srcu);
@@ -2526,6 +2534,7 @@ static void mpam_enable_once(void)
	}

	static_branch_enable(&mpam_enabled);
	mpam_resctrl_enabled = true;
	mpam_register_cpuhp_callbacks(mpam_cpu_online, mpam_cpu_offline,
				      "mpam:online");

@@ -2585,24 +2594,39 @@ static void mpam_reset_class(struct mpam_class *class)
void mpam_disable(struct work_struct *ignored)
{
	int idx;
	bool do_resctrl_exit;
	struct mpam_class *class;
	struct mpam_msc *msc, *tmp;

	if (mpam_is_enabled())
		static_branch_disable(&mpam_enabled);

	mutex_lock(&mpam_cpuhp_state_lock);
	if (mpam_cpuhp_state) {
		cpuhp_remove_state(mpam_cpuhp_state);
		mpam_cpuhp_state = 0;
	}

	/*
	 * Removing the cpuhp state called mpam_cpu_offline() and told resctrl
	 * all the CPUs are offline.
	 */
	do_resctrl_exit = mpam_resctrl_enabled;
	mpam_resctrl_enabled = false;
	mutex_unlock(&mpam_cpuhp_state_lock);

	static_branch_disable(&mpam_enabled);
	if (do_resctrl_exit)
		mpam_resctrl_exit();

	mpam_unregister_irqs();

	idx = srcu_read_lock(&mpam_srcu);
	list_for_each_entry_srcu(class, &mpam_classes, classes_list,
				 srcu_read_lock_held(&mpam_srcu))
				 srcu_read_lock_held(&mpam_srcu)) {
		mpam_reset_class(class);
		if (do_resctrl_exit)
			mpam_resctrl_teardown_class(class);
	}
	srcu_read_unlock(&mpam_srcu, idx);

	mutex_lock(&mpam_list_lock);
+4 −0
Original line number Diff line number Diff line
@@ -431,12 +431,16 @@ int mpam_get_cpumask_from_cache_id(unsigned long cache_id, u32 cache_level,

#ifdef CONFIG_RESCTRL_FS
int mpam_resctrl_setup(void);
void mpam_resctrl_exit(void);
int mpam_resctrl_online_cpu(unsigned int cpu);
void mpam_resctrl_offline_cpu(unsigned int cpu);
void mpam_resctrl_teardown_class(struct mpam_class *class);
#else
static inline int mpam_resctrl_setup(void) { return 0; }
static inline void mpam_resctrl_exit(void) { }
static inline int mpam_resctrl_online_cpu(unsigned int cpu) { return 0; }
static inline void mpam_resctrl_offline_cpu(unsigned int cpu) { }
static inline void mpam_resctrl_teardown_class(struct mpam_class *class) { }
#endif /* CONFIG_RESCTRL_FS */

/*
+62 −1
Original line number Diff line number Diff line
@@ -69,6 +69,12 @@ static bool cdp_enabled;
static bool cacheinfo_ready;
static DECLARE_WAIT_QUEUE_HEAD(wait_cacheinfo_ready);

/*
 * If resctrl_init() succeeded, resctrl_exit() can be used to remove support
 * for the filesystem in the event of an error.
 */
static bool resctrl_enabled;

bool resctrl_arch_alloc_capable(void)
{
	struct mpam_resctrl_res *res;
@@ -360,6 +366,9 @@ static int resctrl_arch_mon_ctx_alloc_no_wait(enum resctrl_event_id evtid)
{
	struct mpam_resctrl_mon *mon = &mpam_resctrl_counters[evtid];

	if (!mpam_is_enabled())
		return -EINVAL;

	if (!mon->class)
		return -EINVAL;

@@ -402,6 +411,9 @@ static void resctrl_arch_mon_ctx_free_no_wait(enum resctrl_event_id evtid,
{
	struct mpam_resctrl_mon *mon = &mpam_resctrl_counters[evtid];

	if (!mpam_is_enabled())
		return;

	if (!mon->class)
		return;

@@ -488,6 +500,9 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain_hdr *hdr,

	resctrl_arch_rmid_read_context_check();

	if (!mpam_is_enabled())
		return -EINVAL;

	if (eventid >= QOS_NUM_EVENTS || !mon->class)
		return -EINVAL;

@@ -1162,6 +1177,9 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_ctrl_domain *d,
	lockdep_assert_cpus_held();
	lockdep_assert_irqs_enabled();

	if (!mpam_is_enabled())
		return -EINVAL;

	/*
	 * No need to check the CPU as mpam_apply_config() doesn't care, and
	 * resctrl_arch_update_domains() relies on this.
@@ -1227,6 +1245,9 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
	lockdep_assert_cpus_held();
	lockdep_assert_irqs_enabled();

	if (!mpam_is_enabled())
		return -EINVAL;

	list_for_each_entry_rcu(d, &r->ctrl_domains, hdr.list) {
		for (enum resctrl_conf_type t = 0; t < CDP_NUM_TYPES; t++) {
			struct resctrl_staged_config *cfg = &d->staged_config[t];
@@ -1619,7 +1640,11 @@ int mpam_resctrl_setup(void)
		return -EOPNOTSUPP;
	}

	/* TODO: call resctrl_init() */
	err = resctrl_init();
	if (err)
		return err;

	WRITE_ONCE(resctrl_enabled, true);

	return 0;

@@ -1629,6 +1654,42 @@ int mpam_resctrl_setup(void)
	return err;
}

void mpam_resctrl_exit(void)
{
	if (!READ_ONCE(resctrl_enabled))
		return;

	WRITE_ONCE(resctrl_enabled, false);
	resctrl_exit();
}

/*
 * The driver is detaching an MSC from this class, if resctrl was using it,
 * pull on resctrl_exit().
 */
void mpam_resctrl_teardown_class(struct mpam_class *class)
{
	struct mpam_resctrl_res *res;
	enum resctrl_res_level rid;
	struct mpam_resctrl_mon *mon;
	enum resctrl_event_id eventid;

	might_sleep();

	for_each_mpam_resctrl_control(res, rid) {
		if (res->class == class) {
			res->class = NULL;
			break;
		}
	}
	for_each_mpam_resctrl_mon(mon, eventid) {
		if (mon->class == class) {
			mon->class = NULL;
			break;
		}
	}
}

static int __init __cacheinfo_ready(void)
{
	cacheinfo_ready = true;