[PATCH 7/8] x86/intel_rdt: Prep to add schemata file for MBA
From: Vikas Shivappa
Date: Mon Apr 03 2017 - 17:57:25 EST
User updates RDT resource controls by updating the schemata file. OS
then parses these updates and updates the corresponding QOS_MSRs.
However the parsing and MSR update functions are specific to cache
resource type and do not support memory resource type.
Define resource specific function pointers to dynamically choose such
functions in order to prepare to add MBA support.
Signed-off-by: Vikas Shivappa <vikas.shivappa@xxxxxxxxxxxxxxx>
---
arch/x86/include/asm/intel_rdt.h | 8 +++++++-
arch/x86/kernel/cpu/intel_rdt.c | 16 ++++++++++------
arch/x86/kernel/cpu/intel_rdt_schemata.c | 23 +++++++++++++----------
3 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h
index b42fba5..6fc82a3 100644
--- a/arch/x86/include/asm/intel_rdt.h
+++ b/arch/x86/include/asm/intel_rdt.h
@@ -109,6 +109,9 @@ struct msr_param {
* @data_width: Character width of data when displaying
* @min_cbm_bits: Minimum number of consecutive bits to be set
* in a cache bit mask
+ * @format_str: Per resource format string to show domain value
+ * @parse_ctrlval: Per resource function pointer to parse
+ * the ctrl values
* @msr_update: Function pointer to update QOS MSRs
* @info_files: resctrl info files for the resource
* @nr_info_files: Number of info files
@@ -137,6 +140,9 @@ struct rdt_resource {
int min_cbm_bits;
u32 default_ctrl;
int data_width;
+ const char *format_str;
+ int (*parse_ctrlval) (char *buf, struct rdt_resource *r,
+ struct rdt_domain *d);
void (*msr_update) (struct rdt_domain *d, struct msr_param *m,
struct rdt_resource *r);
struct rftype *info_files;
@@ -146,7 +152,6 @@ struct rdt_resource {
u32 bw_gran;
u32 delay_linear;
u32 *mb_map;
-
struct list_head domains;
int msr_base;
int cache_level;
@@ -156,6 +161,7 @@ struct rdt_resource {
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 fd65548..2c18142 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -58,7 +58,9 @@ struct rdt_resource rdt_resources_all[] = {
.name = "L3",
.domains = domain_init(RDT_RESOURCE_L3),
.msr_base = IA32_L3_CBM_BASE,
+ .parse_ctrlval = parse_cbm,
.msr_update = cqm_wrmsr,
+ .format_str = "%d=%0*x",
.min_cbm_bits = 1,
.cache_level = 3,
.cbm_idx_multi = 1,
@@ -68,7 +70,9 @@ struct rdt_resource rdt_resources_all[] = {
.name = "L3DATA",
.domains = domain_init(RDT_RESOURCE_L3DATA),
.msr_base = IA32_L3_CBM_BASE,
+ .parse_ctrlval = parse_cbm,
.msr_update = cqm_wrmsr,
+ .format_str = "%d=%0*x",
.min_cbm_bits = 1,
.cache_level = 3,
.cbm_idx_multi = 2,
@@ -78,7 +82,9 @@ struct rdt_resource rdt_resources_all[] = {
.name = "L3CODE",
.domains = domain_init(RDT_RESOURCE_L3CODE),
.msr_base = IA32_L3_CBM_BASE,
+ .parse_ctrlval = parse_cbm,
.msr_update = cqm_wrmsr,
+ .format_str = "%d=%0*x",
.min_cbm_bits = 1,
.cache_level = 3,
.cbm_idx_multi = 2,
@@ -88,7 +94,9 @@ struct rdt_resource rdt_resources_all[] = {
.name = "L2",
.domains = domain_init(RDT_RESOURCE_L2),
.msr_base = IA32_L2_CBM_BASE,
+ .parse_ctrlval = parse_cbm,
.msr_update = cqm_wrmsr,
+ .format_str = "%d=%0*x",
.min_cbm_bits = 1,
.cache_level = 2,
.cbm_idx_multi = 1,
@@ -349,7 +357,7 @@ void rdt_ctrl_update(void *arg)
{
struct msr_param *m = (struct msr_param *)arg;
struct rdt_resource *r = m->res;
- int i, cpu = smp_processor_id();
+ int cpu = smp_processor_id();
struct rdt_domain *d;
list_for_each_entry(d, &r->domains, list) {
@@ -363,11 +371,7 @@ void rdt_ctrl_update(void *arg)
return;
found:
- for (i = m->low; i < m->high; i++) {
- int idx = cbm_idx(r, i);
-
- wrmsrl(r->msr_base + idx, d->ctrl_val[i]);
- }
+ r->msr_update(d, m, r);
}
/*
diff --git a/arch/x86/kernel/cpu/intel_rdt_schemata.c b/arch/x86/kernel/cpu/intel_rdt_schemata.c
index 7695179..03f9a70 100644
--- a/arch/x86/kernel/cpu/intel_rdt_schemata.c
+++ b/arch/x86/kernel/cpu/intel_rdt_schemata.c
@@ -34,9 +34,14 @@
* 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, var;
+ int ret;
+
+ ret = kstrtoul(buf, 16, &var);
+ if (ret)
+ return false;
if (var == 0 || var > r->default_ctrl)
return false;
@@ -49,6 +54,8 @@ static bool cbm_validate(unsigned long var, struct rdt_resource *r)
if ((zero_bit - first_bit) < r->min_cbm_bits)
return false;
+
+ *data = var;
return true;
}
@@ -56,18 +63,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;
@@ -96,7 +99,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;
}
@@ -207,7 +210,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;
}
--
1.9.1