Commit c377dcfb authored by Tony Luck's avatar Tony Luck Committed by Thomas Gleixner

x86/intel_rdt: Add diagnostics when writing the schemata file

Save helpful descriptions of what went wrong when writing a
schemata file.
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Vikas Shivappa <vikas.shivappa@intel.com>
Cc: Boris Petkov <bp@suse.de>
Cc: Reinette Chatre <reinette.chatre@intel.com>
Link: https://lkml.kernel.org/r/9d6cef757dc88639c8ab47f1e7bc1b081a84bb88.1506382469.git.tony.luck@intel.com
parent 9b3a7fd0
...@@ -42,15 +42,22 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) ...@@ -42,15 +42,22 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r)
/* /*
* Only linear delay values is supported for current Intel SKUs. * Only linear delay values is supported for current Intel SKUs.
*/ */
if (!r->membw.delay_linear) if (!r->membw.delay_linear) {
rdt_last_cmd_puts("No support for non-linear MB domains\n");
return false; return false;
}
ret = kstrtoul(buf, 10, &bw); ret = kstrtoul(buf, 10, &bw);
if (ret) if (ret) {
rdt_last_cmd_printf("Non-decimal digit in MB value %s\n", buf);
return false; return false;
}
if (bw < r->membw.min_bw || bw > r->default_ctrl) if (bw < r->membw.min_bw || bw > r->default_ctrl) {
rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw,
r->membw.min_bw, r->default_ctrl);
return false; return false;
}
*data = roundup(bw, (unsigned long)r->membw.bw_gran); *data = roundup(bw, (unsigned long)r->membw.bw_gran);
return true; return true;
...@@ -60,8 +67,10 @@ int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d) ...@@ -60,8 +67,10 @@ int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d)
{ {
unsigned long data; unsigned long data;
if (d->have_new_ctrl) if (d->have_new_ctrl) {
rdt_last_cmd_printf("duplicate domain %d\n", d->id);
return -EINVAL; return -EINVAL;
}
if (!bw_validate(buf, &data, r)) if (!bw_validate(buf, &data, r))
return -EINVAL; return -EINVAL;
...@@ -84,20 +93,29 @@ static bool cbm_validate(char *buf, unsigned long *data, struct rdt_resource *r) ...@@ -84,20 +93,29 @@ static bool cbm_validate(char *buf, unsigned long *data, struct rdt_resource *r)
int ret; int ret;
ret = kstrtoul(buf, 16, &val); ret = kstrtoul(buf, 16, &val);
if (ret) if (ret) {
rdt_last_cmd_printf("non-hex character in mask %s\n", buf);
return false; return false;
}
if (val == 0 || val > r->default_ctrl) if (val == 0 || val > r->default_ctrl) {
rdt_last_cmd_puts("mask out of range\n");
return false; return false;
}
first_bit = find_first_bit(&val, cbm_len); first_bit = find_first_bit(&val, cbm_len);
zero_bit = find_next_zero_bit(&val, cbm_len, first_bit); zero_bit = find_next_zero_bit(&val, cbm_len, first_bit);
if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len) if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len) {
rdt_last_cmd_printf("mask %lx has non-consecutive 1-bits\n", val);
return false; return false;
}
if ((zero_bit - first_bit) < r->cache.min_cbm_bits) if ((zero_bit - first_bit) < r->cache.min_cbm_bits) {
rdt_last_cmd_printf("Need at least %d bits in mask\n",
r->cache.min_cbm_bits);
return false; return false;
}
*data = val; *data = val;
return true; return true;
...@@ -111,8 +129,10 @@ int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d) ...@@ -111,8 +129,10 @@ int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d)
{ {
unsigned long data; unsigned long data;
if (d->have_new_ctrl) if (d->have_new_ctrl) {
rdt_last_cmd_printf("duplicate domain %d\n", d->id);
return -EINVAL; return -EINVAL;
}
if(!cbm_validate(buf, &data, r)) if(!cbm_validate(buf, &data, r))
return -EINVAL; return -EINVAL;
...@@ -139,8 +159,10 @@ static int parse_line(char *line, struct rdt_resource *r) ...@@ -139,8 +159,10 @@ static int parse_line(char *line, struct rdt_resource *r)
return 0; return 0;
dom = strsep(&line, ";"); dom = strsep(&line, ";");
id = strsep(&dom, "="); id = strsep(&dom, "=");
if (!dom || kstrtoul(id, 10, &dom_id)) if (!dom || kstrtoul(id, 10, &dom_id)) {
rdt_last_cmd_puts("Missing '=' or non-numeric domain\n");
return -EINVAL; return -EINVAL;
}
dom = strim(dom); dom = strim(dom);
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) {
...@@ -196,6 +218,7 @@ static int rdtgroup_parse_resource(char *resname, char *tok, int closid) ...@@ -196,6 +218,7 @@ static int rdtgroup_parse_resource(char *resname, char *tok, int closid)
if (!strcmp(resname, r->name) && closid < r->num_closid) if (!strcmp(resname, r->name) && closid < r->num_closid)
return parse_line(tok, r); return parse_line(tok, r);
} }
rdt_last_cmd_printf("unknown/unsupported resource name '%s'\n", resname);
return -EINVAL; return -EINVAL;
} }
...@@ -209,8 +232,10 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, ...@@ -209,8 +232,10 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
int closid, ret = 0; int closid, ret = 0;
/* Valid input requires a trailing newline */ /* Valid input requires a trailing newline */
if (nbytes == 0 || buf[nbytes - 1] != '\n') if (nbytes == 0 || buf[nbytes - 1] != '\n') {
seq_buf_puts(&last_cmd_status, "no trailing newline\n");
return -EINVAL; return -EINVAL;
}
buf[nbytes - 1] = '\0'; buf[nbytes - 1] = '\0';
rdtgrp = rdtgroup_kn_lock_live(of->kn); rdtgrp = rdtgroup_kn_lock_live(of->kn);
...@@ -218,6 +243,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, ...@@ -218,6 +243,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
rdtgroup_kn_unlock(of->kn); rdtgroup_kn_unlock(of->kn);
return -ENOENT; return -ENOENT;
} }
rdt_last_cmd_clear();
closid = rdtgrp->closid; closid = rdtgrp->closid;
...@@ -229,6 +255,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, ...@@ -229,6 +255,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
while ((tok = strsep(&buf, "\n")) != NULL) { while ((tok = strsep(&buf, "\n")) != NULL) {
resname = strim(strsep(&tok, ":")); resname = strim(strsep(&tok, ":"));
if (!tok) { if (!tok) {
rdt_last_cmd_puts("Missing ':'\n");
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment