
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC35SV -------------------------------- In the following patches, we would introduce many QoS configuration in order to enhance MPAM's capability for isolating interference and schedule shared resources. As a prerequisite patch, it introduces the resctrl_schema_fmt, an enumeration type that indicates the format in which resource configurations are issued by users. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- arch/x86/kernel/cpu/resctrl/core.c | 6 ++- drivers/platform/mpam/mpam_resctrl.c | 70 ++++++++++++++++------------ fs/resctrl/ctrlmondata.c | 13 ++++-- fs/resctrl/rdtgroup.c | 13 ++++-- include/linux/resctrl.h | 13 +++++- 5 files changed, 75 insertions(+), 40 deletions(-) diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c index 6a5a5b43af27..0d63f1a0eb72 100644 --- a/arch/x86/kernel/cpu/resctrl/core.c +++ b/arch/x86/kernel/cpu/resctrl/core.c @@ -61,7 +61,7 @@ mba_wrmsr_amd(struct rdt_domain *d, struct msr_param *m, #define domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].r_resctrl.domains) -struct rdt_hw_resource rdt_resources_all[] = { +struct rdt_hw_resource rdt_resources_all[RDT_NUM_RESOURCES] = { [RDT_RESOURCE_L3] = { .r_resctrl = { @@ -71,6 +71,7 @@ struct rdt_hw_resource rdt_resources_all[] = { .domains = domain_init(RDT_RESOURCE_L3), .format_str = "%d=%0*x", .fflags = RFTYPE_RES_CACHE, + .schema_fmt = RESCTRL_SCHEMA_BITMAP, }, .msr_base = MSR_IA32_L3_CBM_BASE, .msr_update = cat_wrmsr, @@ -84,6 +85,7 @@ struct rdt_hw_resource rdt_resources_all[] = { .domains = domain_init(RDT_RESOURCE_L2), .format_str = "%d=%0*x", .fflags = RFTYPE_RES_CACHE, + .schema_fmt = RESCTRL_SCHEMA_BITMAP, }, .msr_base = MSR_IA32_L2_CBM_BASE, .msr_update = cat_wrmsr, @@ -97,6 +99,7 @@ struct rdt_hw_resource rdt_resources_all[] = { .domains = domain_init(RDT_RESOURCE_MBA), .format_str = "%d=%*u", .fflags = RFTYPE_RES_MB, + .schema_fmt = RESCTRL_SCHEMA_RANGE, }, }, [RDT_RESOURCE_SMBA] = @@ -108,6 +111,7 @@ struct rdt_hw_resource rdt_resources_all[] = { .domains = domain_init(RDT_RESOURCE_SMBA), .format_str = "%d=%*u", .fflags = RFTYPE_RES_MB, + .schema_fmt = RESCTRL_SCHEMA_RANGE, }, }, }; diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 7586c8ffbb88..5080271fdcaa 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -581,6 +581,9 @@ static u32 mbw_max_to_percent(u16 mbw_max, u8 wd) u8 bit; u32 divisor = 2, value = 0, precision = get_wd_precision(wd); + if (mbw_max == GENMASK(15, 15 - wd + 1)) + return MAX_MBA_BW; + for (bit = 15; bit; bit--) { if (mbw_max & BIT(bit)) value += MAX_MBA_BW * precision / divisor; @@ -610,6 +613,9 @@ static u16 percent_to_mbw_max(u32 pc, u8 wd) if (WARN_ON_ONCE(wd > 15)) return MAX_MBA_BW; + if (pc == MAX_MBA_BW) + return GENMASK(15, 15 - wd + 1); + pc *= precision; for (bit = 15; bit; bit--) { @@ -677,22 +683,25 @@ static void mpam_resctrl_pick_caches(void) if (mpam_has_feature(mpam_feat_msmon_csu, cprops)) update_rmid_limits(cache_size); - if (class->level == 2) { - res = &mpam_resctrl_exports[RDT_RESOURCE_L2]; - res->resctrl_res.name = "L2"; - } else { - res = &mpam_resctrl_exports[RDT_RESOURCE_L3]; - res->resctrl_res.name = "L3"; + if (has_cpor) { + if (class->level == 2) { + res = &mpam_resctrl_exports[RDT_RESOURCE_L2]; + res->resctrl_res.name = "L2"; + } else { + res = &mpam_resctrl_exports[RDT_RESOURCE_L3]; + res->resctrl_res.name = "L3"; + } + res->class = class; } - res->class = class; } srcu_read_unlock(&mpam_srcu, idx); } static void mpam_resctrl_pick_mba(void) { - struct mpam_class *class, *candidate_class = NULL; struct mpam_resctrl_res *res; + struct mpam_class *class; + bool has_mba; int idx; lockdep_assert_cpus_held(); @@ -701,6 +710,8 @@ static void mpam_resctrl_pick_mba(void) list_for_each_entry_rcu(class, &mpam_classes, classes_list) { struct mpam_props *cprops = &class->props; + has_mba = class_has_usable_mba(cprops); + if (class->level < 3) continue; @@ -710,21 +721,13 @@ static void mpam_resctrl_pick_mba(void) if (!cpumask_equal(&class->affinity, cpu_possible_mask)) continue; - /* - * mba_sc reads the mbm_local counter, and waggles the MBA controls. - * mbm_local is implicitly part of the L3, pick a resouce to be MBA - * that as close as possible to the L3. - */ - if (!candidate_class || class->level < candidate_class->level) - candidate_class = class; + if (has_mba) { + res = &mpam_resctrl_exports[RDT_RESOURCE_MBA]; + res->class = class; + res->resctrl_res.name = "MB"; + } } srcu_read_unlock(&mpam_srcu, idx); - - if (candidate_class) { - res = &mpam_resctrl_exports[RDT_RESOURCE_MBA]; - res->class = candidate_class; - res->resctrl_res.name = "MB"; - } } bool resctrl_arch_is_evt_configurable(enum resctrl_event_id evt) @@ -778,14 +781,15 @@ void resctrl_arch_reset_rmid_all(struct rdt_resource *r, struct rdt_domain *d) static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) { struct mpam_class *class = res->class; + struct mpam_props *cprops = &class->props; struct rdt_resource *r = &res->resctrl_res; bool has_mbwu = class_has_usable_mbwu(class); + bool has_csu = cache_has_usable_csu(class); /* Is this one of the two well-known caches? */ - if (res->resctrl_res.rid == RDT_RESOURCE_L2 || - res->resctrl_res.rid == RDT_RESOURCE_L3) { - bool has_csu = cache_has_usable_csu(class); - + switch (res->resctrl_res.rid) { + case RDT_RESOURCE_L2: + case RDT_RESOURCE_L3: /* TODO: Scaling is not yet supported */ r->cache.cbm_len = class->props.cpbm_wd; r->cache.arch_has_sparse_bitmasks = true; @@ -795,6 +799,7 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) /* TODO: kill these properties off as they are derivatives */ r->format_str = "%d=%0*x"; + r->schema_fmt = RESCTRL_SCHEMA_BITMAP; r->fflags = RFTYPE_RES_CACHE; r->default_ctrl = BIT_MASK(class->props.cpbm_wd) - 1; r->data_width = (class->props.cpbm_wd + 3) / 4; @@ -808,7 +813,7 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) */ r->cache.shareable_bits = r->default_ctrl; - if (mpam_has_feature(mpam_feat_cpor_part, &class->props)) { + if (mpam_has_feature(mpam_feat_cpor_part, cprops)) { r->alloc_capable = true; exposed_alloc_capable = true; } @@ -832,11 +837,12 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) class->level == 3) { r->mon_capable = true; } - } else if (res->resctrl_res.rid == RDT_RESOURCE_MBA) { - struct mpam_props *cprops = &class->props; + break; + case RDT_RESOURCE_MBA: /* TODO: kill these properties off as they are derivatives */ r->format_str = "%d=%0*u"; + r->schema_fmt = RESCTRL_SCHEMA_PERCENT; r->fflags = RFTYPE_RES_MB; r->default_ctrl = MAX_MBA_BW; r->data_width = 3; @@ -858,6 +864,10 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) mbm_total_class = class; r->mon_capable = true; } + break; + + default: + break; } if (r->mon_capable) { @@ -871,7 +881,7 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) * For mpam, each control group has its own pmg/rmid * space. */ - r->num_rmid = 1; + r->num_rmid = mpam_partid_max * mpam_pmg_max; } return 0; @@ -1027,6 +1037,8 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, if (!r->alloc_capable || partid >= resctrl_arch_get_num_closid(r)) return -EINVAL; + cfg = dom->comp->cfg[partid]; + switch (r->rid) { case RDT_RESOURCE_L2: case RDT_RESOURCE_L3: diff --git a/fs/resctrl/ctrlmondata.c b/fs/resctrl/ctrlmondata.c index 15df4334ff14..60b422eed2c8 100644 --- a/fs/resctrl/ctrlmondata.c +++ b/fs/resctrl/ctrlmondata.c @@ -45,20 +45,23 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) * Only linear delay values is supported for current Intel SKUs. */ if (!r->membw.delay_linear && r->membw.arch_needs_linear) { - rdt_last_cmd_puts("No support for non-linear MB domains\n"); + rdt_last_cmd_printf("No support for non-linear %s domains\n", + r->name); return false; } ret = kstrtoul(buf, 10, &bw); if (ret) { - rdt_last_cmd_printf("Non-decimal digit in MB value %s\n", buf); + rdt_last_cmd_printf("Non-decimal digit in %s value %s\n", + r->name, buf); return false; } if ((bw < r->membw.min_bw || bw > r->default_ctrl) && !is_mba_sc(r)) { - rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw, - r->membw.min_bw, r->default_ctrl); + rdt_last_cmd_printf("%s value %ld out of range [%d,%d]\n", + r->name, bw, r->membw.min_bw, + r->default_ctrl); return false; } @@ -227,7 +230,7 @@ static int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s, static ctrlval_parser_t *get_parser(struct rdt_resource *res) { - if (res->fflags & RFTYPE_RES_CACHE) + if (res->schema_fmt == RESCTRL_SCHEMA_BITMAP) return &parse_cbm; else return &parse_bw; diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c index 4b38a68cc0f3..ffb6b8930435 100644 --- a/fs/resctrl/rdtgroup.c +++ b/fs/resctrl/rdtgroup.c @@ -1679,11 +1679,11 @@ static int rdtgroup_size_show(struct kernfs_open_file *of, ctrl = resctrl_arch_get_config(r, d, closid, type); - if (r->rid == RDT_RESOURCE_MBA || - r->rid == RDT_RESOURCE_SMBA) - size = ctrl; - else + if (r->rid == RDT_RESOURCE_L3 || + r->rid == RDT_RESOURCE_L2) size = rdtgroup_cbm_to_size(r, d, ctrl); + else + size = ctrl; } seq_printf(s, "%d=%u", d->id, size); sep = true; @@ -2293,6 +2293,11 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) /* loop over enabled controls, these are all alloc_capable */ list_for_each_entry(s, &resctrl_schema_all, list) { r = s->res; + + /* Not supported yet */ + if (r->rid > RDT_RESOURCE_SMBA) + continue; + fflags = r->fflags | RFTYPE_CTRL_INFO; ret = rdtgroup_mkdir_info_resdir(s, s->name, fflags); if (ret) diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index 61ff7dd5d74c..9aa4e4ee0a67 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -177,6 +177,16 @@ struct resctrl_membw { u32 *mb_map; }; +/** + * enum resctrl_schema_fmt - The format user-space provides for a schema. + * @RESCTRL_SCHEMA_BITMAP: The schema is a bitmap in hex. + * @RESCTRL_SCHEMA_RANGE: The schema is a decimal number. + */ +enum resctrl_schema_fmt { + RESCTRL_SCHEMA_BITMAP, + RESCTRL_SCHEMA_RANGE, +}; + /** * struct rdt_resource - attributes of a resctrl resource * @rid: The index of the resource @@ -211,6 +221,7 @@ struct rdt_resource { struct list_head evt_list; unsigned long fflags; bool cdp_capable; + enum resctrl_schema_fmt schema_fmt; }; /* @@ -234,7 +245,7 @@ struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l); */ struct resctrl_schema { struct list_head list; - char name[8]; + char name[16]; enum resctrl_conf_type conf_type; struct rdt_resource *res; u32 num_closid; -- 2.25.1