x86/resctrl: Switch over to the resctrl mbps_val list
authorJames Morse <james.morse@arm.com>
Fri, 2 Sep 2022 15:48:17 +0000 (15:48 +0000)
committerBorislav Petkov <bp@suse.de>
Thu, 22 Sep 2022 15:34:08 +0000 (17:34 +0200)
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: James Morse <james.morse@arm.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Jamie Iles <quic_jiles@quicinc.com>
Reviewed-by: Shaopeng Tan <tan.shaopeng@fujitsu.com>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Xin Hao <xhao@linux.alibaba.com>
Tested-by: Shaopeng Tan <tan.shaopeng@fujitsu.com>
Tested-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20220902154829.30399-10-james.morse@arm.com
arch/x86/kernel/cpu/resctrl/ctrlmondata.c
arch/x86/kernel/cpu/resctrl/monitor.c
arch/x86/kernel/cpu/resctrl/rdtgroup.c

index 87666275eed920654868ccf3fd9bb2a0b6b81004..bf9d73c5be149027b2a04ab3a7f1b2d35bd51763 100644 (file)
@@ -61,6 +61,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
             struct rdt_domain *d)
 {
        struct resctrl_staged_config *cfg;
+       u32 closid = data->rdtgrp->closid;
        struct rdt_resource *r = s->res;
        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))
                return -EINVAL;
+
+       if (is_mba_sc(r)) {
+               d->mbps_val[closid] = bw_val;
+               return 0;
+       }
+
        cfg->new_ctrl = bw_val;
        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,
                         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;
-       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);
-               dc[idx] = cfg->new_ctrl;
+               hw_dom->ctrl_val[idx] = cfg->new_ctrl;
 
                return true;
        }
@@ -284,14 +290,12 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
        enum resctrl_conf_type t;
        cpumask_var_t cpu_mask;
        struct rdt_domain *d;
-       bool mba_sc;
        int cpu;
        u32 idx;
 
        if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))
                return -ENOMEM;
 
-       mba_sc = is_mba_sc(r);
        msr_param.res = NULL;
        list_for_each_entry(d, &r->domains, list) {
                hw_dom = resctrl_to_arch_dom(d);
@@ -301,7 +305,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
                                continue;
 
                        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;
 
                        if (!msr_param.res) {
@@ -315,11 +319,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
                }
        }
 
-       /*
-        * Avoid writing the control msr with control values when
-        * MBA software controller is enabled
-        */
-       if (cpumask_empty(cpu_mask) || mba_sc)
+       if (cpumask_empty(cpu_mask))
                goto done;
        cpu = get_cpu();
        /* 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) {
                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);
                if (ret)
                        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);
        u32 idx = get_config_index(closid, type);
 
-       if (!is_mba_sc(r))
-               return hw_dom->ctrl_val[idx];
-       return hw_dom->mbps_val[idx];
+       return hw_dom->ctrl_val[idx];
 }
 
 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)
                        seq_puts(s, ";");
 
-               ctrl_val = resctrl_arch_get_config(r, dom, closid,
-                                                  schema->conf_type);
+               if (is_mba_sc(r))
+                       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,
                           ctrl_val);
                sep = true;
index 497cadf3285d478765340e0c76dd79e95e3ce479..16028b2f756ad5e4775095044904b3f08d222a99 100644 (file)
@@ -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);
 
        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;
-       /*
-        * resctrl_arch_get_config() chooses the mbps/ctrl value to return
-        * based on is_mba_sc(). For now, reach into the hw_dom.
-        */
-       cur_msr_val = hw_dom_mba->ctrl_val[closid];
+
+       /* MBA resource doesn't support CDP */
+       cur_msr_val = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE);
 
        /*
         * For Ctrl groups read data from child monitor groups.
index f7ebd019e7a51710756e28951474a402681b8dca..55d8a12287c30ee766f8a36db8a11a30bfad40f9 100644 (file)
@@ -1356,11 +1356,13 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
                              struct seq_file *s, void *v)
 {
        struct resctrl_schema *schema;
+       enum resctrl_conf_type type;
        struct rdtgroup *rdtgrp;
        struct rdt_resource *r;
        struct rdt_domain *d;
        unsigned int size;
        int ret = 0;
+       u32 closid;
        bool sep;
        u32 ctrl;
 
@@ -1386,8 +1388,11 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
                goto out;
        }
 
+       closid = rdtgrp->closid;
+
        list_for_each_entry(schema, &resctrl_schema_all, list) {
                r = schema->res;
+               type = schema->conf_type;
                sep = false;
                seq_printf(s, "%*s:", max_name_width, schema->name);
                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) {
                                size = 0;
                        } else {
-                               ctrl = resctrl_arch_get_config(r, d,
-                                                              rdtgrp->closid,
-                                                              schema->conf_type);
+                               if (is_mba_sc(r))
+                                       ctrl = d->mbps_val[closid];
+                               else
+                                       ctrl = resctrl_arch_get_config(r, d,
+                                                                      closid,
+                                                                      type);
                                if (r->rid == RDT_RESOURCE_MBA)
                                        size = ctrl;
                                else
@@ -2818,14 +2826,19 @@ static int rdtgroup_init_cat(struct resctrl_schema *s, u32 closid)
 }
 
 /* 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 rdt_domain *d;
 
        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->new_ctrl = is_mba_sc(r) ? MBA_MAX_MBPS : r->default_ctrl;
+               cfg->new_ctrl = r->default_ctrl;
                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) {
                r = s->res;
                if (r->rid == RDT_RESOURCE_MBA) {
-                       rdtgroup_init_mba(r);
+                       rdtgroup_init_mba(r, rdtgrp->closid);
+                       if (is_mba_sc(r))
+                               continue;
                } else {
                        ret = rdtgroup_init_cat(s, rdtgrp->closid);
                        if (ret < 0)