1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Resource Director Technology(RDT) 4 * - Cache Allocation code. 5 * 6 * Copyright (C) 2016 Intel Corporation 7 * 8 * Authors: 9 * Fenghua Yu <fenghua.yu@intel.com> 10 * Tony Luck <tony.luck@intel.com> 11 * 12 * More information about RDT be found in the Intel (R) x86 Architecture 13 * Software Developer Manual June 2016, volume 3, section 17.17. 14 */ 15 16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 18 #include <linux/cpu.h> 19 #include <linux/kernfs.h> 20 #include <linux/seq_file.h> 21 #include <linux/slab.h> 22 #include "internal.h" 23 24 /* 25 * Check whether MBA bandwidth percentage value is correct. The value is 26 * checked against the minimum and max bandwidth values specified by the 27 * hardware. The allocated bandwidth percentage is rounded to the next 28 * control step available on the hardware. 29 */ 30 static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) 31 { 32 unsigned long bw; 33 int ret; 34 35 /* 36 * Only linear delay values is supported for current Intel SKUs. 37 */ 38 if (!r->membw.delay_linear && r->membw.arch_needs_linear) { 39 rdt_last_cmd_puts("No support for non-linear MB domains\n"); 40 return false; 41 } 42 43 ret = kstrtoul(buf, 10, &bw); 44 if (ret) { 45 rdt_last_cmd_printf("Non-decimal digit in MB value %s\n", buf); 46 return false; 47 } 48 49 if ((bw < r->membw.min_bw || bw > r->default_ctrl) && 50 !is_mba_sc(r)) { 51 rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw, 52 r->membw.min_bw, r->default_ctrl); 53 return false; 54 } 55 56 *data = roundup(bw, (unsigned long)r->membw.bw_gran); 57 return true; 58 } 59 60 int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s, 61 struct rdt_domain *d) 62 { 63 struct resctrl_staged_config *cfg; 64 u32 closid = data->rdtgrp->closid; 65 struct rdt_resource *r = s->res; 66 unsigned long bw_val; 67 68 cfg = &d->staged_config[s->conf_type]; 69 if (cfg->have_new_ctrl) { 70 rdt_last_cmd_printf("Duplicate domain %d\n", d->id); 71 return -EINVAL; 72 } 73 74 if (!bw_validate(data->buf, &bw_val, r)) 75 return -EINVAL; 76 77 if (is_mba_sc(r)) { 78 d->mbps_val[closid] = bw_val; 79 return 0; 80 } 81 82 cfg->new_ctrl = bw_val; 83 cfg->have_new_ctrl = true; 84 85 return 0; 86 } 87 88 /* 89 * Check whether a cache bit mask is valid. 90 * For Intel the SDM says: 91 * Please note that all (and only) contiguous '1' combinations 92 * are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.). 93 * Additionally Haswell requires at least two bits set. 94 * AMD allows non-contiguous bitmasks. 95 */ 96 static bool cbm_validate(char *buf, u32 *data, struct rdt_resource *r) 97 { 98 unsigned long first_bit, zero_bit, val; 99 unsigned int cbm_len = r->cache.cbm_len; 100 int ret; 101 102 ret = kstrtoul(buf, 16, &val); 103 if (ret) { 104 rdt_last_cmd_printf("Non-hex character in the mask %s\n", buf); 105 return false; 106 } 107 108 if ((r->cache.min_cbm_bits > 0 && val == 0) || val > r->default_ctrl) { 109 rdt_last_cmd_puts("Mask out of range\n"); 110 return false; 111 } 112 113 first_bit = find_first_bit(&val, cbm_len); 114 zero_bit = find_next_zero_bit(&val, cbm_len, first_bit); 115 116 /* Are non-contiguous bitmaps allowed? */ 117 if (!r->cache.arch_has_sparse_bitmaps && 118 (find_next_bit(&val, cbm_len, zero_bit) < cbm_len)) { 119 rdt_last_cmd_printf("The mask %lx has non-consecutive 1-bits\n", val); 120 return false; 121 } 122 123 if ((zero_bit - first_bit) < r->cache.min_cbm_bits) { 124 rdt_last_cmd_printf("Need at least %d bits in the mask\n", 125 r->cache.min_cbm_bits); 126 return false; 127 } 128 129 *data = val; 130 return true; 131 } 132 133 /* 134 * Read one cache bit mask (hex). Check that it is valid for the current 135 * resource type. 136 */ 137 int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s, 138 struct rdt_domain *d) 139 { 140 struct rdtgroup *rdtgrp = data->rdtgrp; 141 struct resctrl_staged_config *cfg; 142 struct rdt_resource *r = s->res; 143 u32 cbm_val; 144 145 cfg = &d->staged_config[s->conf_type]; 146 if (cfg->have_new_ctrl) { 147 rdt_last_cmd_printf("Duplicate domain %d\n", d->id); 148 return -EINVAL; 149 } 150 151 /* 152 * Cannot set up more than one pseudo-locked region in a cache 153 * hierarchy. 154 */ 155 if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP && 156 rdtgroup_pseudo_locked_in_hierarchy(d)) { 157 rdt_last_cmd_puts("Pseudo-locked region in hierarchy\n"); 158 return -EINVAL; 159 } 160 161 if (!cbm_validate(data->buf, &cbm_val, r)) 162 return -EINVAL; 163 164 if ((rdtgrp->mode == RDT_MODE_EXCLUSIVE || 165 rdtgrp->mode == RDT_MODE_SHAREABLE) && 166 rdtgroup_cbm_overlaps_pseudo_locked(d, cbm_val)) { 167 rdt_last_cmd_puts("CBM overlaps with pseudo-locked region\n"); 168 return -EINVAL; 169 } 170 171 /* 172 * The CBM may not overlap with the CBM of another closid if 173 * either is exclusive. 174 */ 175 if (rdtgroup_cbm_overlaps(s, d, cbm_val, rdtgrp->closid, true)) { 176 rdt_last_cmd_puts("Overlaps with exclusive group\n"); 177 return -EINVAL; 178 } 179 180 if (rdtgroup_cbm_overlaps(s, d, cbm_val, rdtgrp->closid, false)) { 181 if (rdtgrp->mode == RDT_MODE_EXCLUSIVE || 182 rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) { 183 rdt_last_cmd_puts("Overlaps with other group\n"); 184 return -EINVAL; 185 } 186 } 187 188 cfg->new_ctrl = cbm_val; 189 cfg->have_new_ctrl = true; 190 191 return 0; 192 } 193 194 /* 195 * For each domain in this resource we expect to find a series of: 196 * id=mask 197 * separated by ";". The "id" is in decimal, and must match one of 198 * the "id"s for this resource. 199 */ 200 static int parse_line(char *line, struct resctrl_schema *s, 201 struct rdtgroup *rdtgrp) 202 { 203 enum resctrl_conf_type t = s->conf_type; 204 struct resctrl_staged_config *cfg; 205 struct rdt_resource *r = s->res; 206 struct rdt_parse_data data; 207 char *dom = NULL, *id; 208 struct rdt_domain *d; 209 unsigned long dom_id; 210 211 if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP && 212 (r->rid == RDT_RESOURCE_MBA || r->rid == RDT_RESOURCE_SMBA)) { 213 rdt_last_cmd_puts("Cannot pseudo-lock MBA resource\n"); 214 return -EINVAL; 215 } 216 217 next: 218 if (!line || line[0] == '\0') 219 return 0; 220 dom = strsep(&line, ";"); 221 id = strsep(&dom, "="); 222 if (!dom || kstrtoul(id, 10, &dom_id)) { 223 rdt_last_cmd_puts("Missing '=' or non-numeric domain\n"); 224 return -EINVAL; 225 } 226 dom = strim(dom); 227 list_for_each_entry(d, &r->domains, list) { 228 if (d->id == dom_id) { 229 data.buf = dom; 230 data.rdtgrp = rdtgrp; 231 if (r->parse_ctrlval(&data, s, d)) 232 return -EINVAL; 233 if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) { 234 cfg = &d->staged_config[t]; 235 /* 236 * In pseudo-locking setup mode and just 237 * parsed a valid CBM that should be 238 * pseudo-locked. Only one locked region per 239 * resource group and domain so just do 240 * the required initialization for single 241 * region and return. 242 */ 243 rdtgrp->plr->s = s; 244 rdtgrp->plr->d = d; 245 rdtgrp->plr->cbm = cfg->new_ctrl; 246 d->plr = rdtgrp->plr; 247 return 0; 248 } 249 goto next; 250 } 251 } 252 return -EINVAL; 253 } 254 255 static u32 get_config_index(u32 closid, enum resctrl_conf_type type) 256 { 257 switch (type) { 258 default: 259 case CDP_NONE: 260 return closid; 261 case CDP_CODE: 262 return closid * 2 + 1; 263 case CDP_DATA: 264 return closid * 2; 265 } 266 } 267 268 static bool apply_config(struct rdt_hw_domain *hw_dom, 269 struct resctrl_staged_config *cfg, u32 idx, 270 cpumask_var_t cpu_mask) 271 { 272 struct rdt_domain *dom = &hw_dom->d_resctrl; 273 274 if (cfg->new_ctrl != hw_dom->ctrl_val[idx]) { 275 cpumask_set_cpu(cpumask_any(&dom->cpu_mask), cpu_mask); 276 hw_dom->ctrl_val[idx] = cfg->new_ctrl; 277 278 return true; 279 } 280 281 return false; 282 } 283 284 int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, 285 u32 closid, enum resctrl_conf_type t, u32 cfg_val) 286 { 287 struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); 288 struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d); 289 u32 idx = get_config_index(closid, t); 290 struct msr_param msr_param; 291 292 if (!cpumask_test_cpu(smp_processor_id(), &d->cpu_mask)) 293 return -EINVAL; 294 295 hw_dom->ctrl_val[idx] = cfg_val; 296 297 msr_param.res = r; 298 msr_param.low = idx; 299 msr_param.high = idx + 1; 300 hw_res->msr_update(d, &msr_param, r); 301 302 return 0; 303 } 304 305 int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid) 306 { 307 struct resctrl_staged_config *cfg; 308 struct rdt_hw_domain *hw_dom; 309 struct msr_param msr_param; 310 enum resctrl_conf_type t; 311 cpumask_var_t cpu_mask; 312 struct rdt_domain *d; 313 u32 idx; 314 315 if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL)) 316 return -ENOMEM; 317 318 msr_param.res = NULL; 319 list_for_each_entry(d, &r->domains, list) { 320 hw_dom = resctrl_to_arch_dom(d); 321 for (t = 0; t < CDP_NUM_TYPES; t++) { 322 cfg = &hw_dom->d_resctrl.staged_config[t]; 323 if (!cfg->have_new_ctrl) 324 continue; 325 326 idx = get_config_index(closid, t); 327 if (!apply_config(hw_dom, cfg, idx, cpu_mask)) 328 continue; 329 330 if (!msr_param.res) { 331 msr_param.low = idx; 332 msr_param.high = msr_param.low + 1; 333 msr_param.res = r; 334 } else { 335 msr_param.low = min(msr_param.low, idx); 336 msr_param.high = max(msr_param.high, idx + 1); 337 } 338 } 339 } 340 341 if (cpumask_empty(cpu_mask)) 342 goto done; 343 344 /* Update resource control msr on all the CPUs. */ 345 on_each_cpu_mask(cpu_mask, rdt_ctrl_update, &msr_param, 1); 346 347 done: 348 free_cpumask_var(cpu_mask); 349 350 return 0; 351 } 352 353 static int rdtgroup_parse_resource(char *resname, char *tok, 354 struct rdtgroup *rdtgrp) 355 { 356 struct resctrl_schema *s; 357 358 list_for_each_entry(s, &resctrl_schema_all, list) { 359 if (!strcmp(resname, s->name) && rdtgrp->closid < s->num_closid) 360 return parse_line(tok, s, rdtgrp); 361 } 362 rdt_last_cmd_printf("Unknown or unsupported resource name '%s'\n", resname); 363 return -EINVAL; 364 } 365 366 ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, 367 char *buf, size_t nbytes, loff_t off) 368 { 369 struct resctrl_schema *s; 370 struct rdtgroup *rdtgrp; 371 struct rdt_resource *r; 372 char *tok, *resname; 373 int ret = 0; 374 375 /* Valid input requires a trailing newline */ 376 if (nbytes == 0 || buf[nbytes - 1] != '\n') 377 return -EINVAL; 378 buf[nbytes - 1] = '\0'; 379 380 cpus_read_lock(); 381 rdtgrp = rdtgroup_kn_lock_live(of->kn); 382 if (!rdtgrp) { 383 rdtgroup_kn_unlock(of->kn); 384 cpus_read_unlock(); 385 return -ENOENT; 386 } 387 rdt_last_cmd_clear(); 388 389 /* 390 * No changes to pseudo-locked region allowed. It has to be removed 391 * and re-created instead. 392 */ 393 if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) { 394 ret = -EINVAL; 395 rdt_last_cmd_puts("Resource group is pseudo-locked\n"); 396 goto out; 397 } 398 399 rdt_staged_configs_clear(); 400 401 while ((tok = strsep(&buf, "\n")) != NULL) { 402 resname = strim(strsep(&tok, ":")); 403 if (!tok) { 404 rdt_last_cmd_puts("Missing ':'\n"); 405 ret = -EINVAL; 406 goto out; 407 } 408 if (tok[0] == '\0') { 409 rdt_last_cmd_printf("Missing '%s' value\n", resname); 410 ret = -EINVAL; 411 goto out; 412 } 413 ret = rdtgroup_parse_resource(resname, tok, rdtgrp); 414 if (ret) 415 goto out; 416 } 417 418 list_for_each_entry(s, &resctrl_schema_all, list) { 419 r = s->res; 420 421 /* 422 * Writes to mba_sc resources update the software controller, 423 * not the control MSR. 424 */ 425 if (is_mba_sc(r)) 426 continue; 427 428 ret = resctrl_arch_update_domains(r, rdtgrp->closid); 429 if (ret) 430 goto out; 431 } 432 433 if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) { 434 /* 435 * If pseudo-locking fails we keep the resource group in 436 * mode RDT_MODE_PSEUDO_LOCKSETUP with its class of service 437 * active and updated for just the domain the pseudo-locked 438 * region was requested for. 439 */ 440 ret = rdtgroup_pseudo_lock_create(rdtgrp); 441 } 442 443 out: 444 rdt_staged_configs_clear(); 445 rdtgroup_kn_unlock(of->kn); 446 cpus_read_unlock(); 447 return ret ?: nbytes; 448 } 449 450 u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, 451 u32 closid, enum resctrl_conf_type type) 452 { 453 struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d); 454 u32 idx = get_config_index(closid, type); 455 456 return hw_dom->ctrl_val[idx]; 457 } 458 459 static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int closid) 460 { 461 struct rdt_resource *r = schema->res; 462 struct rdt_domain *dom; 463 bool sep = false; 464 u32 ctrl_val; 465 466 seq_printf(s, "%*s:", max_name_width, schema->name); 467 list_for_each_entry(dom, &r->domains, list) { 468 if (sep) 469 seq_puts(s, ";"); 470 471 if (is_mba_sc(r)) 472 ctrl_val = dom->mbps_val[closid]; 473 else 474 ctrl_val = resctrl_arch_get_config(r, dom, closid, 475 schema->conf_type); 476 477 seq_printf(s, r->format_str, dom->id, max_data_width, 478 ctrl_val); 479 sep = true; 480 } 481 seq_puts(s, "\n"); 482 } 483 484 int rdtgroup_schemata_show(struct kernfs_open_file *of, 485 struct seq_file *s, void *v) 486 { 487 struct resctrl_schema *schema; 488 struct rdtgroup *rdtgrp; 489 int ret = 0; 490 u32 closid; 491 492 rdtgrp = rdtgroup_kn_lock_live(of->kn); 493 if (rdtgrp) { 494 if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) { 495 list_for_each_entry(schema, &resctrl_schema_all, list) { 496 seq_printf(s, "%s:uninitialized\n", schema->name); 497 } 498 } else if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) { 499 if (!rdtgrp->plr->d) { 500 rdt_last_cmd_clear(); 501 rdt_last_cmd_puts("Cache domain offline\n"); 502 ret = -ENODEV; 503 } else { 504 seq_printf(s, "%s:%d=%x\n", 505 rdtgrp->plr->s->res->name, 506 rdtgrp->plr->d->id, 507 rdtgrp->plr->cbm); 508 } 509 } else { 510 closid = rdtgrp->closid; 511 list_for_each_entry(schema, &resctrl_schema_all, list) { 512 if (closid < schema->num_closid) 513 show_doms(s, schema, closid); 514 } 515 } 516 } else { 517 ret = -ENOENT; 518 } 519 rdtgroup_kn_unlock(of->kn); 520 return ret; 521 } 522 523 void mon_event_read(struct rmid_read *rr, struct rdt_resource *r, 524 struct rdt_domain *d, struct rdtgroup *rdtgrp, 525 int evtid, int first) 526 { 527 /* 528 * setup the parameters to send to the IPI to read the data. 529 */ 530 rr->rgrp = rdtgrp; 531 rr->evtid = evtid; 532 rr->r = r; 533 rr->d = d; 534 rr->val = 0; 535 rr->first = first; 536 537 smp_call_function_any(&d->cpu_mask, mon_event_count, rr, 1); 538 } 539 540 int rdtgroup_mondata_show(struct seq_file *m, void *arg) 541 { 542 struct kernfs_open_file *of = m->private; 543 u32 resid, evtid, domid; 544 struct rdtgroup *rdtgrp; 545 struct rdt_resource *r; 546 union mon_data_bits md; 547 struct rdt_domain *d; 548 struct rmid_read rr; 549 int ret = 0; 550 551 rdtgrp = rdtgroup_kn_lock_live(of->kn); 552 if (!rdtgrp) { 553 ret = -ENOENT; 554 goto out; 555 } 556 557 md.priv = of->kn->priv; 558 resid = md.u.rid; 559 domid = md.u.domid; 560 evtid = md.u.evtid; 561 562 r = &rdt_resources_all[resid].r_resctrl; 563 d = rdt_find_domain(r, domid, NULL); 564 if (IS_ERR_OR_NULL(d)) { 565 ret = -ENOENT; 566 goto out; 567 } 568 569 mon_event_read(&rr, r, d, rdtgrp, evtid, false); 570 571 if (rr.err == -EIO) 572 seq_puts(m, "Error\n"); 573 else if (rr.err == -EINVAL) 574 seq_puts(m, "Unavailable\n"); 575 else 576 seq_printf(m, "%llu\n", rr.val); 577 578 out: 579 rdtgroup_kn_unlock(of->kn); 580 return ret; 581 } 582