[RFC PATCH 11/20] x86/intel_rdt: Pass in the code/data/both configuration value when parsing

From: James Morse
Date: Fri Aug 24 2018 - 06:47:14 EST


The illusion of three types of cache at each level is a neat trick to
allow a static table of resources to be used. This is a problem if the
cache topology and partitioning abilities have to be discovered at boot.

We want to fold the three code/data/both caches into one, and move the
CDP configuration details to be a property of the configuration and
its closid, not the cache. The resctrl filesystem can then re-create
the illusion of separate caches.

Temporarily label the configuration property of the cache, and pass
this value down to the configuration helpers. Eventually we will move
this label up to become a property of the schema.

A later patch will correct the closid for CDP when the configuration is
staged, which will let us merge the three types of resource.

Signed-off-by: James Morse <james.morse@xxxxxxx>
---
arch/x86/kernel/cpu/intel_rdt.c | 6 ++++++
arch/x86/kernel/cpu/intel_rdt.h | 7 +++++--
arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c | 15 ++++++++++-----
include/linux/resctrl.h | 11 ++++++++++-
4 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c
index c035280b4398..8d3544b6c149 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -83,6 +83,7 @@ struct rdt_hw_resource rdt_resources_all[] = {
.format_str = "%d=%0*x",
.fflags = RFTYPE_RES_CACHE,
},
+ .cdp_type = CDP_BOTH,
.msr_base = IA32_L3_CBM_BASE,
.msr_update = cat_wrmsr,
},
@@ -102,6 +103,7 @@ struct rdt_hw_resource rdt_resources_all[] = {
.format_str = "%d=%0*x",
.fflags = RFTYPE_RES_CACHE,
},
+ .cdp_type = CDP_DATA,
.msr_base = IA32_L3_CBM_BASE,
.msr_update = cat_wrmsr,

@@ -122,6 +124,7 @@ struct rdt_hw_resource rdt_resources_all[] = {
.format_str = "%d=%0*x",
.fflags = RFTYPE_RES_CACHE,
},
+ .cdp_type = CDP_CODE,
.msr_base = IA32_L3_CBM_BASE,
.msr_update = cat_wrmsr,
},
@@ -141,6 +144,7 @@ struct rdt_hw_resource rdt_resources_all[] = {
.format_str = "%d=%0*x",
.fflags = RFTYPE_RES_CACHE,
},
+ .cdp_type = CDP_BOTH,
.msr_base = IA32_L2_CBM_BASE,
.msr_update = cat_wrmsr,
},
@@ -160,6 +164,7 @@ struct rdt_hw_resource rdt_resources_all[] = {
.format_str = "%d=%0*x",
.fflags = RFTYPE_RES_CACHE,
},
+ .cdp_type = CDP_DATA,
.msr_base = IA32_L2_CBM_BASE,
.msr_update = cat_wrmsr,
},
@@ -179,6 +184,7 @@ struct rdt_hw_resource rdt_resources_all[] = {
.format_str = "%d=%0*x",
.fflags = RFTYPE_RES_CACHE,
},
+ .cdp_type = CDP_CODE,
.msr_base = IA32_L2_CBM_BASE,
.msr_update = cat_wrmsr,
},
diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h
index 92822ff99f1a..cc8dea58b74f 100644
--- a/arch/x86/kernel/cpu/intel_rdt.h
+++ b/arch/x86/kernel/cpu/intel_rdt.h
@@ -285,6 +285,7 @@ struct rdt_hw_resource {
struct rdt_resource resctrl;
int rid;
u32 hw_num_closid;
+ enum resctrl_conf_type cdp_type; // temporary
unsigned int msr_base;
void (*msr_update) (struct rdt_domain *d, struct msr_param *m,
struct rdt_resource *r);
@@ -296,8 +297,10 @@ static inline struct rdt_hw_resource *resctrl_to_rdt(struct rdt_resource *r)
return container_of(r, struct rdt_hw_resource, resctrl);
}

-int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d, u32 closid);
-int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d, u32 closid);
+int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d,
+ enum resctrl_conf_type t, u32 closid);
+int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d,
+ enum resctrl_conf_type t, u32 closid);

extern struct mutex rdtgroup_mutex;

diff --git a/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
index 766c3e62ad91..bab6032704c3 100644
--- a/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
+++ b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
@@ -64,7 +64,8 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r)
return true;
}

-int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d, u32 closid)
+int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d,
+ enum resctrl_conf_type t, u32 closid)
{
unsigned long data;
struct resctrl_staged_config *cfg = &d->staged_config[0];
@@ -78,6 +79,7 @@ int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d, u32 closid
return -EINVAL;
cfg->closid = closid;
cfg->new_ctrl = data;
+ cfg->new_ctrl_type = t;
cfg->have_new_ctrl = true;

return 0;
@@ -128,7 +130,8 @@ static bool cbm_validate(char *buf, unsigned long *data, struct rdt_resource *r)
* Read one cache bit mask (hex). Check that it is valid for the current
* resource type.
*/
-int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d, u32 closid)
+int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d,
+ enum resctrl_conf_type t, u32 closid)
{
unsigned long data;
struct resctrl_staged_config *cfg = &d->staged_config[0];
@@ -142,6 +145,7 @@ int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d, u32 closi
return -EINVAL;
cfg->closid = closid;
cfg->new_ctrl = data;
+ cfg->new_ctrl_type = t;
cfg->have_new_ctrl = true;

return 0;
@@ -153,7 +157,8 @@ int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d, u32 closi
* separated by ";". The "id" is in decimal, and must match one of
* the "id"s for this resource.
*/
-static int parse_line(char *line, struct rdt_resource *r, u32 closid)
+static int parse_line(char *line, struct rdt_resource *r,
+ enum resctrl_conf_type t, u32 closid)
{
char *dom = NULL, *id;
struct rdt_domain *d;
@@ -171,7 +176,7 @@ static int parse_line(char *line, struct rdt_resource *r, u32 closid)
dom = strim(dom);
list_for_each_entry(d, &r->domains, list) {
if (d->id == dom_id) {
- if (r->parse_ctrlval(dom, r, d, closid))
+ if (r->parse_ctrlval(dom, r, d, t, closid))
return -EINVAL;
goto next;
}
@@ -260,7 +265,7 @@ static int rdtgroup_parse_resource(char *resname, char *tok, int closid)

for_each_alloc_enabled_rdt_resource(r) {
if (!strcmp(resname, r->name) && closid < r->num_closid)
- return parse_line(tok, r, closid);
+ return parse_line(tok, r, resctrl_to_rdt(r)->cdp_type, closid);
}
rdt_last_cmd_printf("unknown/unsupported resource name '%s'\n", resname);
return -EINVAL;
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 8bf813071039..592242635204 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -7,16 +7,24 @@
#include <linux/list.h>
#include <linux/kernel.h>

+enum resctrl_conf_type {
+ CDP_BOTH = 0,
+ CDP_CODE,
+ CDP_DATA,
+};
+
/**
* struct resctrl_staged_config - parsed configuration to be applied
* @closid: The closid the new configuration applies to
* @new_ctrl: new ctrl value to be loaded
* @have_new_ctrl: did user provide new_ctrl for this domain
+ * @new_ctrl_type: CDP property of the new ctrl
*/
struct resctrl_staged_config {
u32 closid;
u32 new_ctrl;
bool have_new_ctrl;
+ enum resctrl_conf_type new_ctrl_type;
};

/**
@@ -122,7 +130,8 @@ struct rdt_resource {
u32 default_ctrl;
const char *format_str;
int (*parse_ctrlval) (char *buf, struct rdt_resource *r,
- struct rdt_domain *d, u32 closid);
+ struct rdt_domain *d,
+ enum resctrl_conf_type t, u32 closid);

struct list_head evt_list;
unsigned long fflags;
--
2.18.0