We want to merge the L2/L2CODE/L2DATA resources to be a single resource,
but we still need to be able to apply separate CODE and DATA schema to
the domain.

Move the new_ctrl bitmap value and flag into a struct, and create an
array of them. Today there is only one element in the array, but
eventually resctrl will use the array slots for CODE/DATA/BOTH to
detect a duplicate schema being written.

Signed-off-by: James Morse <james.mo...@arm.com>
---
 arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c | 44 +++++++++++++++------
 include/linux/resctrl.h                     | 16 ++++++--
 2 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c 
b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
index e3dcb5161122..1068a19e03c5 100644
--- a/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
+++ b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
@@ -67,16 +67,17 @@ static bool bw_validate(char *buf, unsigned long *data, 
struct rdt_resource *r)
 int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d)
 {
        unsigned long data;
+       struct resctrl_staged_config *cfg = &d->staged_config[0];
 
-       if (d->have_new_ctrl) {
+       if (cfg->have_new_ctrl) {
                rdt_last_cmd_printf("duplicate domain %d\n", d->id);
                return -EINVAL;
        }
 
        if (!bw_validate(buf, &data, r))
                return -EINVAL;
-       d->new_ctrl = data;
-       d->have_new_ctrl = true;
+       cfg->new_ctrl = data;
+       cfg->have_new_ctrl = true;
 
        return 0;
 }
@@ -129,16 +130,17 @@ static bool cbm_validate(char *buf, unsigned long *data, 
struct rdt_resource *r)
 int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d)
 {
        unsigned long data;
+       struct resctrl_staged_config *cfg = &d->staged_config[0];
 
-       if (d->have_new_ctrl) {
+       if (cfg->have_new_ctrl) {
                rdt_last_cmd_printf("duplicate domain %d\n", d->id);
                return -EINVAL;
        }
 
        if(!cbm_validate(buf, &data, r))
                return -EINVAL;
-       d->new_ctrl = data;
-       d->have_new_ctrl = true;
+       cfg->new_ctrl = data;
+       cfg->have_new_ctrl = true;
 
        return 0;
 }
@@ -175,15 +177,29 @@ static int parse_line(char *line, struct rdt_resource *r)
        return -EINVAL;
 }
 
+static void apply_config(struct rdt_hw_domain *hw_dom,
+                        struct resctrl_staged_config *cfg, int closid,
+                        cpumask_var_t cpu_mask, bool mba_sc)
+{
+       u32 *dc = !mba_sc ? hw_dom->ctrl_val : hw_dom->mbps_val;
+
+       if (cfg->new_ctrl != dc[closid]) {
+               cpumask_set_cpu(cpumask_any(&hw_dom->resctrl.cpu_mask),
+                               cpu_mask);
+               dc[closid] = cfg->new_ctrl;
+               cfg->have_new_ctrl = false;
+       }
+}
+
 static int update_domains(struct rdt_resource *r, int closid)
 {
+       struct resctrl_staged_config *cfg;
        struct rdt_hw_domain *hw_dom;
        struct msr_param msr_param;
        cpumask_var_t cpu_mask;
        struct rdt_domain *d;
        bool mba_sc;
-       u32 *dc;
-       int cpu;
+       int i, cpu;
 
        if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))
                return -ENOMEM;
@@ -195,10 +211,12 @@ static int update_domains(struct rdt_resource *r, int 
closid)
        mba_sc = is_mba_sc(r);
        list_for_each_entry(d, &r->domains, list) {
                hw_dom = rc_dom_to_rdt(d);
-               dc = !mba_sc ? hw_dom->ctrl_val : hw_dom->mbps_val;
-               if (d->have_new_ctrl && d->new_ctrl != dc[closid]) {
-                       cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask);
-                       dc[closid] = d->new_ctrl;
+               for (i = 0; i < ARRAY_SIZE(d->staged_config); i++) {
+                       cfg = &hw_dom->resctrl.staged_config[i];
+                       if (!cfg->have_new_ctrl)
+                               continue;
+
+                       apply_config(hw_dom, cfg, closid, cpu_mask, mba_sc);
                }
        }
 
@@ -259,7 +277,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
 
        for_each_alloc_enabled_rdt_resource(r) {
                list_for_each_entry(dom, &r->domains, list)
-                       dom->have_new_ctrl = false;
+                       memset(dom->staged_config, 0, 
sizeof(dom->staged_config));
        }
 
        while ((tok = strsep(&buf, "\n")) != NULL) {
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 5950c30fcc30..0b57a55f4b3d 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -7,21 +7,29 @@
 #include <linux/list.h>
 #include <linux/kernel.h>
 
+/**
+ * struct resctrl_staged_config - parsed configuration to be applied
+ * @new_ctrl:          new ctrl value to be loaded
+ * @have_new_ctrl:     did user provide new_ctrl for this domain
+ */
+struct resctrl_staged_config {
+       u32                     new_ctrl;
+       bool                    have_new_ctrl;
+};
+
 /**
  * struct rdt_domain - group of cpus sharing an RDT resource
  * @list:      all instances of this resource
  * @id:                unique id for this instance
  * @cpu_mask:  which cpus share this resource
- * @new_ctrl:  new ctrl value to be loaded
- * @have_new_ctrl: did user provide new_ctrl for this domain
+ * @staged_config: parsed configuration to be applied
  */
 struct rdt_domain {
        struct list_head        list;
        int                     id;
        struct cpumask          cpu_mask;
 
-       u32                     new_ctrl;
-       bool                    have_new_ctrl;
+       struct resctrl_staged_config    staged_config[1];
 };
 
 /**
-- 
2.18.0

Reply via email to