提交 c6ea67de 编写于 作者: V Vikas Shivappa 提交者: Thomas Gleixner

x86/intel_rdt: Make schemata file parsers resource specific

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: NVikas 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.comSigned-off-by: NThomas Gleixner <tglx@linutronix.de>
上级 db69ef65
...@@ -152,6 +152,8 @@ struct rdt_membw { ...@@ -152,6 +152,8 @@ struct rdt_membw {
* @cache: Cache allocation related data * @cache: Cache allocation related data
* @info_files: resctrl info files for the resource * @info_files: resctrl info files for the resource
* @nr_info_files: Number of info files * @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 { struct rdt_resource {
bool enabled; bool enabled;
...@@ -171,10 +173,14 @@ struct rdt_resource { ...@@ -171,10 +173,14 @@ struct rdt_resource {
}; };
struct rftype *info_files; struct rftype *info_files;
int nr_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_cache_infofile(struct rdt_resource *r);
void rdt_get_mba_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; extern struct mutex rdtgroup_mutex;
......
...@@ -65,6 +65,8 @@ struct rdt_resource rdt_resources_all[] = { ...@@ -65,6 +65,8 @@ struct rdt_resource rdt_resources_all[] = {
.cbm_idx_mult = 1, .cbm_idx_mult = 1,
.cbm_idx_offset = 0, .cbm_idx_offset = 0,
}, },
.parse_ctrlval = parse_cbm,
.format_str = "%d=%0*x",
}, },
{ {
.name = "L3DATA", .name = "L3DATA",
...@@ -77,6 +79,8 @@ struct rdt_resource rdt_resources_all[] = { ...@@ -77,6 +79,8 @@ struct rdt_resource rdt_resources_all[] = {
.cbm_idx_mult = 2, .cbm_idx_mult = 2,
.cbm_idx_offset = 0, .cbm_idx_offset = 0,
}, },
.parse_ctrlval = parse_cbm,
.format_str = "%d=%0*x",
}, },
{ {
.name = "L3CODE", .name = "L3CODE",
...@@ -89,6 +93,8 @@ struct rdt_resource rdt_resources_all[] = { ...@@ -89,6 +93,8 @@ struct rdt_resource rdt_resources_all[] = {
.cbm_idx_mult = 2, .cbm_idx_mult = 2,
.cbm_idx_offset = 1, .cbm_idx_offset = 1,
}, },
.parse_ctrlval = parse_cbm,
.format_str = "%d=%0*x",
}, },
{ {
.name = "L2", .name = "L2",
...@@ -101,6 +107,8 @@ struct rdt_resource rdt_resources_all[] = { ...@@ -101,6 +107,8 @@ struct rdt_resource rdt_resources_all[] = {
.cbm_idx_mult = 1, .cbm_idx_mult = 1,
.cbm_idx_offset = 0, .cbm_idx_offset = 0,
}, },
.parse_ctrlval = parse_cbm,
.format_str = "%d=%0*x",
}, },
{ {
.name = "MB", .name = "MB",
......
...@@ -34,22 +34,29 @@ ...@@ -34,22 +34,29 @@
* are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.). * are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.).
* Additionally Haswell requires at least two bits set. * 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; 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; return false;
first_bit = find_first_bit(&var, cbm_len); first_bit = find_first_bit(&val, cbm_len);
zero_bit = find_next_zero_bit(&var, cbm_len, first_bit); 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; return false;
if ((zero_bit - first_bit) < r->cache.min_cbm_bits) if ((zero_bit - first_bit) < r->cache.min_cbm_bits)
return false; return false;
*data = val;
return true; return true;
} }
...@@ -57,18 +64,14 @@ static bool cbm_validate(unsigned long var, struct rdt_resource *r) ...@@ -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 * Read one cache bit mask (hex). Check that it is valid for the current
* resource type. * 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; unsigned long data;
int ret;
if (d->have_new_ctrl) if (d->have_new_ctrl)
return -EINVAL; return -EINVAL;
ret = kstrtoul(buf, 16, &data); if(!cbm_validate(buf, &data, r))
if (ret)
return ret;
if (!cbm_validate(data, r))
return -EINVAL; return -EINVAL;
d->new_ctrl = data; d->new_ctrl = data;
d->have_new_ctrl = true; d->have_new_ctrl = true;
...@@ -97,7 +100,7 @@ static int parse_line(char *line, struct rdt_resource *r) ...@@ -97,7 +100,7 @@ static int parse_line(char *line, struct rdt_resource *r)
return -EINVAL; return -EINVAL;
list_for_each_entry(d, &r->domains, list) { list_for_each_entry(d, &r->domains, list) {
if (d->id == dom_id) { if (d->id == dom_id) {
if (parse_cbm(dom, r, d)) if (r->parse_ctrlval(dom, r, d))
return -EINVAL; return -EINVAL;
goto next; goto next;
} }
...@@ -208,7 +211,7 @@ static void show_doms(struct seq_file *s, struct rdt_resource *r, int closid) ...@@ -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) { list_for_each_entry(dom, &r->domains, list) {
if (sep) if (sep)
seq_puts(s, ";"); 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]); dom->ctrl_val[closid]);
sep = true; sep = true;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册