diff options
author | James Morse <james.morse@arm.com> | 2021-07-28 20:06:37 +0300 |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2021-08-11 19:39:42 +0300 |
commit | 5c3b63cdba441c6a530b974ff73b14161d96a0c3 (patch) | |
tree | 464801a2901ad0b692870ed811cc4708519b455c /arch/x86/kernel/cpu/resctrl/rdtgroup.c | |
parent | 327364d5b6b6f8c89d2d6253a986d80323512890 (diff) | |
download | linux-5c3b63cdba441c6a530b974ff73b14161d96a0c3.tar.xz |
x86/resctrl: Merge the CDP resources
resctrl uses struct rdt_resource to describe the available hardware
resources. The domains of the CDP aliases share a single ctrl_val[]
array. The only differences between the struct rdt_hw_resource aliases
is the name and conf_type.
The name from struct rdt_hw_resource is visible to user-space. To
support another architecture, as many user-visible details should be
handled in the filesystem parts of the code that is common to all
architectures. The name and conf_type go together.
Remove conf_type and the CDP aliases. When CDP is supported and enabled,
schemata_list_create() can create two schemata using the single
resource, generating the CODE/DATA suffix to the schema name itself.
This allows the alloc_ctrlval_array() and complications around free()ing
the ctrl_val arrays to be removed.
Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Jamie Iles <jamie@nuviainc.com>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Link: https://lkml.kernel.org/r/20210728170637.25610-25-james.morse@arm.com
Diffstat (limited to 'arch/x86/kernel/cpu/resctrl/rdtgroup.c')
-rw-r--r-- | arch/x86/kernel/cpu/resctrl/rdtgroup.c | 140 |
1 files changed, 73 insertions, 67 deletions
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 7cf4bf3583a9..89123a4977cf 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -1880,10 +1880,10 @@ void rdt_domain_reconfigure_cdp(struct rdt_resource *r) if (!r->cdp_capable) return; - if (r == &rdt_resources_all[RDT_RESOURCE_L2DATA].r_resctrl) + if (r->rid == RDT_RESOURCE_L2) l2_qos_cfg_update(&hw_res->cdp_enabled); - if (r == &rdt_resources_all[RDT_RESOURCE_L3DATA].r_resctrl) + if (r->rid == RDT_RESOURCE_L3) l3_qos_cfg_update(&hw_res->cdp_enabled); } @@ -1912,68 +1912,42 @@ static int set_mba_sc(bool mba_sc) return 0; } -static int cdp_enable(int level, int data_type, int code_type) +static int cdp_enable(int level) { - struct rdt_resource *r_ldata = &rdt_resources_all[data_type].r_resctrl; - struct rdt_resource *r_lcode = &rdt_resources_all[code_type].r_resctrl; struct rdt_resource *r_l = &rdt_resources_all[level].r_resctrl; int ret; - if (!r_l->alloc_capable || !r_ldata->alloc_capable || - !r_lcode->alloc_capable) + if (!r_l->alloc_capable) return -EINVAL; ret = set_cache_qos_cfg(level, true); - if (!ret) { - r_l->alloc_enabled = false; - r_ldata->alloc_enabled = true; - r_lcode->alloc_enabled = true; + if (!ret) rdt_resources_all[level].cdp_enabled = true; - rdt_resources_all[data_type].cdp_enabled = true; - rdt_resources_all[code_type].cdp_enabled = true; - } + return ret; } -static void cdp_disable(int level, int data_type, int code_type) +static void cdp_disable(int level) { struct rdt_hw_resource *r_hw = &rdt_resources_all[level]; - struct rdt_resource *r = &r_hw->r_resctrl; - - r->alloc_enabled = r->alloc_capable; if (r_hw->cdp_enabled) { - rdt_resources_all[data_type].r_resctrl.alloc_enabled = false; - rdt_resources_all[code_type].r_resctrl.alloc_enabled = false; set_cache_qos_cfg(level, false); r_hw->cdp_enabled = false; - rdt_resources_all[data_type].cdp_enabled = false; - rdt_resources_all[code_type].cdp_enabled = false; } } int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) { struct rdt_hw_resource *hw_res = &rdt_resources_all[l]; - enum resctrl_res_level code_type, data_type; if (!hw_res->r_resctrl.cdp_capable) return -EINVAL; - if (l == RDT_RESOURCE_L3) { - code_type = RDT_RESOURCE_L3CODE; - data_type = RDT_RESOURCE_L3DATA; - } else if (l == RDT_RESOURCE_L2) { - code_type = RDT_RESOURCE_L2CODE; - data_type = RDT_RESOURCE_L2DATA; - } else { - return -EINVAL; - } - if (enable) - return cdp_enable(l, data_type, code_type); + return cdp_enable(l); - cdp_disable(l, data_type, code_type); + cdp_disable(l); return 0; } @@ -2072,50 +2046,82 @@ static int rdt_enable_ctx(struct rdt_fs_context *ctx) return ret; } -static int schemata_list_create(void) +static int schemata_list_add(struct rdt_resource *r, enum resctrl_conf_type type) { struct resctrl_schema *s; - struct rdt_resource *r; + const char *suffix = ""; int ret, cl; - for_each_alloc_enabled_rdt_resource(r) { - s = kzalloc(sizeof(*s), GFP_KERNEL); - if (!s) - return -ENOMEM; - - s->res = r; - s->conf_type = resctrl_to_arch_res(r)->conf_type; - s->num_closid = resctrl_arch_get_num_closid(r); - if (resctrl_arch_get_cdp_enabled(r->rid)) - s->num_closid /= 2; - - ret = snprintf(s->name, sizeof(s->name), r->name); - if (ret >= sizeof(s->name)) { - kfree(s); - return -EINVAL; - } - - cl = strlen(s->name); + s = kzalloc(sizeof(*s), GFP_KERNEL); + if (!s) + return -ENOMEM; - /* - * If CDP is supported by this resource, but not enabled, - * include the suffix. This ensures the tabular format of the - * schemata file does not change between mounts of the - * filesystem. - */ - if (r->cdp_capable && !resctrl_arch_get_cdp_enabled(r->rid)) - cl += 4; + s->res = r; + s->num_closid = resctrl_arch_get_num_closid(r); + if (resctrl_arch_get_cdp_enabled(r->rid)) + s->num_closid /= 2; - if (cl > max_name_width) - max_name_width = cl; + s->conf_type = type; + switch (type) { + case CDP_CODE: + suffix = "CODE"; + break; + case CDP_DATA: + suffix = "DATA"; + break; + case CDP_NONE: + suffix = ""; + break; + } - INIT_LIST_HEAD(&s->list); - list_add(&s->list, &resctrl_schema_all); + ret = snprintf(s->name, sizeof(s->name), "%s%s", r->name, suffix); + if (ret >= sizeof(s->name)) { + kfree(s); + return -EINVAL; } + cl = strlen(s->name); + + /* + * If CDP is supported by this resource, but not enabled, + * include the suffix. This ensures the tabular format of the + * schemata file does not change between mounts of the filesystem. + */ + if (r->cdp_capable && !resctrl_arch_get_cdp_enabled(r->rid)) + cl += 4; + + if (cl > max_name_width) + max_name_width = cl; + + INIT_LIST_HEAD(&s->list); + list_add(&s->list, &resctrl_schema_all); + return 0; } +static int schemata_list_create(void) +{ + struct rdt_resource *r; + int ret = 0; + + for_each_alloc_enabled_rdt_resource(r) { + if (resctrl_arch_get_cdp_enabled(r->rid)) { + ret = schemata_list_add(r, CDP_CODE); + if (ret) + break; + + ret = schemata_list_add(r, CDP_DATA); + } else { + ret = schemata_list_add(r, CDP_NONE); + } + + if (ret) + break; + } + + return ret; +} + static void schemata_list_destroy(void) { struct resctrl_schema *s, *tmp; |