aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2017-09-25 19:39:34 -0400
committerThomas Gleixner <tglx@linutronix.de>2017-09-27 06:10:10 -0400
commitc377dcfbee808efdb66cf1bb6b9f06fa26b2ad0a (patch)
treea308012b2c66a87261d3cbc21acd0c0aa0986f6b
parent9b3a7fd0f5fb583a8fdda678e8a87dff1717f7f3 (diff)
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: Tony Luck <tony.luck@intel.com> Signed-off-by: Thomas 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
-rw-r--r--arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
index f6ea94f8954a..f29b4c21e7d4 100644
--- a/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
+++ b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
@@ -42,15 +42,22 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r)
42 /* 42 /*
43 * Only linear delay values is supported for current Intel SKUs. 43 * Only linear delay values is supported for current Intel SKUs.
44 */ 44 */
45 if (!r->membw.delay_linear) 45 if (!r->membw.delay_linear) {
46 rdt_last_cmd_puts("No support for non-linear MB domains\n");
46 return false; 47 return false;
48 }
47 49
48 ret = kstrtoul(buf, 10, &bw); 50 ret = kstrtoul(buf, 10, &bw);
49 if (ret) 51 if (ret) {
52 rdt_last_cmd_printf("Non-decimal digit in MB value %s\n", buf);
50 return false; 53 return false;
54 }
51 55
52 if (bw < r->membw.min_bw || bw > r->default_ctrl) 56 if (bw < r->membw.min_bw || bw > r->default_ctrl) {
57 rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw,
58 r->membw.min_bw, r->default_ctrl);
53 return false; 59 return false;
60 }
54 61
55 *data = roundup(bw, (unsigned long)r->membw.bw_gran); 62 *data = roundup(bw, (unsigned long)r->membw.bw_gran);
56 return true; 63 return true;
@@ -60,8 +67,10 @@ int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d)
60{ 67{
61 unsigned long data; 68 unsigned long data;
62 69
63 if (d->have_new_ctrl) 70 if (d->have_new_ctrl) {
71 rdt_last_cmd_printf("duplicate domain %d\n", d->id);
64 return -EINVAL; 72 return -EINVAL;
73 }
65 74
66 if (!bw_validate(buf, &data, r)) 75 if (!bw_validate(buf, &data, r))
67 return -EINVAL; 76 return -EINVAL;
@@ -84,20 +93,29 @@ static bool cbm_validate(char *buf, unsigned long *data, struct rdt_resource *r)
84 int ret; 93 int ret;
85 94
86 ret = kstrtoul(buf, 16, &val); 95 ret = kstrtoul(buf, 16, &val);
87 if (ret) 96 if (ret) {
97 rdt_last_cmd_printf("non-hex character in mask %s\n", buf);
88 return false; 98 return false;
99 }
89 100
90 if (val == 0 || val > r->default_ctrl) 101 if (val == 0 || val > r->default_ctrl) {
102 rdt_last_cmd_puts("mask out of range\n");
91 return false; 103 return false;
104 }
92 105
93 first_bit = find_first_bit(&val, cbm_len); 106 first_bit = find_first_bit(&val, cbm_len);
94 zero_bit = find_next_zero_bit(&val, cbm_len, first_bit); 107 zero_bit = find_next_zero_bit(&val, cbm_len, first_bit);
95 108
96 if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len) 109 if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len) {
110 rdt_last_cmd_printf("mask %lx has non-consecutive 1-bits\n", val);
97 return false; 111 return false;
112 }
98 113
99 if ((zero_bit - first_bit) < r->cache.min_cbm_bits) 114 if ((zero_bit - first_bit) < r->cache.min_cbm_bits) {
115 rdt_last_cmd_printf("Need at least %d bits in mask\n",
116 r->cache.min_cbm_bits);
100 return false; 117 return false;
118 }
101 119
102 *data = val; 120 *data = val;
103 return true; 121 return true;
@@ -111,8 +129,10 @@ int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d)
111{ 129{
112 unsigned long data; 130 unsigned long data;
113 131
114 if (d->have_new_ctrl) 132 if (d->have_new_ctrl) {
133 rdt_last_cmd_printf("duplicate domain %d\n", d->id);
115 return -EINVAL; 134 return -EINVAL;
135 }
116 136
117 if(!cbm_validate(buf, &data, r)) 137 if(!cbm_validate(buf, &data, r))
118 return -EINVAL; 138 return -EINVAL;
@@ -139,8 +159,10 @@ next:
139 return 0; 159 return 0;
140 dom = strsep(&line, ";"); 160 dom = strsep(&line, ";");
141 id = strsep(&dom, "="); 161 id = strsep(&dom, "=");
142 if (!dom || kstrtoul(id, 10, &dom_id)) 162 if (!dom || kstrtoul(id, 10, &dom_id)) {
163 rdt_last_cmd_puts("Missing '=' or non-numeric domain\n");
143 return -EINVAL; 164 return -EINVAL;
165 }
144 dom = strim(dom); 166 dom = strim(dom);
145 list_for_each_entry(d, &r->domains, list) { 167 list_for_each_entry(d, &r->domains, list) {
146 if (d->id == dom_id) { 168 if (d->id == dom_id) {
@@ -196,6 +218,7 @@ static int rdtgroup_parse_resource(char *resname, char *tok, int closid)
196 if (!strcmp(resname, r->name) && closid < r->num_closid) 218 if (!strcmp(resname, r->name) && closid < r->num_closid)
197 return parse_line(tok, r); 219 return parse_line(tok, r);
198 } 220 }
221 rdt_last_cmd_printf("unknown/unsupported resource name '%s'\n", resname);
199 return -EINVAL; 222 return -EINVAL;
200} 223}
201 224
@@ -209,8 +232,10 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
209 int closid, ret = 0; 232 int closid, ret = 0;
210 233
211 /* Valid input requires a trailing newline */ 234 /* Valid input requires a trailing newline */
212 if (nbytes == 0 || buf[nbytes - 1] != '\n') 235 if (nbytes == 0 || buf[nbytes - 1] != '\n') {
236 seq_buf_puts(&last_cmd_status, "no trailing newline\n");
213 return -EINVAL; 237 return -EINVAL;
238 }
214 buf[nbytes - 1] = '\0'; 239 buf[nbytes - 1] = '\0';
215 240
216 rdtgrp = rdtgroup_kn_lock_live(of->kn); 241 rdtgrp = rdtgroup_kn_lock_live(of->kn);
@@ -218,6 +243,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
218 rdtgroup_kn_unlock(of->kn); 243 rdtgroup_kn_unlock(of->kn);
219 return -ENOENT; 244 return -ENOENT;
220 } 245 }
246 rdt_last_cmd_clear();
221 247
222 closid = rdtgrp->closid; 248 closid = rdtgrp->closid;
223 249
@@ -229,6 +255,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
229 while ((tok = strsep(&buf, "\n")) != NULL) { 255 while ((tok = strsep(&buf, "\n")) != NULL) {
230 resname = strim(strsep(&tok, ":")); 256 resname = strim(strsep(&tok, ":"));
231 if (!tok) { 257 if (!tok) {
258 rdt_last_cmd_puts("Missing ':'\n");
232 ret = -EINVAL; 259 ret = -EINVAL;
233 goto out; 260 goto out;
234 } 261 }