[PATCH OLK-6.6 0/7] Support MATA monitor feature for MPAM

Zeng Heng (7): arm64/mpam: Support MATA monitor feature for MPAM arm64/mpam: Add judgment to distinguish MSMON_MBWU_CAPTURE definition arm64/mpam: fix MBA granularity conversion formula arm64/mpam: fix bug in percent_to_mbw_max() arm64/mpam: Fix out-of-bound access of mbwu_state array arm64/mpam: Fix out-of-bound access of cfg array arm64/mpam: Improve conversion accuracy between percent and fixed-point fraction drivers/platform/mpam/mpam_devices.c | 31 ++++++++++--- drivers/platform/mpam/mpam_resctrl.c | 68 ++++++++++++++++++---------- fs/resctrl/monitor.c | 42 ++++++++++++----- 3 files changed, 98 insertions(+), 43 deletions(-) -- 2.25.1

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/14934 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/S... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/14934 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/S...

hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8T2RT -------------------------------- To support the MB monitoring feature, provide mbm_total_bytes interface under the resctrl fs to monitor the MATA memory bandwidth. In fact, resctrl does not mandate that MBM should work in the mode of free running, so even if the number of monitor instances doesn't meet the number of resctrl has control/monitor groups, it will not affect the monitoring function. Fixes: dc2005d467b3 ("untested: arm_mpam: resctrl: Add support for mbm counters") Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_resctrl.c | 8 ------ fs/resctrl/monitor.c | 42 ++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 38e53c46a9ec..4e5e54c90388 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -473,14 +473,6 @@ static bool class_has_usable_mbwu(struct mpam_class *class) if (!mpam_has_feature(mpam_feat_msmon_mbwu, cprops)) return false; - /* - * resctrl expects the bandwidth counters to be free running, - * which means we need as many monitors as resctrl has - * control/monitor groups. - */ - if (cprops->num_mbwu_mon < resctrl_arch_system_num_rmid_idx()) - return false; - return (mpam_partid_max > 1) || (mpam_pmg_max != 0); } diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c index 68401ca0827a..cecd98fdb85e 100644 --- a/fs/resctrl/monitor.c +++ b/fs/resctrl/monitor.c @@ -817,29 +817,30 @@ static void l3_mon_evt_init(struct rdt_resource *r) { INIT_LIST_HEAD(&r->evt_list); - if (resctrl_arch_is_llc_occupancy_enabled()) + if ((r->rid == RDT_RESOURCE_L3) && + resctrl_arch_is_llc_occupancy_enabled()) { list_add_tail(&llc_occupancy_event.list, &r->evt_list); - if (resctrl_arch_is_mbm_total_enabled()) + + if (resctrl_arch_is_mbm_local_enabled()) + list_add_tail(&mbm_local_event.list, &r->evt_list); + } + + if ((r->rid == RDT_RESOURCE_MBA) && + resctrl_arch_is_mbm_total_enabled()) list_add_tail(&mbm_total_event.list, &r->evt_list); - if (resctrl_arch_is_mbm_local_enabled()) - list_add_tail(&mbm_local_event.list, &r->evt_list); } -int resctrl_mon_resource_init(void) +static int __resctrl_mon_resource_init(enum resctrl_res_level res) { - struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3); - int ret; + struct rdt_resource *r = resctrl_arch_get_resource(res); if (!r->mon_capable) return 0; - ret = dom_data_init(r); - if (ret) - return ret; - l3_mon_evt_init(r); - if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_TOTAL_EVENT_ID)) { + if ((r->rid == RDT_RESOURCE_MBA) && + resctrl_arch_is_evt_configurable(QOS_L3_MBM_TOTAL_EVENT_ID)) { mbm_total_event.configurable = true; mbm_config_rftype_init("mbm_total_bytes_config"); } @@ -851,6 +852,23 @@ int resctrl_mon_resource_init(void) return 0; } +int resctrl_mon_resource_init(void) +{ + struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3); + int ret; + + if (!r->mon_capable) + return 0; + + ret = dom_data_init(r); + if (ret) + return ret; + + __resctrl_mon_resource_init(RDT_RESOURCE_L3); + __resctrl_mon_resource_init(RDT_RESOURCE_MBA); + return 0; +} + void resctrl_mon_resource_exit(void) { struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3); -- 2.25.1

hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8T2RT -------------------------------- Because MSMON_MBWU_CAPTURE register is implemented in different definition according to the corresponding versions of the protocol. This would affect mbm_total_bytes interface returns the various result. Consequently, it is necessary to determine the specification definition followed by according to the chip model. Fixes: 21ac9fc8f275 ("arm_mpam: Track bandwidth counter state for overflow and power management") Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_devices.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/platform/mpam/mpam_devices.c b/drivers/platform/mpam/mpam_devices.c index 19bd40814685..719c8d404526 100644 --- a/drivers/platform/mpam/mpam_devices.c +++ b/drivers/platform/mpam/mpam_devices.c @@ -915,6 +915,12 @@ static u64 mpam_msmon_overflow_val(struct mpam_msc_ris *ris) return GENMASK_ULL(30, 0); } +static const struct midr_range mbwu_flowrate_list[] = { + MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), + MIDR_ALL_VERSIONS(MIDR_HISI_LINXICORE9100), + { /* sentinel */ } +}; + static void __ris_msmon_read(void *arg) { bool nrdy = false; @@ -986,6 +992,18 @@ static void __ris_msmon_read(void *arg) if (!mbwu_state) break; + /* + * Following the definition of the DDI0598 version, + * the value field of MPAM Memory Bandwidth Usage Monitor Register + * indicates the memory bandwidth usage in bytes per second, + * instead the scaled count of bytes transferred since the monitor + * was last reset in the latest version (DDI0598D_b). + */ + if (ris->comp->class->type == MPAM_CLASS_MEMORY) { + if (is_midr_in_range_list(read_cpuid_id(), mbwu_flowrate_list)) + break; + } + /* Add any pre-overflow value to the mbwu_state->val */ if (mbwu_state->prev_val > now) overflow_val = mpam_msmon_overflow_val(ris) - mbwu_state->prev_val; -- 2.25.1

hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8T2RT -------------------------------- Correct MBA granularity conversion formula. Fixes: 58db5c68e84a ("untested: arm_mpam: resctrl: Add support for MB resource") Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_resctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 4e5e54c90388..9dc0a970988c 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -505,7 +505,7 @@ static u32 get_mba_granularity(struct mpam_props *cprops) * bwa_wd is the number of bits implemented in the 0.xxx * fixed point fraction. 1 bit is 50%, 2 is 25% etc. */ - return MAX_MBA_BW / (cprops->bwa_wd + 1); + return MAX_MBA_BW / (1 << cprops->bwa_wd); } return 0; -- 2.25.1

hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8T2RT -------------------------------- Correct percentage to fixed floating point conversion formula. Fixes: 58db5c68e84a ("untested: arm_mpam: resctrl: Add support for MB resource") Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_resctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 9dc0a970988c..364b1a96e77f 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -567,7 +567,7 @@ static u16 percent_to_mbw_max(u8 pc, struct mpam_props *cprops) break; } - value &= GENMASK(15, 15 - cprops->bwa_wd); + value &= GENMASK(15, 15 - cprops->bwa_wd + 1); return value; } -- 2.25.1

hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAFGJ6 --------------------------------------------------- The mbwu_state array is allocated according to the monitor number. However when select the monitor the index is encoded by closid and rmid, which may exceed the monitor number. If the KASAN config is enabled, we would find the following error when create new monitors: BUG: KASAN: slab-use-after-free in mpam_msmon_reset_mbwu+0x3b8/0x450 Write of size 1 at addr ffff0800c2350fa1 by task kworker/0:0/8 In addition, the statistics of mbwu monitors are cumulative values, which are different type with csu monitors, so need to make sure use the same monitor between twice readings. Here we adapt the remainder of rmid to the num_mbwu_mon as a compromise, if the mbwu monitor number of system can't support free run mode. Fixes: dc2005d467b3 ("untested: arm_mpam: resctrl: Add support for mbm counters") Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_resctrl.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 364b1a96e77f..7ee7c1cc0e7d 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -336,8 +336,10 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d, { int err; u64 cdp_val; + u16 num_mbwu_mon; struct mon_cfg cfg; struct mpam_resctrl_dom *dom; + struct mpam_resctrl_res *res; u32 mon = *(u32 *)arch_mon_ctx; enum mpam_device_features type; @@ -358,8 +360,16 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d, } cfg.mon = mon; - if (cfg.mon == USE_RMID_IDX) - cfg.mon = resctrl_arch_rmid_idx_encode(closid, rmid); + if (cfg.mon == USE_RMID_IDX) { + /* + * The number of mbwu monitors can't support free run mode, + * adapt the remainder of rmid to the num_mbwu_mon as a + * compromise. + */ + res = container_of(r, struct mpam_resctrl_res, resctrl_res); + num_mbwu_mon = res->class->props.num_mbwu_mon; + cfg.mon = resctrl_arch_rmid_idx_encode(closid, rmid) % num_mbwu_mon; + } cfg.match_pmg = true; cfg.pmg = rmid; @@ -386,13 +396,17 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d, void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d, u32 closid, u32 rmid, enum resctrl_event_id eventid) { + u16 num_mbwu_mon; struct mon_cfg cfg; struct mpam_resctrl_dom *dom; + struct mpam_resctrl_res *res; if (eventid != QOS_L3_MBM_LOCAL_EVENT_ID) return; - cfg.mon = resctrl_arch_rmid_idx_encode(closid, rmid); + res = container_of(r, struct mpam_resctrl_res, resctrl_res); + num_mbwu_mon = res->class->props.num_mbwu_mon; + cfg.mon = resctrl_arch_rmid_idx_encode(closid, rmid) % num_mbwu_mon; cfg.match_pmg = true; cfg.pmg = rmid; -- 2.25.1

hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAFGJ6 -------------------------------- The cfg array of per msc component is allocated according to the partid number. The length of array should be (mpam_partid_max + 1) instead of mpam_partid_max. Otherwise, when resctrl_arch_get_config() accesses the array would raise slab-out-of-bounds fault like below: BUG: KASAN: slab-out-of-bounds in resctrl_arch_get_config+0x404/0x7c8 Read of size 4 at addr ffff08280da29b64 by task mkdir/4156 Fixes: be74872ad2e3 ("arm_mpam: Allow configuration to be applied and restored during cpu online") Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_devices.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/platform/mpam/mpam_devices.c b/drivers/platform/mpam/mpam_devices.c index 719c8d404526..5ffa3cc8fb82 100644 --- a/drivers/platform/mpam/mpam_devices.c +++ b/drivers/platform/mpam/mpam_devices.c @@ -1247,7 +1247,7 @@ struct reprogram_ris { /* Call with MSC lock held */ static int mpam_reprogram_ris(void *_arg) { - u16 partid, partid_max; + u16 partid, num_partid; struct reprogram_ris *arg = _arg; struct mpam_msc_ris *ris = arg->ris; struct mpam_config *cfg = arg->cfg; @@ -1256,9 +1256,9 @@ static int mpam_reprogram_ris(void *_arg) return 0; spin_lock(&partid_max_lock); - partid_max = mpam_partid_max; + num_partid = resctrl_arch_get_num_closid(NULL); spin_unlock(&partid_max_lock); - for (partid = 0; partid < partid_max; partid++) + for (partid = 0; partid < num_partid; partid++) mpam_reprogram_ris_partid(ris, partid, cfg); return 0; @@ -1414,7 +1414,7 @@ static void mpam_reprogram_msc(struct mpam_msc *msc) } reset = true; - for (partid = 0; partid < mpam_partid_max; partid++) { + for (partid = 0; partid < resctrl_arch_get_num_closid(NULL); partid++) { cfg = &ris->comp->cfg[partid]; if (cfg->features) reset = false; @@ -2117,7 +2117,8 @@ static int __allocate_component_cfg(struct mpam_component *comp) if (comp->cfg) return 0; - comp->cfg = kcalloc(mpam_partid_max, sizeof(*comp->cfg), GFP_KERNEL); + comp->cfg = kcalloc(resctrl_arch_get_num_closid(NULL), + sizeof(*comp->cfg), GFP_KERNEL); if (!comp->cfg) return -ENOMEM; @@ -2229,7 +2230,7 @@ void mpam_reset_class(struct mpam_class *class) idx = srcu_read_lock(&mpam_srcu); list_for_each_entry_rcu(comp, &class->components, class_list) { - memset(comp->cfg, 0, (mpam_partid_max * sizeof(*comp->cfg))); + memset(comp->cfg, 0, resctrl_arch_get_num_closid(NULL) * sizeof(*comp->cfg)); list_for_each_entry_rcu(ris, &comp->ris, comp_list) { mutex_lock(&ris->msc->lock); -- 2.25.1

hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAKAKN -------------------------------- According to the bit width of the fixed-point fraction implemented by hardware, the maximum supported precision is calculated to reduce the conversion granularity as much as possible, so that improving conversion accuracy between percent and fixed-point fraction. Fixes: 58db5c68e84a ("untested: arm_mpam: resctrl: Add support for MB resource") Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_resctrl.c | 38 ++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 7ee7c1cc0e7d..edfb58523a59 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -536,18 +536,28 @@ static u32 mbw_pbm_to_percent(unsigned long mbw_pbm, struct mpam_props *cprops) return result; } -static u32 mbw_max_to_percent(u16 mbw_max, struct mpam_props *cprops) +static int get_wd_precision(u8 wd) +{ + int ret = (1 << wd) / MAX_MBA_BW; + + if (!ret) + return 1; + + return ret; +} + +static u32 mbw_max_to_percent(u16 mbw_max, u8 wd) { u8 bit; - u32 divisor = 2, value = 0; + u32 divisor = 2, value = 0, precision = get_wd_precision(wd); for (bit = 15; bit; bit--) { if (mbw_max & BIT(bit)) - value += MAX_MBA_BW / divisor; + value += MAX_MBA_BW * precision / divisor; divisor <<= 1; } - return value; + return DIV_ROUND_UP(value, precision); } static u32 percent_to_mbw_pbm(u8 pc, struct mpam_props *cprops) @@ -562,26 +572,28 @@ static u32 percent_to_mbw_pbm(u8 pc, struct mpam_props *cprops) return (1 << num_bits) - 1; } -static u16 percent_to_mbw_max(u8 pc, struct mpam_props *cprops) +static u16 percent_to_mbw_max(u8 pc, u8 wd) { u8 bit; - u32 divisor = 2, value = 0; + u32 divisor = 2, value = 0, precision = get_wd_precision(wd); - if (WARN_ON_ONCE(cprops->bwa_wd > 15)) + if (WARN_ON_ONCE(wd > 15)) return MAX_MBA_BW; + pc *= precision; + for (bit = 15; bit; bit--) { - if (pc >= MAX_MBA_BW / divisor) { - pc -= MAX_MBA_BW / divisor; + if (pc >= MAX_MBA_BW * precision / divisor) { + pc -= MAX_MBA_BW * precision / divisor; value |= BIT(bit); } divisor <<= 1; - if (!pc || !(MAX_MBA_BW / divisor)) + if (!pc || !(MAX_MBA_BW * precision / divisor)) break; } - value &= GENMASK(15, 15 - cprops->bwa_wd + 1); + value &= GENMASK(15, 15 - wd + 1); return value; } @@ -947,7 +959,7 @@ 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); + return mbw_max_to_percent(cfg->mbw_max, cprops->bwa_wd); default: return -EINVAL; } @@ -989,7 +1001,7 @@ 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)) { - cfg.mbw_max = percent_to_mbw_max(cfg_val, cprops); + cfg.mbw_max = percent_to_mbw_max(cfg_val, cprops->bwa_wd); mpam_set_feature(mpam_feat_mbw_max, &cfg); break; } -- 2.25.1
participants (2)
-
patchwork bot
-
Zeng Heng