x86/intel_rdt: Make schemata file parsers resource specific
authorVikas Shivappa <vikas.shivappa@linux.intel.com>
Sat, 8 Apr 2017 00:33:56 +0000 (17:33 -0700)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 14 Apr 2017 14:10:09 +0000 (16:10 +0200)
The schemata files are the user space interface to update resource
controls. The parser is hardwired to support only cache resources, which do
not fit the requirements of memory resources.

Add a function pointer for a parser to the struct rdt_resource and switch
the cache parsing over.

[ tglx: Massaged changelog ]

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
Cc: ravi.v.shankar@intel.com
Cc: tony.luck@intel.com
Cc: fenghua.yu@intel.com
Cc: vikas.shivappa@intel.com
Link: http://lkml.kernel.org/r/1491611637-20417-8-git-send-email-vikas.shivappa@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/include/asm/intel_rdt.h
arch/x86/kernel/cpu/intel_rdt.c
arch/x86/kernel/cpu/intel_rdt_schemata.c

index 167fe10f00b928ac3a9090f61c827631a0a9ec06..4a9005766d9670e42bf5387a6a497f2524b5d2cb 100644 (file)
@@ -152,6 +152,8 @@ struct rdt_membw {
  * @cache:             Cache allocation related data
  * @info_files:                resctrl info files for the resource
  * @nr_info_files:     Number of info files
+ * @format_str:                Per resource format string to show domain value
+ * @parse_ctrlval:     Per resource function pointer to parse control values
  */
 struct rdt_resource {
        bool                    enabled;
@@ -171,10 +173,14 @@ struct rdt_resource {
        };
        struct rftype           *info_files;
        int                     nr_info_files;
+       const char              *format_str;
+       int (*parse_ctrlval)    (char *buf, struct rdt_resource *r,
+                                struct rdt_domain *d);
 };
 
 void rdt_get_cache_infofile(struct rdt_resource *r);
 void rdt_get_mba_infofile(struct rdt_resource *r);
+int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d);
 
 extern struct mutex rdtgroup_mutex;
 
index 438efefd686250ff5a2bfa39e1c3f4afe5c7d1ca..1e410ea6905e8244ef29b1a7281dba31721e84c5 100644 (file)
@@ -65,6 +65,8 @@ struct rdt_resource rdt_resources_all[] = {
                        .cbm_idx_mult   = 1,
                        .cbm_idx_offset = 0,
                },
+               .parse_ctrlval          = parse_cbm,
+               .format_str             = "%d=%0*x",
        },
        {
                .name                   = "L3DATA",
@@ -77,6 +79,8 @@ struct rdt_resource rdt_resources_all[] = {
                        .cbm_idx_mult   = 2,
                        .cbm_idx_offset = 0,
                },
+               .parse_ctrlval          = parse_cbm,
+               .format_str             = "%d=%0*x",
        },
        {
                .name                   = "L3CODE",
@@ -89,6 +93,8 @@ struct rdt_resource rdt_resources_all[] = {
                        .cbm_idx_mult   = 2,
                        .cbm_idx_offset = 1,
                },
+               .parse_ctrlval          = parse_cbm,
+               .format_str             = "%d=%0*x",
        },
        {
                .name                   = "L2",
@@ -101,6 +107,8 @@ struct rdt_resource rdt_resources_all[] = {
                        .cbm_idx_mult   = 1,
                        .cbm_idx_offset = 0,
                },
+               .parse_ctrlval          = parse_cbm,
+               .format_str             = "%d=%0*x",
        },
        {
                .name                   = "MB",
index 5097ac65d00200a1d90aefd8a29286bc7a41397d..c72c9cc17aac89fc77aaf986d0b60df9bd894b34 100644 (file)
  *     are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.).
  * Additionally Haswell requires at least two bits set.
  */
-static bool cbm_validate(unsigned long var, struct rdt_resource *r)
+static bool cbm_validate(char *buf, unsigned long *data, struct rdt_resource *r)
 {
-       unsigned long first_bit, zero_bit;
+       unsigned long first_bit, zero_bit, val;
        unsigned int cbm_len = r->cache.cbm_len;
+       int ret;
+
+       ret = kstrtoul(buf, 16, &val);
+       if (ret)
+               return false;
 
-       if (var == 0 || var > r->default_ctrl)
+       if (val == 0 || val > r->default_ctrl)
                return false;
 
-       first_bit = find_first_bit(&var, cbm_len);
-       zero_bit = find_next_zero_bit(&var, cbm_len, first_bit);
+       first_bit = find_first_bit(&val, cbm_len);
+       zero_bit = find_next_zero_bit(&val, cbm_len, first_bit);
 
-       if (find_next_bit(&var, cbm_len, zero_bit) < cbm_len)
+       if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len)
                return false;
 
        if ((zero_bit - first_bit) < r->cache.min_cbm_bits)
                return false;
+
+       *data = val;
        return true;
 }
 
@@ -57,18 +64,14 @@ static bool cbm_validate(unsigned long var, struct rdt_resource *r)
  * Read one cache bit mask (hex). Check that it is valid for the current
  * resource type.
  */
-static int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d)
+int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d)
 {
        unsigned long data;
-       int ret;
 
        if (d->have_new_ctrl)
                return -EINVAL;
 
-       ret = kstrtoul(buf, 16, &data);
-       if (ret)
-               return ret;
-       if (!cbm_validate(data, r))
+       if(!cbm_validate(buf, &data, r))
                return -EINVAL;
        d->new_ctrl = data;
        d->have_new_ctrl = true;
@@ -97,7 +100,7 @@ next:
                return -EINVAL;
        list_for_each_entry(d, &r->domains, list) {
                if (d->id == dom_id) {
-                       if (parse_cbm(dom, r, d))
+                       if (r->parse_ctrlval(dom, r, d))
                                return -EINVAL;
                        goto next;
                }
@@ -208,7 +211,7 @@ static void show_doms(struct seq_file *s, struct rdt_resource *r, int closid)
        list_for_each_entry(dom, &r->domains, list) {
                if (sep)
                        seq_puts(s, ";");
-               seq_printf(s, "%d=%0*x", dom->id, max_data_width,
+               seq_printf(s, r->format_str, dom->id, max_data_width,
                           dom->ctrl_val[closid]);
                sep = true;
        }