Skip to content

Commit

Permalink
x86/intel_rdt: Enable setting of exclusive mode
Browse files Browse the repository at this point in the history
The new "mode" file now accepts "exclusive" that means that the
allocations of this resource group cannot be shared.

Enable users to modify a resource group's mode to "exclusive". To
succeed it is required that there is no overlap between resource group's
current schemata and that of all the other active resource groups as
well as cache regions potentially used by other hardware entities.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: fenghua.yu@intel.com
Cc: tony.luck@intel.com
Cc: vikas.shivappa@linux.intel.com
Cc: gavin.hindman@intel.com
Cc: jithu.joseph@intel.com
Cc: dave.hansen@intel.com
Cc: hpa@zytor.com
Link: https://lkml.kernel.org/r/83642cbba3c8c21db7fa6bb36fe7d385d3b275f2.1529706536.git.reinette.chatre@intel.com
  • Loading branch information
Reinette Chatre authored and Thomas Gleixner committed Jun 23, 2018
1 parent 414dd2b commit 49f7b4e
Showing 1 changed file with 96 additions and 1 deletion.
97 changes: 96 additions & 1 deletion arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,93 @@ static int rdtgroup_mode_show(struct kernfs_open_file *of,
return 0;
}

/**
* rdtgroup_cbm_overlaps - Does CBM for intended closid overlap with other
* @r: Resource to which domain instance @d belongs.
* @d: The domain instance for which @closid is being tested.
* @cbm: Capacity bitmask being tested.
* @closid: Intended closid for @cbm.
* @exclusive: Only check if overlaps with exclusive resource groups
*
* Checks if provided @cbm intended to be used for @closid on domain
* @d overlaps with any other closids or other hardware usage associated
* with this domain. If @exclusive is true then only overlaps with
* resource groups in exclusive mode will be considered. If @exclusive
* is false then overlaps with any resource group or hardware entities
* will be considered.
*
* Return: false if CBM does not overlap, true if it does.
*/
static bool rdtgroup_cbm_overlaps(struct rdt_resource *r, struct rdt_domain *d,
u32 _cbm, int closid, bool exclusive)
{
unsigned long *cbm = (unsigned long *)&_cbm;
unsigned long *ctrl_b;
enum rdtgrp_mode mode;
u32 *ctrl;
int i;

/* Check for any overlap with regions used by hardware directly */
if (!exclusive) {
if (bitmap_intersects(cbm,
(unsigned long *)&r->cache.shareable_bits,
r->cache.cbm_len))
return true;
}

/* Check for overlap with other resource groups */
ctrl = d->ctrl_val;
for (i = 0; i < r->num_closid; i++, ctrl++) {
ctrl_b = (unsigned long *)ctrl;
if (closid_allocated(i) && i != closid) {
if (bitmap_intersects(cbm, ctrl_b, r->cache.cbm_len)) {
mode = rdtgroup_mode_by_closid(i);
if (exclusive) {
if (mode == RDT_MODE_EXCLUSIVE)
return true;
continue;
}
return true;
}
}
}

return false;
}

/**
* rdtgroup_mode_test_exclusive - Test if this resource group can be exclusive
*
* An exclusive resource group implies that there should be no sharing of
* its allocated resources. At the time this group is considered to be
* exclusive this test can determine if its current schemata supports this
* setting by testing for overlap with all other resource groups.
*
* Return: true if resource group can be exclusive, false if there is overlap
* with allocations of other resource groups and thus this resource group
* cannot be exclusive.
*/
static bool rdtgroup_mode_test_exclusive(struct rdtgroup *rdtgrp)
{
int closid = rdtgrp->closid;
struct rdt_resource *r;
struct rdt_domain *d;

for_each_alloc_enabled_rdt_resource(r) {
list_for_each_entry(d, &r->domains, list) {
if (rdtgroup_cbm_overlaps(r, d, d->ctrl_val[closid],
rdtgrp->closid, false))
return false;
}
}

return true;
}

/**
* rdtgroup_mode_write - Modify the resource group's mode
*
*/
static ssize_t rdtgroup_mode_write(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off)
{
Expand All @@ -834,11 +921,19 @@ static ssize_t rdtgroup_mode_write(struct kernfs_open_file *of,

mode = rdtgrp->mode;

if ((!strcmp(buf, "shareable") && mode == RDT_MODE_SHAREABLE))
if ((!strcmp(buf, "shareable") && mode == RDT_MODE_SHAREABLE) ||
(!strcmp(buf, "exclusive") && mode == RDT_MODE_EXCLUSIVE))
goto out;

if (!strcmp(buf, "shareable")) {
rdtgrp->mode = RDT_MODE_SHAREABLE;
} else if (!strcmp(buf, "exclusive")) {
if (!rdtgroup_mode_test_exclusive(rdtgrp)) {
rdt_last_cmd_printf("schemata overlaps\n");
ret = -EINVAL;
goto out;
}
rdtgrp->mode = RDT_MODE_EXCLUSIVE;
} else {
rdt_last_cmd_printf("unknown/unsupported mode\n");
ret = -EINVAL;
Expand Down

0 comments on commit 49f7b4e

Please sign in to comment.