hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/9840 ------------------ Add support for the MBWU (Memory Bandwidth Usage) counter scaling feature as defined in the ARM MPAM specification. This allows hardware to report bandwidth usage with granularity by applying a scaling factor to raw counter values. The scaling factor is extracted from MPAMF_MBWUMON_IDR.SCALE field during hardware probing. When scale bit is enabled, extend the measurable range by 2^scale while reducing granularity accordingly. The scaling is applied to: - Overflow threshold calculations - Raw counter value readings This feature is mutually exclusive with the "long" counter format, as both provide alternative mechanisms for extending the effective range of bandwidth measurements. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_devices.c | 21 ++++++++++++++++----- drivers/platform/mpam/mpam_internal.h | 3 +++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/platform/mpam/mpam_devices.c b/drivers/platform/mpam/mpam_devices.c index 62b7ae418a882..3e875f29bd03b 100644 --- a/drivers/platform/mpam/mpam_devices.c +++ b/drivers/platform/mpam/mpam_devices.c @@ -745,6 +745,14 @@ static void mpam_ris_hw_probe(struct mpam_msc_ris *ris) else mpam_set_feature(mpam_feat_msmon_mbwu_44counter, props); } + + if (!has_long) { + props->mbwu_scale = FIELD_GET(MPAMF_MBWUMON_IDR_SCALE, mbwumonidr); + if (props->mbwu_scale) + mpam_set_feature(mpam_feat_msmon_mbwu_scale, props); + } else { + props->mbwu_scale = 0; + } } } @@ -909,6 +917,9 @@ static void gen_msmon_ctl_flt_vals(struct mon_read *m, u32 *ctl_val, */ *ctl_val |= MSMON_CFG_x_CTL_MATCH_PARTID; + if (mpam_has_feature(mpam_feat_msmon_mbwu_scale, &m->ris->props)) + *ctl_val |= MSMON_CFG_x_CTL_SCLEN; + *flt_val = FIELD_PREP(MSMON_CFG_MBWU_FLT_PARTID, ctx->partid); *flt_val |= FIELD_PREP(MSMON_CFG_MBWU_FLT_RWBW, ctx->opts); if (m->ctx->match_pmg) { @@ -995,7 +1006,8 @@ static u64 mpam_msmon_overflow_val(struct mpam_msc_ris *ris) else if (mpam_has_feature(mpam_feat_msmon_mbwu_44counter, &ris->props)) return GENMASK_ULL(43, 0); else - return GENMASK_ULL(30, 0); + /* Only non-long MBWU counter enables scale */ + return GENMASK_ULL(30, 0) << ris->props.mbwu_scale; } bool resctrl_arch_would_mbm_overflow(void) @@ -1044,7 +1056,7 @@ static void __ris_msmon_read(void *arg) unsigned long flags; bool config_mismatch; struct mon_read *m = arg; - u64 now, overflow_val = 0; + u64 now; bool mbwu_overflow = false; struct mon_cfg *ctx = m->ctx; bool reset_on_next_read = false; @@ -1120,6 +1132,7 @@ static void __ris_msmon_read(void *arg) now = mpam_read_monsel_reg(msc, MBWU); nrdy = now & MSMON___NRDY; now = FIELD_GET(MSMON___VALUE, now); + now <<= ris->props.mbwu_scale; } if (config_mismatch && !mpam_ris_has_nrdy_bit(ris)) @@ -1145,9 +1158,7 @@ static void __ris_msmon_read(void *arg) /* Add any pre-overflow value to the mbwu_state->val */ if (mbwu_overflow) - overflow_val = mpam_msmon_overflow_val(ris); - - mbwu_state->correction += overflow_val; + mbwu_state->correction += mpam_msmon_overflow_val(ris); /* Include bandwidth consumed before the last hardware reset */ now += mbwu_state->correction; diff --git a/drivers/platform/mpam/mpam_internal.h b/drivers/platform/mpam/mpam_internal.h index ebb6d7357a980..70d4abb93fd19 100644 --- a/drivers/platform/mpam/mpam_internal.h +++ b/drivers/platform/mpam/mpam_internal.h @@ -110,6 +110,7 @@ enum mpam_device_features { mpam_feat_msmon_mbwu_63counter, mpam_feat_msmon_mbwu_capture, mpam_feat_msmon_mbwu_rwbw, + mpam_feat_msmon_mbwu_scale, mpam_feat_msmon_capt, mpam_feat_partid_nrw, MPAM_FEATURE_LAST, @@ -128,6 +129,7 @@ struct mpam_props u16 dspri_wd; u16 num_csu_mon; u16 num_mbwu_mon; + u8 mbwu_scale; }; #define mpam_has_feature(_feat, x) ((1<<_feat) & (x)->features) @@ -434,6 +436,7 @@ bool mpam_cpbm_hisi_check_invalid(struct rdt_resource *r, unsigned long val); /* MPAMF_MBWUMON_IDR - MPAM memory bandwidth usage monitor ID register */ #define MPAMF_MBWUMON_IDR_NUM_MON GENMASK(15, 0) +#define MPAMF_MBWUMON_IDR_SCALE GENMASK(20, 16) #define MPAMF_MBWUMON_IDR_HAS_RWBW BIT(28) #define MPAMF_MBWUMON_IDR_LWD BIT(29) #define MPAMF_MBWUMON_IDR_HAS_LONG BIT(30) -- 2.43.0