Skip to content

Commit 95f0b77

Browse files
rchatreKAGA-KOKO
authored andcommitted
x86/intel_rdt: Initialize new resource group with sane defaults
Currently when a new resource group is created its allocations would be those that belonged to the resource group to which its closid belonged previously. That is, we can encounter a case like: mkdir newgroup cat newgroup/schemata L2:0=ff;1=ff echo 'L2:0=0xf0;1=0xf0' > newgroup/schemata cat newgroup/schemata L2:0=0xf0;1=0xf0 rmdir newgroup mkdir newnewgroup cat newnewgroup/schemata L2:0=0xf0;1=0xf0 When the new group is created it would be reasonable to expect its allocations to be initialized with all regions that it can possibly use. At this time these regions would be all that are shareable by other resource groups as well as regions that are not currently used. If the available cache region is found to be non-contiguous the available region is adjusted to enforce validity. When a new resource group is created the hardware is initialized with these new default allocations. 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/c468ed79340b63024111978e01430bb9589d85c0.1529706536.git.reinette.chatre@intel.com
1 parent 024d15b commit 95f0b77

File tree

1 file changed

+112
-3
lines changed

1 file changed

+112
-3
lines changed

arch/x86/kernel/cpu/intel_rdt_rdtgroup.c

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ void closid_free(int closid)
133133
* Return: true if @closid is currently associated with a resource group,
134134
* false if @closid is free
135135
*/
136-
static bool __attribute__ ((unused)) closid_allocated(unsigned int closid)
136+
static bool closid_allocated(unsigned int closid)
137137
{
138138
return (closid_free_map & (1 << closid)) == 0;
139139
}
@@ -1807,6 +1807,110 @@ static int mkdir_mondata_all(struct kernfs_node *parent_kn,
18071807
return ret;
18081808
}
18091809

1810+
/**
1811+
* cbm_ensure_valid - Enforce validity on provided CBM
1812+
* @_val: Candidate CBM
1813+
* @r: RDT resource to which the CBM belongs
1814+
*
1815+
* The provided CBM represents all cache portions available for use. This
1816+
* may be represented by a bitmap that does not consist of contiguous ones
1817+
* and thus be an invalid CBM.
1818+
* Here the provided CBM is forced to be a valid CBM by only considering
1819+
* the first set of contiguous bits as valid and clearing all bits.
1820+
* The intention here is to provide a valid default CBM with which a new
1821+
* resource group is initialized. The user can follow this with a
1822+
* modification to the CBM if the default does not satisfy the
1823+
* requirements.
1824+
*/
1825+
static void cbm_ensure_valid(u32 *_val, struct rdt_resource *r)
1826+
{
1827+
/*
1828+
* Convert the u32 _val to an unsigned long required by all the bit
1829+
* operations within this function. No more than 32 bits of this
1830+
* converted value can be accessed because all bit operations are
1831+
* additionally provided with cbm_len that is initialized during
1832+
* hardware enumeration using five bits from the EAX register and
1833+
* thus never can exceed 32 bits.
1834+
*/
1835+
unsigned long *val = (unsigned long *)_val;
1836+
unsigned int cbm_len = r->cache.cbm_len;
1837+
unsigned long first_bit, zero_bit;
1838+
1839+
if (*val == 0)
1840+
return;
1841+
1842+
first_bit = find_first_bit(val, cbm_len);
1843+
zero_bit = find_next_zero_bit(val, cbm_len, first_bit);
1844+
1845+
/* Clear any remaining bits to ensure contiguous region */
1846+
bitmap_clear(val, zero_bit, cbm_len - zero_bit);
1847+
}
1848+
1849+
/**
1850+
* rdtgroup_init_alloc - Initialize the new RDT group's allocations
1851+
*
1852+
* A new RDT group is being created on an allocation capable (CAT)
1853+
* supporting system. Set this group up to start off with all usable
1854+
* allocations. That is, all shareable and unused bits.
1855+
*
1856+
* All-zero CBM is invalid. If there are no more shareable bits available
1857+
* on any domain then the entire allocation will fail.
1858+
*/
1859+
static int rdtgroup_init_alloc(struct rdtgroup *rdtgrp)
1860+
{
1861+
u32 used_b = 0, unused_b = 0;
1862+
u32 closid = rdtgrp->closid;
1863+
struct rdt_resource *r;
1864+
enum rdtgrp_mode mode;
1865+
struct rdt_domain *d;
1866+
int i, ret;
1867+
u32 *ctrl;
1868+
1869+
for_each_alloc_enabled_rdt_resource(r) {
1870+
list_for_each_entry(d, &r->domains, list) {
1871+
d->have_new_ctrl = false;
1872+
d->new_ctrl = r->cache.shareable_bits;
1873+
used_b = r->cache.shareable_bits;
1874+
ctrl = d->ctrl_val;
1875+
for (i = 0; i < r->num_closid; i++, ctrl++) {
1876+
if (closid_allocated(i) && i != closid) {
1877+
mode = rdtgroup_mode_by_closid(i);
1878+
used_b |= *ctrl;
1879+
if (mode == RDT_MODE_SHAREABLE)
1880+
d->new_ctrl |= *ctrl;
1881+
}
1882+
}
1883+
unused_b = used_b ^ (BIT_MASK(r->cache.cbm_len) - 1);
1884+
unused_b &= BIT_MASK(r->cache.cbm_len) - 1;
1885+
d->new_ctrl |= unused_b;
1886+
/*
1887+
* Force the initial CBM to be valid, user can
1888+
* modify the CBM based on system availability.
1889+
*/
1890+
cbm_ensure_valid(&d->new_ctrl, r);
1891+
if (bitmap_weight((unsigned long *) &d->new_ctrl,
1892+
r->cache.cbm_len) <
1893+
r->cache.min_cbm_bits) {
1894+
rdt_last_cmd_printf("no space on %s:%d\n",
1895+
r->name, d->id);
1896+
return -ENOSPC;
1897+
}
1898+
d->have_new_ctrl = true;
1899+
}
1900+
}
1901+
1902+
for_each_alloc_enabled_rdt_resource(r) {
1903+
ret = update_domains(r, rdtgrp->closid);
1904+
if (ret < 0) {
1905+
rdt_last_cmd_puts("failed to initialize allocations\n");
1906+
return ret;
1907+
}
1908+
rdtgrp->mode = RDT_MODE_SHAREABLE;
1909+
}
1910+
1911+
return 0;
1912+
}
1913+
18101914
static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
18111915
struct kernfs_node *prgrp_kn,
18121916
const char *name, umode_t mode,
@@ -1965,6 +2069,10 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
19652069
ret = 0;
19662070

19672071
rdtgrp->closid = closid;
2072+
ret = rdtgroup_init_alloc(rdtgrp);
2073+
if (ret < 0)
2074+
goto out_id_free;
2075+
19682076
list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups);
19692077

19702078
if (rdt_mon_capable) {
@@ -1975,15 +2083,16 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
19752083
ret = mongroup_create_dir(kn, NULL, "mon_groups", NULL);
19762084
if (ret) {
19772085
rdt_last_cmd_puts("kernfs subdir error\n");
1978-
goto out_id_free;
2086+
goto out_del_list;
19792087
}
19802088
}
19812089

19822090
goto out_unlock;
19832091

2092+
out_del_list:
2093+
list_del(&rdtgrp->rdtgroup_list);
19842094
out_id_free:
19852095
closid_free(closid);
1986-
list_del(&rdtgrp->rdtgroup_list);
19872096
out_common_fail:
19882097
mkdir_rdt_prepare_clean(rdtgrp);
19892098
out_unlock:

0 commit comments

Comments
 (0)