Commit 6ce1560d authored by James Morse's avatar James Morse Committed by Borislav Petkov
Browse files

x86/resctrl: Switch over to the resctrl mbps_val list



Updates to resctrl's software controller follow the same path as
other configuration updates, but they don't modify the hardware state.
rdtgroup_schemata_write() uses parse_line() and the resource's
parse_ctrlval() function to stage the configuration.
resctrl_arch_update_domains() then updates the mbps_val[] array
instead, and resctrl_arch_update_domains() skips the rdt_ctrl_update()
call that would update hardware.

This complicates the interface between resctrl's filesystem parts
and architecture specific code. It should be possible for mba_sc
to be completely implemented by the filesystem parts of resctrl. This
would allow it to work on a second architecture with no additional code.
resctrl_arch_update_domains() using the mbps_val[] array prevents this.

Change parse_bw() to write the configuration value directly to the
mbps_val[] array in the domain structure. Change rdtgroup_schemata_write()
to skip the call to resctrl_arch_update_domains(), meaning all the
mba_sc specific code in resctrl_arch_update_domains() can be removed.
On the read-side, show_doms() and update_mba_bw() are changed to read
the mbps_val[] array from the domain structure. With this,
resctrl_arch_get_config() no longer needs to consider mba_sc resources.

Signed-off-by: default avatarJames Morse <james.morse@arm.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarJamie Iles <quic_jiles@quicinc.com>
Reviewed-by: default avatarShaopeng Tan <tan.shaopeng@fujitsu.com>
Reviewed-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Tested-by: default avatarXin Hao <xhao@linux.alibaba.com>
Tested-by: default avatarShaopeng Tan <tan.shaopeng@fujitsu.com>
Tested-by: default avatarCristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20220902154829.30399-10-james.morse@arm.com
parent 781096d9
Loading
Loading
Loading
Loading
+27 −17
Original line number Original line Diff line number Diff line
@@ -61,6 +61,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
	     struct rdt_domain *d)
	     struct rdt_domain *d)
{
{
	struct resctrl_staged_config *cfg;
	struct resctrl_staged_config *cfg;
	u32 closid = data->rdtgrp->closid;
	struct rdt_resource *r = s->res;
	struct rdt_resource *r = s->res;
	unsigned long bw_val;
	unsigned long bw_val;


@@ -72,6 +73,12 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,


	if (!bw_validate(data->buf, &bw_val, r))
	if (!bw_validate(data->buf, &bw_val, r))
		return -EINVAL;
		return -EINVAL;

	if (is_mba_sc(r)) {
		d->mbps_val[closid] = bw_val;
		return 0;
	}

	cfg->new_ctrl = bw_val;
	cfg->new_ctrl = bw_val;
	cfg->have_new_ctrl = true;
	cfg->have_new_ctrl = true;


@@ -261,14 +268,13 @@ static u32 get_config_index(u32 closid, enum resctrl_conf_type type)


static bool apply_config(struct rdt_hw_domain *hw_dom,
static bool apply_config(struct rdt_hw_domain *hw_dom,
			 struct resctrl_staged_config *cfg, u32 idx,
			 struct resctrl_staged_config *cfg, u32 idx,
			 cpumask_var_t cpu_mask, bool mba_sc)
			 cpumask_var_t cpu_mask)
{
{
	struct rdt_domain *dom = &hw_dom->d_resctrl;
	struct rdt_domain *dom = &hw_dom->d_resctrl;
	u32 *dc = !mba_sc ? hw_dom->ctrl_val : hw_dom->mbps_val;


	if (cfg->new_ctrl != dc[idx]) {
	if (cfg->new_ctrl != hw_dom->ctrl_val[idx]) {
		cpumask_set_cpu(cpumask_any(&dom->cpu_mask), cpu_mask);
		cpumask_set_cpu(cpumask_any(&dom->cpu_mask), cpu_mask);
		dc[idx] = cfg->new_ctrl;
		hw_dom->ctrl_val[idx] = cfg->new_ctrl;


		return true;
		return true;
	}
	}
@@ -284,14 +290,12 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
	enum resctrl_conf_type t;
	enum resctrl_conf_type t;
	cpumask_var_t cpu_mask;
	cpumask_var_t cpu_mask;
	struct rdt_domain *d;
	struct rdt_domain *d;
	bool mba_sc;
	int cpu;
	int cpu;
	u32 idx;
	u32 idx;


	if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))
	if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))
		return -ENOMEM;
		return -ENOMEM;


	mba_sc = is_mba_sc(r);
	msr_param.res = NULL;
	msr_param.res = NULL;
	list_for_each_entry(d, &r->domains, list) {
	list_for_each_entry(d, &r->domains, list) {
		hw_dom = resctrl_to_arch_dom(d);
		hw_dom = resctrl_to_arch_dom(d);
@@ -301,7 +305,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
				continue;
				continue;


			idx = get_config_index(closid, t);
			idx = get_config_index(closid, t);
			if (!apply_config(hw_dom, cfg, idx, cpu_mask, mba_sc))
			if (!apply_config(hw_dom, cfg, idx, cpu_mask))
				continue;
				continue;


			if (!msr_param.res) {
			if (!msr_param.res) {
@@ -315,11 +319,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
		}
		}
	}
	}


	/*
	if (cpumask_empty(cpu_mask))
	 * Avoid writing the control msr with control values when
	 * MBA software controller is enabled
	 */
	if (cpumask_empty(cpu_mask) || mba_sc)
		goto done;
		goto done;
	cpu = get_cpu();
	cpu = get_cpu();
	/* Update resource control msr on this CPU if it's in cpu_mask. */
	/* Update resource control msr on this CPU if it's in cpu_mask. */
@@ -406,6 +406,14 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,


	list_for_each_entry(s, &resctrl_schema_all, list) {
	list_for_each_entry(s, &resctrl_schema_all, list) {
		r = s->res;
		r = s->res;

		/*
		 * Writes to mba_sc resources update the software controller,
		 * not the control MSR.
		 */
		if (is_mba_sc(r))
			continue;

		ret = resctrl_arch_update_domains(r, rdtgrp->closid);
		ret = resctrl_arch_update_domains(r, rdtgrp->closid);
		if (ret)
		if (ret)
			goto out;
			goto out;
@@ -433,9 +441,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d,
	struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
	struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
	u32 idx = get_config_index(closid, type);
	u32 idx = get_config_index(closid, type);


	if (!is_mba_sc(r))
	return hw_dom->ctrl_val[idx];
	return hw_dom->ctrl_val[idx];
	return hw_dom->mbps_val[idx];
}
}


static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int closid)
static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int closid)
@@ -450,8 +456,12 @@ static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int clo
		if (sep)
		if (sep)
			seq_puts(s, ";");
			seq_puts(s, ";");


		if (is_mba_sc(r))
			ctrl_val = dom->mbps_val[closid];
		else
			ctrl_val = resctrl_arch_get_config(r, dom, closid,
			ctrl_val = resctrl_arch_get_config(r, dom, closid,
							   schema->conf_type);
							   schema->conf_type);

		seq_printf(s, r->format_str, dom->id, max_data_width,
		seq_printf(s, r->format_str, dom->id, max_data_width,
			   ctrl_val);
			   ctrl_val);
		sep = true;
		sep = true;
+4 −6
Original line number Original line Diff line number Diff line
@@ -447,13 +447,11 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
	hw_dom_mba = resctrl_to_arch_dom(dom_mba);
	hw_dom_mba = resctrl_to_arch_dom(dom_mba);


	cur_bw = pmbm_data->prev_bw;
	cur_bw = pmbm_data->prev_bw;
	user_bw = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE);
	user_bw = dom_mba->mbps_val[closid];
	delta_bw = pmbm_data->delta_bw;
	delta_bw = pmbm_data->delta_bw;
	/*

	 * resctrl_arch_get_config() chooses the mbps/ctrl value to return
	/* MBA resource doesn't support CDP */
	 * based on is_mba_sc(). For now, reach into the hw_dom.
	cur_msr_val = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE);
	 */
	cur_msr_val = hw_dom_mba->ctrl_val[closid];


	/*
	/*
	 * For Ctrl groups read data from child monitor groups.
	 * For Ctrl groups read data from child monitor groups.
+21 −6
Original line number Original line Diff line number Diff line
@@ -1356,11 +1356,13 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
			      struct seq_file *s, void *v)
			      struct seq_file *s, void *v)
{
{
	struct resctrl_schema *schema;
	struct resctrl_schema *schema;
	enum resctrl_conf_type type;
	struct rdtgroup *rdtgrp;
	struct rdtgroup *rdtgrp;
	struct rdt_resource *r;
	struct rdt_resource *r;
	struct rdt_domain *d;
	struct rdt_domain *d;
	unsigned int size;
	unsigned int size;
	int ret = 0;
	int ret = 0;
	u32 closid;
	bool sep;
	bool sep;
	u32 ctrl;
	u32 ctrl;


@@ -1386,8 +1388,11 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
		goto out;
		goto out;
	}
	}


	closid = rdtgrp->closid;

	list_for_each_entry(schema, &resctrl_schema_all, list) {
	list_for_each_entry(schema, &resctrl_schema_all, list) {
		r = schema->res;
		r = schema->res;
		type = schema->conf_type;
		sep = false;
		sep = false;
		seq_printf(s, "%*s:", max_name_width, schema->name);
		seq_printf(s, "%*s:", max_name_width, schema->name);
		list_for_each_entry(d, &r->domains, list) {
		list_for_each_entry(d, &r->domains, list) {
@@ -1396,9 +1401,12 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
			if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
			if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
				size = 0;
				size = 0;
			} else {
			} else {
				if (is_mba_sc(r))
					ctrl = d->mbps_val[closid];
				else
					ctrl = resctrl_arch_get_config(r, d,
					ctrl = resctrl_arch_get_config(r, d,
							       rdtgrp->closid,
								       closid,
							       schema->conf_type);
								       type);
				if (r->rid == RDT_RESOURCE_MBA)
				if (r->rid == RDT_RESOURCE_MBA)
					size = ctrl;
					size = ctrl;
				else
				else
@@ -2818,14 +2826,19 @@ static int rdtgroup_init_cat(struct resctrl_schema *s, u32 closid)
}
}


/* Initialize MBA resource with default values. */
/* Initialize MBA resource with default values. */
static void rdtgroup_init_mba(struct rdt_resource *r)
static void rdtgroup_init_mba(struct rdt_resource *r, u32 closid)
{
{
	struct resctrl_staged_config *cfg;
	struct resctrl_staged_config *cfg;
	struct rdt_domain *d;
	struct rdt_domain *d;


	list_for_each_entry(d, &r->domains, list) {
	list_for_each_entry(d, &r->domains, list) {
		if (is_mba_sc(r)) {
			d->mbps_val[closid] = MBA_MAX_MBPS;
			continue;
		}

		cfg = &d->staged_config[CDP_NONE];
		cfg = &d->staged_config[CDP_NONE];
		cfg->new_ctrl = is_mba_sc(r) ? MBA_MAX_MBPS : r->default_ctrl;
		cfg->new_ctrl = r->default_ctrl;
		cfg->have_new_ctrl = true;
		cfg->have_new_ctrl = true;
	}
	}
}
}
@@ -2840,7 +2853,9 @@ static int rdtgroup_init_alloc(struct rdtgroup *rdtgrp)
	list_for_each_entry(s, &resctrl_schema_all, list) {
	list_for_each_entry(s, &resctrl_schema_all, list) {
		r = s->res;
		r = s->res;
		if (r->rid == RDT_RESOURCE_MBA) {
		if (r->rid == RDT_RESOURCE_MBA) {
			rdtgroup_init_mba(r);
			rdtgroup_init_mba(r, rdtgrp->closid);
			if (is_mba_sc(r))
				continue;
		} else {
		} else {
			ret = rdtgroup_init_cat(s, rdtgrp->closid);
			ret = rdtgroup_init_cat(s, rdtgrp->closid);
			if (ret < 0)
			if (ret < 0)