Skip to content

Commit 792e0f6

Browse files
James Morsesuryasaimadhu
authored andcommitted
x86/resctrl: Split struct rdt_domain
resctrl is the defacto Linux ABI for SoC resource partitioning features. To support it on another architecture, it needs to be abstracted from the features provided by Intel RDT and AMD PQoS, and moved to /fs/. struct rdt_domain contains a mix of architecture private details and properties of the filesystem interface user-space uses. Continue by splitting struct rdt_domain, into an architecture private 'hw' struct, which contains the common resctrl structure that would be used by any architecture. The hardware values in ctrl_val and mbps_val need to be accessed via helpers to allow another architecture to convert these into a different format if necessary. After this split, filesystem code paths touching a 'hw' struct indicates where an abstraction is needed. Splitting this structure only moves types around, and should not lead to any change in behaviour. Signed-off-by: James Morse <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Reviewed-by: Jamie Iles <[email protected]> Reviewed-by: Reinette Chatre <[email protected]> Tested-by: Babu Moger <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 63c8b12 commit 792e0f6

File tree

6 files changed

+94
-60
lines changed

6 files changed

+94
-60
lines changed

arch/x86/kernel/cpu/resctrl/core.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,11 @@ static void
385385
mba_wrmsr_amd(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r)
386386
{
387387
unsigned int i;
388+
struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
388389
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
389390

390391
for (i = m->low; i < m->high; i++)
391-
wrmsrl(hw_res->msr_base + i, d->ctrl_val[i]);
392+
wrmsrl(hw_res->msr_base + i, hw_dom->ctrl_val[i]);
392393
}
393394

394395
/*
@@ -410,21 +411,23 @@ mba_wrmsr_intel(struct rdt_domain *d, struct msr_param *m,
410411
struct rdt_resource *r)
411412
{
412413
unsigned int i;
414+
struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
413415
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
414416

415417
/* Write the delay values for mba. */
416418
for (i = m->low; i < m->high; i++)
417-
wrmsrl(hw_res->msr_base + i, delay_bw_map(d->ctrl_val[i], r));
419+
wrmsrl(hw_res->msr_base + i, delay_bw_map(hw_dom->ctrl_val[i], r));
418420
}
419421

420422
static void
421423
cat_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r)
422424
{
423425
unsigned int i;
426+
struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
424427
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
425428

426429
for (i = m->low; i < m->high; i++)
427-
wrmsrl(hw_res->msr_base + cbm_idx(r, i), d->ctrl_val[i]);
430+
wrmsrl(hw_res->msr_base + cbm_idx(r, i), hw_dom->ctrl_val[i]);
428431
}
429432

430433
struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r)
@@ -510,21 +513,22 @@ void setup_default_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm)
510513
static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d)
511514
{
512515
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
516+
struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
513517
struct msr_param m;
514518
u32 *dc, *dm;
515519

516-
dc = kmalloc_array(hw_res->num_closid, sizeof(*d->ctrl_val), GFP_KERNEL);
520+
dc = kmalloc_array(hw_res->num_closid, sizeof(*hw_dom->ctrl_val), GFP_KERNEL);
517521
if (!dc)
518522
return -ENOMEM;
519523

520-
dm = kmalloc_array(hw_res->num_closid, sizeof(*d->mbps_val), GFP_KERNEL);
524+
dm = kmalloc_array(hw_res->num_closid, sizeof(*hw_dom->mbps_val), GFP_KERNEL);
521525
if (!dm) {
522526
kfree(dc);
523527
return -ENOMEM;
524528
}
525529

526-
d->ctrl_val = dc;
527-
d->mbps_val = dm;
530+
hw_dom->ctrl_val = dc;
531+
hw_dom->mbps_val = dm;
528532
setup_default_ctrlval(r, dc, dm);
529533

530534
m.low = 0;
@@ -586,6 +590,7 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
586590
{
587591
int id = get_cpu_cacheinfo_id(cpu, r->cache_level);
588592
struct list_head *add_pos = NULL;
593+
struct rdt_hw_domain *hw_dom;
589594
struct rdt_domain *d;
590595

591596
d = rdt_find_domain(r, id, &add_pos);
@@ -601,10 +606,11 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
601606
return;
602607
}
603608

604-
d = kzalloc_node(sizeof(*d), GFP_KERNEL, cpu_to_node(cpu));
605-
if (!d)
609+
hw_dom = kzalloc_node(sizeof(*hw_dom), GFP_KERNEL, cpu_to_node(cpu));
610+
if (!hw_dom)
606611
return;
607612

613+
d = &hw_dom->d_resctrl;
608614
d->id = id;
609615
cpumask_set_cpu(cpu, &d->cpu_mask);
610616

@@ -633,13 +639,15 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
633639
static void domain_remove_cpu(int cpu, struct rdt_resource *r)
634640
{
635641
int id = get_cpu_cacheinfo_id(cpu, r->cache_level);
642+
struct rdt_hw_domain *hw_dom;
636643
struct rdt_domain *d;
637644

638645
d = rdt_find_domain(r, id, NULL);
639646
if (IS_ERR_OR_NULL(d)) {
640647
pr_warn("Couldn't find cache id for CPU %d\n", cpu);
641648
return;
642649
}
650+
hw_dom = resctrl_to_arch_dom(d);
643651

644652
cpumask_clear_cpu(cpu, &d->cpu_mask);
645653
if (cpumask_empty(&d->cpu_mask)) {
@@ -672,12 +680,12 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r)
672680
if (d->plr)
673681
d->plr->d = NULL;
674682

675-
kfree(d->ctrl_val);
676-
kfree(d->mbps_val);
683+
kfree(hw_dom->ctrl_val);
684+
kfree(hw_dom->mbps_val);
677685
bitmap_free(d->rmid_busy_llc);
678686
kfree(d->mbm_total);
679687
kfree(d->mbm_local);
680-
kfree(d);
688+
kfree(hw_dom);
681689
return;
682690
}
683691

arch/x86/kernel/cpu/resctrl/ctrlmondata.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ static int parse_line(char *line, struct rdt_resource *r,
238238

239239
int update_domains(struct rdt_resource *r, int closid)
240240
{
241+
struct rdt_hw_domain *hw_dom;
241242
struct msr_param msr_param;
242243
cpumask_var_t cpu_mask;
243244
struct rdt_domain *d;
@@ -254,7 +255,8 @@ int update_domains(struct rdt_resource *r, int closid)
254255

255256
mba_sc = is_mba_sc(r);
256257
list_for_each_entry(d, &r->domains, list) {
257-
dc = !mba_sc ? d->ctrl_val : d->mbps_val;
258+
hw_dom = resctrl_to_arch_dom(d);
259+
dc = !mba_sc ? hw_dom->ctrl_val : hw_dom->mbps_val;
258260
if (d->have_new_ctrl && d->new_ctrl != dc[closid]) {
259261
cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask);
260262
dc[closid] = d->new_ctrl;
@@ -375,17 +377,19 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
375377

376378
static void show_doms(struct seq_file *s, struct rdt_resource *r, int closid)
377379
{
380+
struct rdt_hw_domain *hw_dom;
378381
struct rdt_domain *dom;
379382
bool sep = false;
380383
u32 ctrl_val;
381384

382385
seq_printf(s, "%*s:", max_name_width, r->name);
383386
list_for_each_entry(dom, &r->domains, list) {
387+
hw_dom = resctrl_to_arch_dom(dom);
384388
if (sep)
385389
seq_puts(s, ";");
386390

387-
ctrl_val = (!is_mba_sc(r) ? dom->ctrl_val[closid] :
388-
dom->mbps_val[closid]);
391+
ctrl_val = (!is_mba_sc(r) ? hw_dom->ctrl_val[closid] :
392+
hw_dom->mbps_val[closid]);
389393
seq_printf(s, r->format_str, dom->id, max_data_width,
390394
ctrl_val);
391395
sep = true;

arch/x86/kernel/cpu/resctrl/internal.h

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -304,44 +304,25 @@ struct mbm_state {
304304
};
305305

306306
/**
307-
* struct rdt_domain - group of cpus sharing an RDT resource
308-
* @list: all instances of this resource
309-
* @id: unique id for this instance
310-
* @cpu_mask: which cpus share this resource
311-
* @rmid_busy_llc:
312-
* bitmap of which limbo RMIDs are above threshold
313-
* @mbm_total: saved state for MBM total bandwidth
314-
* @mbm_local: saved state for MBM local bandwidth
315-
* @mbm_over: worker to periodically read MBM h/w counters
316-
* @cqm_limbo: worker to periodically read CQM h/w counters
317-
* @mbm_work_cpu:
318-
* worker cpu for MBM h/w counters
319-
* @cqm_work_cpu:
320-
* worker cpu for CQM h/w counters
307+
* struct rdt_hw_domain - Arch private attributes of a set of CPUs that share
308+
* a resource
309+
* @d_resctrl: Properties exposed to the resctrl file system
321310
* @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID)
322311
* @mbps_val: When mba_sc is enabled, this holds the bandwidth in MBps
323-
* @new_ctrl: new ctrl value to be loaded
324-
* @have_new_ctrl: did user provide new_ctrl for this domain
325-
* @plr: pseudo-locked region (if any) associated with domain
312+
*
313+
* Members of this structure are accessed via helpers that provide abstraction.
326314
*/
327-
struct rdt_domain {
328-
struct list_head list;
329-
int id;
330-
struct cpumask cpu_mask;
331-
unsigned long *rmid_busy_llc;
332-
struct mbm_state *mbm_total;
333-
struct mbm_state *mbm_local;
334-
struct delayed_work mbm_over;
335-
struct delayed_work cqm_limbo;
336-
int mbm_work_cpu;
337-
int cqm_work_cpu;
315+
struct rdt_hw_domain {
316+
struct rdt_domain d_resctrl;
338317
u32 *ctrl_val;
339318
u32 *mbps_val;
340-
u32 new_ctrl;
341-
bool have_new_ctrl;
342-
struct pseudo_lock_region *plr;
343319
};
344320

321+
static inline struct rdt_hw_domain *resctrl_to_arch_dom(struct rdt_domain *r)
322+
{
323+
return container_of(r, struct rdt_hw_domain, d_resctrl);
324+
}
325+
345326
/**
346327
* struct msr_param - set a range of MSRs from a domain
347328
* @res: The resource to use

arch/x86/kernel/cpu/resctrl/monitor.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
418418
u32 closid, rmid, cur_msr, cur_msr_val, new_msr_val;
419419
struct mbm_state *pmbm_data, *cmbm_data;
420420
struct rdt_hw_resource *hw_r_mba;
421+
struct rdt_hw_domain *hw_dom_mba;
421422
u32 cur_bw, delta_bw, user_bw;
422423
struct rdt_resource *r_mba;
423424
struct rdt_domain *dom_mba;
@@ -438,11 +439,12 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
438439
pr_warn_once("Failure to get domain for MBA update\n");
439440
return;
440441
}
442+
hw_dom_mba = resctrl_to_arch_dom(dom_mba);
441443

442444
cur_bw = pmbm_data->prev_bw;
443-
user_bw = dom_mba->mbps_val[closid];
445+
user_bw = hw_dom_mba->mbps_val[closid];
444446
delta_bw = pmbm_data->delta_bw;
445-
cur_msr_val = dom_mba->ctrl_val[closid];
447+
cur_msr_val = hw_dom_mba->ctrl_val[closid];
446448

447449
/*
448450
* For Ctrl groups read data from child monitor groups.
@@ -479,7 +481,7 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
479481

480482
cur_msr = hw_r_mba->msr_base + closid;
481483
wrmsrl(cur_msr, delay_bw_map(new_msr_val, r_mba));
482-
dom_mba->ctrl_val[closid] = new_msr_val;
484+
hw_dom_mba->ctrl_val[closid] = new_msr_val;
483485

484486
/*
485487
* Delta values are updated dynamically package wise for each

arch/x86/kernel/cpu/resctrl/rdtgroup.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ static int rdt_bit_usage_show(struct kernfs_open_file *of,
915915
list_for_each_entry(dom, &r->domains, list) {
916916
if (sep)
917917
seq_putc(seq, ';');
918-
ctrl = dom->ctrl_val;
918+
ctrl = resctrl_to_arch_dom(dom)->ctrl_val;
919919
sw_shareable = 0;
920920
exclusive = 0;
921921
seq_printf(seq, "%d=", dom->id);
@@ -1193,7 +1193,7 @@ static bool __rdtgroup_cbm_overlaps(struct rdt_resource *r, struct rdt_domain *d
11931193
}
11941194

11951195
/* Check for overlap with other resource groups */
1196-
ctrl = d->ctrl_val;
1196+
ctrl = resctrl_to_arch_dom(d)->ctrl_val;
11971197
for (i = 0; i < closids_supported(); i++, ctrl++) {
11981198
ctrl_b = *ctrl;
11991199
mode = rdtgroup_mode_by_closid(i);
@@ -1262,6 +1262,7 @@ bool rdtgroup_cbm_overlaps(struct rdt_resource *r, struct rdt_domain *d,
12621262
*/
12631263
static bool rdtgroup_mode_test_exclusive(struct rdtgroup *rdtgrp)
12641264
{
1265+
struct rdt_hw_domain *hw_dom;
12651266
int closid = rdtgrp->closid;
12661267
struct rdt_resource *r;
12671268
bool has_cache = false;
@@ -1272,7 +1273,8 @@ static bool rdtgroup_mode_test_exclusive(struct rdtgroup *rdtgrp)
12721273
continue;
12731274
has_cache = true;
12741275
list_for_each_entry(d, &r->domains, list) {
1275-
if (rdtgroup_cbm_overlaps(r, d, d->ctrl_val[closid],
1276+
hw_dom = resctrl_to_arch_dom(d);
1277+
if (rdtgroup_cbm_overlaps(r, d, hw_dom->ctrl_val[closid],
12761278
rdtgrp->closid, false)) {
12771279
rdt_last_cmd_puts("Schemata overlaps\n");
12781280
return false;
@@ -1404,6 +1406,7 @@ unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r,
14041406
static int rdtgroup_size_show(struct kernfs_open_file *of,
14051407
struct seq_file *s, void *v)
14061408
{
1409+
struct rdt_hw_domain *hw_dom;
14071410
struct rdtgroup *rdtgrp;
14081411
struct rdt_resource *r;
14091412
struct rdt_domain *d;
@@ -1438,14 +1441,15 @@ static int rdtgroup_size_show(struct kernfs_open_file *of,
14381441
sep = false;
14391442
seq_printf(s, "%*s:", max_name_width, r->name);
14401443
list_for_each_entry(d, &r->domains, list) {
1444+
hw_dom = resctrl_to_arch_dom(d);
14411445
if (sep)
14421446
seq_putc(s, ';');
14431447
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
14441448
size = 0;
14451449
} else {
14461450
ctrl = (!is_mba_sc(r) ?
1447-
d->ctrl_val[rdtgrp->closid] :
1448-
d->mbps_val[rdtgrp->closid]);
1451+
hw_dom->ctrl_val[rdtgrp->closid] :
1452+
hw_dom->mbps_val[rdtgrp->closid]);
14491453
if (r->rid == RDT_RESOURCE_MBA)
14501454
size = ctrl;
14511455
else
@@ -1940,15 +1944,18 @@ void rdt_domain_reconfigure_cdp(struct rdt_resource *r)
19401944
static int set_mba_sc(bool mba_sc)
19411945
{
19421946
struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_MBA].r_resctrl;
1947+
struct rdt_hw_domain *hw_dom;
19431948
struct rdt_domain *d;
19441949

19451950
if (!is_mbm_enabled() || !is_mba_linear() ||
19461951
mba_sc == is_mba_sc(r))
19471952
return -EINVAL;
19481953

19491954
r->membw.mba_sc = mba_sc;
1950-
list_for_each_entry(d, &r->domains, list)
1951-
setup_default_ctrlval(r, d->ctrl_val, d->mbps_val);
1955+
list_for_each_entry(d, &r->domains, list) {
1956+
hw_dom = resctrl_to_arch_dom(d);
1957+
setup_default_ctrlval(r, hw_dom->ctrl_val, hw_dom->mbps_val);
1958+
}
19521959

19531960
return 0;
19541961
}
@@ -2265,6 +2272,7 @@ static int rdt_init_fs_context(struct fs_context *fc)
22652272
static int reset_all_ctrls(struct rdt_resource *r)
22662273
{
22672274
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
2275+
struct rdt_hw_domain *hw_dom;
22682276
struct msr_param msr_param;
22692277
cpumask_var_t cpu_mask;
22702278
struct rdt_domain *d;
@@ -2283,10 +2291,11 @@ static int reset_all_ctrls(struct rdt_resource *r)
22832291
* from each domain to update the MSRs below.
22842292
*/
22852293
list_for_each_entry(d, &r->domains, list) {
2294+
hw_dom = resctrl_to_arch_dom(d);
22862295
cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask);
22872296

22882297
for (i = 0; i < hw_res->num_closid; i++)
2289-
d->ctrl_val[i] = r->default_ctrl;
2298+
hw_dom->ctrl_val[i] = r->default_ctrl;
22902299
}
22912300
cpu = get_cpu();
22922301
/* Update CBM on this cpu if it's in cpu_mask. */
@@ -2665,7 +2674,7 @@ static int __init_one_rdt_domain(struct rdt_domain *d, struct rdt_resource *r,
26652674
d->have_new_ctrl = false;
26662675
d->new_ctrl = r->cache.shareable_bits;
26672676
used_b = r->cache.shareable_bits;
2668-
ctrl = d->ctrl_val;
2677+
ctrl = resctrl_to_arch_dom(d)->ctrl_val;
26692678
for (i = 0; i < closids_supported(); i++, ctrl++) {
26702679
if (closid_allocated(i) && i != closid) {
26712680
mode = rdtgroup_mode_by_closid(i);
@@ -2682,7 +2691,7 @@ static int __init_one_rdt_domain(struct rdt_domain *d, struct rdt_resource *r,
26822691
* with an exclusive group.
26832692
*/
26842693
if (d_cdp)
2685-
peer_ctl = d_cdp->ctrl_val[i];
2694+
peer_ctl = resctrl_to_arch_dom(d_cdp)->ctrl_val[i];
26862695
else
26872696
peer_ctl = 0;
26882697
used_b |= *ctrl | peer_ctl;

0 commit comments

Comments
 (0)