hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/8420 ------------------ Because it needs to support mixed systems that include MSCs with and without Narrow-PARTID support, there are the following incompatible control issues. If an MSC does not support Narrow-PARTID and its control method is not of the "partition bitmap" type, then delivering the resctrl control group configuration across multiple PARTIDs will change the user's expected behavior. Currently, the original semantics of MBMAX (and MBMIN) cannot be guaranteed through simple configuration of different control values. So here decide to restrict the usage scenarios of this feature. When we find that the MSC does not support the Narrow-PARTID feature: 1. And if a control group modifies its MBMAX/MBMIN configuration, it cannot be allowed to create monitoring sub-groups by reqPartids. 2. And If a control group has created monitoring sub-groups by reqPartids, it cannot be allowed to modify MBMAX/MBMIN configuration. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_resctrl.c | 97 +++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 8b5ca4ec99ee..196c48fe1805 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -1260,9 +1260,71 @@ void update_rmid_entries_for_reqpartid(u32 reqpartid) update_rmid_entry(closid, req_pmg2rmid(reqpartid, pmg)); } +static int check_narrow_mkdir_limit(u32 closid) +{ + u32 intpartid; + struct rdt_domain *d; + struct mpam_props *cprops; + struct mpam_resctrl_res *res; + struct mpam_resctrl_dom *dom; + struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_MBA); + struct rdt_resource *r_min = resctrl_arch_get_resource(RDT_RESOURCE_MB_MIN); + + if (cdp_enabled) + intpartid = resctrl_get_config_index(closid, CDP_DATA); + else + intpartid = resctrl_get_config_index(closid, CDP_NONE); + + res = container_of(r, struct mpam_resctrl_res, resctrl_res); + cprops = &res->class->props; + + if (mpam_has_feature(mpam_feat_partid_nrw, cprops)) + return 0; + + if (get_num_reqpartid() == resctrl_arch_get_num_closid(NULL)) + return 0; + + /* Config has changed */ + list_for_each_entry(d, &r->domains, list) { + dom = container_of(d, struct mpam_resctrl_dom, resctrl_dom); + + if (dom->comp->cfg[intpartid].mbw_max != + percent_to_mbw_max(r->default_ctrl, cprops->bwa_wd)) + return -ENOSPC; + + if (dom->comp->cfg[intpartid].mbw_min != + percent_to_mbw_max(r_min->default_ctrl, cprops->bwa_wd)) + return -ENOSPC; + } + + return 0; +} + +static int mpam_sync_config(u32 intpartid) +{ + struct mpam_component *comp; + struct mpam_class *class; + int err; + + list_for_each_entry(class, &mpam_classes, classes_list) { + list_for_each_entry(comp, &class->components, class_list) { + err = mpam_apply_config(comp, intpartid, + &comp->cfg[intpartid], true); + if (err) + return err; + } + } + + return 0; +} + int resctrl_arch_expand_rmid(u32 closid) { - int i; + int i, err; + + err = check_narrow_mkdir_limit(closid); + if (err) + return err; for (i = resctrl_arch_get_num_closid(NULL); i < get_num_reqpartid(); i++) { @@ -1484,6 +1546,31 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, } } +static int check_narrow_config_limit(struct rdt_resource *r, u32 intpartid, + struct mpam_props *cprops, u32 cfg_val) +{ + int reqpartid; + int req_num = get_num_reqpartid(); + int closid_num = resctrl_arch_get_num_closid(NULL); + + if (mpam_has_feature(mpam_feat_partid_nrw, cprops)) + return 0; + + if (req_num == closid_num) + return 0; + + if (cfg_val == r->default_ctrl) + return 0; + + /* Already deploys reqPartid */ + for (reqpartid = closid_num; reqpartid < req_num; reqpartid++) { + if (req2intpartid(reqpartid) == intpartid) + return -EPERM; + } + + return 0; +} + int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, u32 closid, enum resctrl_conf_type t, u32 cfg_val) { @@ -1540,12 +1627,20 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, mpam_set_feature(mpam_feat_mbw_part, &cfg); break; } else if (mpam_has_feature(mpam_feat_mbw_max, cprops)) { + err = check_narrow_config_limit(r, partid, cprops, cfg_val); + if (err) + return err; + cfg.mbw_max = percent_to_mbw_max(cfg_val, cprops->bwa_wd); mpam_set_feature(mpam_feat_mbw_max, &cfg); break; } return -EINVAL; case RDT_RESOURCE_MB_MIN: + err = check_narrow_config_limit(r, partid, cprops, cfg_val); + if (err) + return err; + cfg.mbw_min = percent_to_mbw_max(cfg_val, cprops->bwa_wd); mpam_set_feature(mpam_feat_mbw_min, &cfg); break; -- 2.25.1