diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h index 167fe10f00b928ac3a9090f61c827631a0a9ec06..4a9005766d9670e42bf5387a6a497f2524b5d2cb 100644 --- a/arch/x86/include/asm/intel_rdt.h +++ b/arch/x86/include/asm/intel_rdt.h @@ -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; diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index 438efefd686250ff5a2bfa39e1c3f4afe5c7d1ca..1e410ea6905e8244ef29b1a7281dba31721e84c5 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c @@ -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", diff --git a/arch/x86/kernel/cpu/intel_rdt_schemata.c b/arch/x86/kernel/cpu/intel_rdt_schemata.c index 5097ac65d00200a1d90aefd8a29286bc7a41397d..c72c9cc17aac89fc77aaf986d0b60df9bd894b34 100644 --- a/arch/x86/kernel/cpu/intel_rdt_schemata.c +++ b/arch/x86/kernel/cpu/intel_rdt_schemata.c @@ -34,22 +34,29 @@ * 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 @@ static int parse_line(char *line, struct rdt_resource *r) 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; }