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

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
...@@ -61,6 +61,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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, ";");
ctrl_val = resctrl_arch_get_config(r, dom, closid, if (is_mba_sc(r))
schema->conf_type); ctrl_val = dom->mbps_val[closid];
else
ctrl_val = resctrl_arch_get_config(r, dom, closid,
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;
......
...@@ -447,13 +447,11 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) ...@@ -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.
......
...@@ -1356,11 +1356,13 @@ static int rdtgroup_size_show(struct kernfs_open_file *of, ...@@ -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, ...@@ -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, ...@@ -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 {
ctrl = resctrl_arch_get_config(r, d, if (is_mba_sc(r))
rdtgrp->closid, ctrl = d->mbps_val[closid];
schema->conf_type); else
ctrl = resctrl_arch_get_config(r, d,
closid,
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) ...@@ -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) ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment