hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/9840 ------------------ Add support for the MBOPT memory bandwidth resource, which provides an alternative bandwidth allocation mechanism compared to the standard MBA (Memory Bandwidth Allocation) resource. MBOPT uses a different scaling and value interpretation for bandwidth limits, allowing finer-grained control. Unlike MBA which converts values to percentages, MBOPT uses raw register values shifted by the hardware standard width. The MBOPT resource is exposed as "MBOPT" in the resctrl schemata, alongside the existing "MB" resource. MBOPT defaults to maximum bandwidth, allowing all traffic by default until explicitly restricted by the user. Example: # cat schemata MBOPT:0=0001023;1=0001023 MB:0=0000100;1=0000100 # echo MBOPT:0=000102 > schemata # cat schemata MBOPT:0=0000102;1=0001023 MB:0=0000010;1=0000100 Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_resctrl.c | 39 ++++++++++++++++++++++++++-- include/linux/resctrl_types.h | 1 + 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 569a5254d65e0..a8f8f1a802eae 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -1002,6 +1002,10 @@ static void mpam_resctrl_pick_mba(void) res = &mpam_resctrl_exports[RDT_RESOURCE_MBA]; res->class = class; res->resctrl_res.name = "MB"; + + res = &mpam_resctrl_exports[RDT_RESOURCE_MB_OPT]; + res->class = class; + res->resctrl_res.name = "MBOPT"; } if (has_mbw_min) { @@ -1307,6 +1311,23 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) r->alloc_capable = true; break; + case RDT_RESOURCE_MB_OPT: + r->format_str = "%d=%0*u"; + r->schema_fmt = RESCTRL_SCHEMA_RANGE; + r->fflags = RFTYPE_RES_MB; + r->default_ctrl = GENMASK(cprops->bwa_wd - 1, 0); + r->membw.max_bw = GENMASK(cprops->bwa_wd - 1, 0); + r->data_width = 5; + + r->membw.delay_linear = true; + r->membw.throttle_mode = THREAD_THROTTLE_UNDEFINED; + r->membw.min_bw = 1; + r->membw.bw_gran = 1; + + if (class_has_usable_mba(cprops)) + r->alloc_capable = true; + break; + default: break; } @@ -1571,6 +1592,10 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, configured_by = mpam_feat_max_limit; break; + case RDT_RESOURCE_MB_OPT: + configured_by = mpam_feat_mbw_max; + break; + default: return -EINVAL; } @@ -1593,14 +1618,20 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, /* TODO: Scaling is not yet supported */ return mbw_pbm_to_percent(cfg->mbw_pbm, cprops); case mpam_feat_mbw_max: - return mbw_max_to_percent(cfg->mbw_max, cprops->bwa_wd); + if (r->rid == RDT_RESOURCE_MBA) + return mbw_max_to_percent(cfg->mbw_max, cprops->bwa_wd); + else if (r->rid == RDT_RESOURCE_MB_OPT) + return cfg->mbw_max >> (16 - cprops->bwa_wd); + break; case mpam_feat_mbw_min: return mbw_max_to_percent(cfg->mbw_min, cprops->bwa_wd); case mpam_feat_max_limit: return cfg->max_limit; default: - return -EINVAL; + break; } + + return -EINVAL; } int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, @@ -1676,6 +1707,10 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, cfg.max_limit = cfg_val; mpam_set_feature(mpam_feat_max_limit, &cfg); break; + case RDT_RESOURCE_MB_OPT: + cfg.mbw_max = cfg_val << (16 - cprops->bwa_wd); + mpam_set_feature(mpam_feat_mbw_max, &cfg); + break; default: return -EINVAL; } diff --git a/include/linux/resctrl_types.h b/include/linux/resctrl_types.h index debba6674578c..8cdbaf2eb6074 100644 --- a/include/linux/resctrl_types.h +++ b/include/linux/resctrl_types.h @@ -94,6 +94,7 @@ enum resctrl_res_level { RDT_RESOURCE_L2_PRI, RDT_RESOURCE_MB_PRI, RDT_RESOURCE_MB_HDL, + RDT_RESOURCE_MB_OPT, #endif /* Must be the last */ -- 2.43.0