x86/intel_rdt: Support creation/removal of pseudo-locked region
The user triggers the creation of a pseudo-locked region when writing a valid schemata to the schemata file of a resource group in the pseudo-locksetup mode. A valid schemata is one that: (1) does not overlap with any other resource group, (2) does not involve a cache that already contains a pseudo-locked region within its hierarchy. After a valid schemata is parsed the system is programmed to associate the to be pseudo-lock bitmask with the closid associated with the resource group. With the system set up the pseudo-locked region can be created. 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/8929c3a9e2ba600e79649abe584aa28b8d0ff639.1529706536.git.reinette.chatre@intel.com
This commit is contained in:
parent
018961ae55
commit
e0bdfe8e36
@ -143,9 +143,26 @@ int parse_cbm(void *_data, struct rdt_resource *r, struct rdt_domain *d)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cannot set up more than one pseudo-locked region in a cache
|
||||||
|
* hierarchy.
|
||||||
|
*/
|
||||||
|
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP &&
|
||||||
|
rdtgroup_pseudo_locked_in_hierarchy(d)) {
|
||||||
|
rdt_last_cmd_printf("pseudo-locked region in hierarchy\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!cbm_validate(data->buf, &cbm_val, r))
|
if (!cbm_validate(data->buf, &cbm_val, r))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if ((rdtgrp->mode == RDT_MODE_EXCLUSIVE ||
|
||||||
|
rdtgrp->mode == RDT_MODE_SHAREABLE) &&
|
||||||
|
rdtgroup_cbm_overlaps_pseudo_locked(d, cbm_val)) {
|
||||||
|
rdt_last_cmd_printf("CBM overlaps with pseudo-locked region\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The CBM may not overlap with the CBM of another closid if
|
* The CBM may not overlap with the CBM of another closid if
|
||||||
* either is exclusive.
|
* either is exclusive.
|
||||||
@ -199,6 +216,21 @@ next:
|
|||||||
data.rdtgrp = rdtgrp;
|
data.rdtgrp = rdtgrp;
|
||||||
if (r->parse_ctrlval(&data, r, d))
|
if (r->parse_ctrlval(&data, r, d))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
|
||||||
|
/*
|
||||||
|
* In pseudo-locking setup mode and just
|
||||||
|
* parsed a valid CBM that should be
|
||||||
|
* pseudo-locked. Only one locked region per
|
||||||
|
* resource group and domain so just do
|
||||||
|
* the required initialization for single
|
||||||
|
* region and return.
|
||||||
|
*/
|
||||||
|
rdtgrp->plr->r = r;
|
||||||
|
rdtgrp->plr->d = d;
|
||||||
|
rdtgrp->plr->cbm = d->new_ctrl;
|
||||||
|
d->plr = rdtgrp->plr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,6 +354,16 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
|
||||||
|
/*
|
||||||
|
* If pseudo-locking fails we keep the resource group in
|
||||||
|
* mode RDT_MODE_PSEUDO_LOCKSETUP with its class of service
|
||||||
|
* active and updated for just the domain the pseudo-locked
|
||||||
|
* region was requested for.
|
||||||
|
*/
|
||||||
|
ret = rdtgroup_pseudo_lock_create(rdtgrp);
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
rdtgroup_kn_unlock(of->kn);
|
rdtgroup_kn_unlock(of->kn);
|
||||||
return ret ?: nbytes;
|
return ret ?: nbytes;
|
||||||
|
@ -1771,6 +1771,9 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn)
|
|||||||
|
|
||||||
if (atomic_dec_and_test(&rdtgrp->waitcount) &&
|
if (atomic_dec_and_test(&rdtgrp->waitcount) &&
|
||||||
(rdtgrp->flags & RDT_DELETED)) {
|
(rdtgrp->flags & RDT_DELETED)) {
|
||||||
|
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP ||
|
||||||
|
rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED)
|
||||||
|
rdtgroup_pseudo_lock_remove(rdtgrp);
|
||||||
kernfs_unbreak_active_protection(kn);
|
kernfs_unbreak_active_protection(kn);
|
||||||
kernfs_put(rdtgrp->kn);
|
kernfs_put(rdtgrp->kn);
|
||||||
kfree(rdtgrp);
|
kfree(rdtgrp);
|
||||||
@ -2002,6 +2005,10 @@ static void rmdir_all_sub(void)
|
|||||||
if (rdtgrp == &rdtgroup_default)
|
if (rdtgrp == &rdtgroup_default)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP ||
|
||||||
|
rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED)
|
||||||
|
rdtgroup_pseudo_lock_remove(rdtgrp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Give any CPUs back to the default group. We cannot copy
|
* Give any CPUs back to the default group. We cannot copy
|
||||||
* cpu_online_mask because a CPU might have executed the
|
* cpu_online_mask because a CPU might have executed the
|
||||||
@ -2313,6 +2320,8 @@ static int rdtgroup_init_alloc(struct rdtgroup *rdtgrp)
|
|||||||
d->new_ctrl |= *ctrl;
|
d->new_ctrl |= *ctrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (d->plr && d->plr->cbm > 0)
|
||||||
|
used_b |= d->plr->cbm;
|
||||||
unused_b = used_b ^ (BIT_MASK(r->cache.cbm_len) - 1);
|
unused_b = used_b ^ (BIT_MASK(r->cache.cbm_len) - 1);
|
||||||
unused_b &= BIT_MASK(r->cache.cbm_len) - 1;
|
unused_b &= BIT_MASK(r->cache.cbm_len) - 1;
|
||||||
d->new_ctrl |= unused_b;
|
d->new_ctrl |= unused_b;
|
||||||
@ -2696,13 +2705,19 @@ static int rdtgroup_rmdir(struct kernfs_node *kn)
|
|||||||
* If the rdtgroup is a mon group and parent directory
|
* If the rdtgroup is a mon group and parent directory
|
||||||
* is a valid "mon_groups" directory, remove the mon group.
|
* is a valid "mon_groups" directory, remove the mon group.
|
||||||
*/
|
*/
|
||||||
if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn)
|
if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn) {
|
||||||
ret = rdtgroup_rmdir_ctrl(kn, rdtgrp, tmpmask);
|
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP ||
|
||||||
else if (rdtgrp->type == RDTMON_GROUP &&
|
rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) {
|
||||||
is_mon_groups(parent_kn, kn->name))
|
ret = rdtgroup_ctrl_remove(kn, rdtgrp);
|
||||||
|
} else {
|
||||||
|
ret = rdtgroup_rmdir_ctrl(kn, rdtgrp, tmpmask);
|
||||||
|
}
|
||||||
|
} else if (rdtgrp->type == RDTMON_GROUP &&
|
||||||
|
is_mon_groups(parent_kn, kn->name)) {
|
||||||
ret = rdtgroup_rmdir_mon(kn, rdtgrp, tmpmask);
|
ret = rdtgroup_rmdir_mon(kn, rdtgrp, tmpmask);
|
||||||
else
|
} else {
|
||||||
ret = -EPERM;
|
ret = -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
rdtgroup_kn_unlock(kn);
|
rdtgroup_kn_unlock(kn);
|
||||||
|
Loading…
Reference in New Issue
Block a user