Each cache domain (struct rdt_domain) contains a pointer to a pseudo-locked region that (if set) is associated with it. At the same time each resource group (struct rdtgroup) also contains a pointer to a pseudo-locked region that (if set) is associated with it.
If a pointer from a cache domain to its pseudo-locked region is maintained then multiple cache domains could point to a single pseudo-locked region when a pseudo-locked region spans multiple resources. Such an arrangement would make it harder to support the current mechanism of iterating over cache domains in order to find all pseudo-locked regions. In preparation for pseudo-locked regions that could span multiple resources the pointer from a cache domain to a pseudo-locked region is removed. The pointer to a pseudo-locked region from a resource group remains - when needing to process all pseudo-locked regions on the system an iteration over all resource groups is used instead of an iteration over all cache domains. Signed-off-by: Reinette Chatre <reinette.cha...@intel.com> --- arch/x86/kernel/cpu/resctrl/ctrlmondata.c | 3 +- arch/x86/kernel/cpu/resctrl/internal.h | 6 +-- arch/x86/kernel/cpu/resctrl/pseudo_lock.c | 46 +++++++++++------------ arch/x86/kernel/cpu/resctrl/rdtgroup.c | 8 ++-- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c index 072f584cb238..a0383ff80afe 100644 --- a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c +++ b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c @@ -217,7 +217,7 @@ int parse_cbm(struct rdt_parse_data *data, struct rdt_resource *r, if ((rdtgrp->mode == RDT_MODE_EXCLUSIVE || rdtgrp->mode == RDT_MODE_SHAREABLE) && - rdtgroup_cbm_overlaps_pseudo_locked(d, cbm_val)) { + rdtgroup_cbm_overlaps_pseudo_locked(r, d, cbm_val)) { rdt_last_cmd_puts("CBM overlaps with pseudo-locked region\n"); return -EINVAL; } @@ -293,7 +293,6 @@ static int parse_line(char *line, struct rdt_resource *r, rdtgrp->plr->r = r; rdtgrp->plr->d_id = d->id; rdtgrp->plr->cbm = d->new_ctrl; - d->plr = rdtgrp->plr; return 0; } goto next; diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h index f17633cf4776..892f38899dda 100644 --- a/arch/x86/kernel/cpu/resctrl/internal.h +++ b/arch/x86/kernel/cpu/resctrl/internal.h @@ -309,7 +309,6 @@ struct mbm_state { * @mbps_val: When mba_sc is enabled, this holds the bandwidth in MBps * @new_ctrl: new ctrl value to be loaded * @have_new_ctrl: did user provide new_ctrl for this domain - * @plr: pseudo-locked region (if any) associated with domain */ struct rdt_domain { struct list_head list; @@ -326,7 +325,6 @@ struct rdt_domain { u32 *mbps_val; u32 new_ctrl; bool have_new_ctrl; - struct pseudo_lock_region *plr; }; /** @@ -567,7 +565,9 @@ enum rdtgrp_mode rdtgroup_mode_by_closid(int closid); int rdtgroup_tasks_assigned(struct rdtgroup *r); int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp); int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp); -bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_domain *d, unsigned long cbm); +bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_resource *r, + struct rdt_domain *d, + unsigned long cbm); u32 rdtgroup_pseudo_locked_bits(struct rdt_resource *r, struct rdt_domain *d); bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d); int rdt_pseudo_lock_init(void); diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c index f16702a076a3..733cb7f34948 100644 --- a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c +++ b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c @@ -272,17 +272,10 @@ static int pseudo_lock_cstates_constrain(struct pseudo_lock_region *plr, */ static void pseudo_lock_region_clear(struct pseudo_lock_region *plr) { - struct rdt_domain *d; - plr->size = 0; plr->line_size = 0; kfree(plr->kmem); plr->kmem = NULL; - if (plr->r && plr->d_id >= 0) { - d = rdt_find_domain(plr->r, plr->d_id, NULL); - if (!IS_ERR_OR_NULL(d)) - d->plr = NULL; - } plr->r = NULL; plr->d_id = -1; plr->cbm = 0; @@ -822,6 +815,7 @@ int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp) /** * rdtgroup_cbm_overlaps_pseudo_locked - Test if CBM or portion is pseudo-locked + * @r: RDT resource to which @d belongs * @d: RDT domain * @cbm: CBM to test * @@ -835,17 +829,17 @@ int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp) * Return: true if @cbm overlaps with pseudo-locked region on @d, false * otherwise. */ -bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_domain *d, unsigned long cbm) +bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_resource *r, + struct rdt_domain *d, + unsigned long cbm) { + unsigned long pseudo_locked; unsigned int cbm_len; - unsigned long cbm_b; - if (d->plr) { - cbm_len = d->plr->r->cache.cbm_len; - cbm_b = d->plr->cbm; - if (bitmap_intersects(&cbm, &cbm_b, cbm_len)) - return true; - } + pseudo_locked = rdtgroup_pseudo_locked_bits(r, d); + cbm_len = r->cache.cbm_len; + if (bitmap_intersects(&cbm, &pseudo_locked, cbm_len)) + return true; return false; } @@ -859,13 +853,13 @@ bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_domain *d, unsigned long cbm * attempts to create new pseudo-locked regions in the same hierarchy. * * Return: true if a pseudo-locked region exists in the hierarchy of @d or - * if it is not possible to test due to memory allocation issue, - * false otherwise. + * if it is not possible to test due to memory allocation or other + * failure, false otherwise. */ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d) { cpumask_var_t cpu_with_psl; - struct rdt_resource *r; + struct rdtgroup *rdtgrp; struct rdt_domain *d_i; bool ret = false; @@ -876,11 +870,16 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d) * First determine which cpus have pseudo-locked regions * associated with them. */ - for_each_alloc_enabled_rdt_resource(r) { - list_for_each_entry(d_i, &r->domains, list) { - if (d_i->plr) - cpumask_or(cpu_with_psl, cpu_with_psl, - &d_i->cpu_mask); + list_for_each_entry(rdtgrp, &rdt_all_groups, rdtgroup_list) { + if (rdtgrp->plr && rdtgrp->plr->d_id >= 0) { + d_i = rdt_find_domain(rdtgrp->plr->r, rdtgrp->plr->d_id, + NULL); + if (IS_ERR_OR_NULL(d_i)) { + ret = true; + goto out; + } + cpumask_or(cpu_with_psl, cpu_with_psl, + &d_i->cpu_mask); } } @@ -891,6 +890,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d) if (cpumask_intersects(&d->cpu_mask, cpu_with_psl)) ret = true; +out: free_cpumask_var(cpu_with_psl); return ret; } diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index c4bf6ed8b031..0c1786f09963 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -845,8 +845,10 @@ static int rdt_bit_usage_show(struct kernfs_open_file *of, break; } } + + pseudo_locked = rdtgroup_pseudo_locked_bits(r, dom); + for (i = r->cache.cbm_len - 1; i >= 0; i--) { - pseudo_locked = dom->plr ? dom->plr->cbm : 0; hwb = test_bit(i, &hw_shareable); swb = test_bit(i, &sw_shareable); excl = test_bit(i, &exclusive); @@ -2541,8 +2543,8 @@ static int __init_one_rdt_domain(struct rdt_domain *d, struct rdt_resource *r, d->new_ctrl |= *ctrl | peer_ctl; } } - if (d->plr && d->plr->cbm > 0) - used_b |= d->plr->cbm; + + used_b |= rdtgroup_pseudo_locked_bits(r, d); unused_b = used_b ^ (BIT_MASK(r->cache.cbm_len) - 1); unused_b &= BIT_MASK(r->cache.cbm_len) - 1; d->new_ctrl |= unused_b; -- 2.17.2