hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ID4UC2 -------------------------------- Due to the inaccurate L2 CSU sampling on the specified platform, the L3 cache capacity statistics accumulate error. To avoid this, perform a full re-scan instead of incremental counting. Each time when read the L3 CSU monitor, we forcibly reconfigure it so that the hardware rescans the L3 cache capacity. Note that the first read of the L3 CSU usually returns EBUSY, so a second read is required. On the second attempt, skip forcibly reconfigure the monitor, preventing another EBUSY and ensuring the correct result. Fixes: bb66b4d115e5 ("arm_mpam: Add mpam_msmon_read() to read monitor value") Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_devices.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/platform/mpam/mpam_devices.c b/drivers/platform/mpam/mpam_devices.c index 30e4ce54a3c4..ebc8887d8267 100644 --- a/drivers/platform/mpam/mpam_devices.c +++ b/drivers/platform/mpam/mpam_devices.c @@ -909,6 +909,27 @@ static void read_msmon_ctl_flt_vals(struct mon_read *m, u32 *ctl_val, } } +static bool mpam_csu_hisi_need_retrigger(struct mpam_msc_ris *ris, + bool read_again) +{ + static const struct midr_range cpus[] = { + MIDR_ALL_VERSIONS(MIDR_HISI_HIP12), + { /* sentinel */ } + }; + + if (ris->comp->class->type != MPAM_CLASS_CACHE || + ris->comp->class->level != 3) + return false; + + if (!is_midr_in_range_list(cpus)) + return false; + + if (read_again) + return false; + + return true; +} + static void write_msmon_ctl_flt_vals(struct mon_read *m, u32 ctl_val, u32 flt_val) { @@ -1047,7 +1068,8 @@ static void __ris_msmon_read(void *arg) config_mismatch = cur_flt != flt_val || cur_ctl != (ctl_val | MSMON_CFG_x_CTL_EN); - if (config_mismatch || reset_on_next_read) { + if (config_mismatch || reset_on_next_read || + mpam_csu_hisi_need_retrigger(ris, m->err == -EBUSY)) { write_msmon_ctl_flt_vals(m, ctl_val, flt_val); if (mbwu_state) { mbwu_state->prev_val = 0; @@ -1190,6 +1212,7 @@ int mpam_msmon_read(struct mpam_component *comp, struct mon_cfg *ctx, arg.ctx = ctx; arg.type = type; arg.val = val; + arg.err = 0; *val = 0; return _msmon_read(comp, &arg); @@ -1448,7 +1471,7 @@ static int mpam_reprogram_ris(void *_arg) static int mpam_restore_mbwu_state(void *_ris) { int i; - struct mon_read mwbu_arg; + struct mon_read mwbu_arg = {}; struct mpam_msc_ris *ris = _ris; for (i = 0; i < ris->props.num_mbwu_mon; i++) { -- 2.25.1