[PATCH] perf/arm-cmn: Fix multi-filter encoding
Ilkka Koskinen
ilkka at os.amperecomputing.com
Tue Sep 15 14:53:02 PDT 2026
On Mon, 14 Sep 2026, Robin Murphy wrote:
> The current special-case for EVICT_STATE_SEL filtering effectively
> assigns the "filter" and "filter2" controls in the opposite order from
> how the CMN S3 r2 TRM states "Filtering is programmed in pmu_hbt_lbt_sel
> and pmu_evict_state_sel". On reflection, not only does this seem
> unnecessarily non-obvious to users, but it's also likely to be a problem
> for scaling to a full multi-filter abstraction in future. There is a
> logical order to filters based on their bitfield positions in the
> pmu_event_sel register, which the TRM descriptions allude to, and the
> cmn_filter_select enum already (almost) follows, so let's fix the UABI
> to follow suit while it's still unreleased.
>
> Fixes: 09178f536bb9 ("perf/arm-cmn: Plumb in new filter types")
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
Looks reasonable,
Reviewed-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
> ---
> drivers/perf/arm-cmn.c | 54 ++++++++++++++++++++++++------------------
> 1 file changed, 31 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index b162de3d9d16..6464b815bd3b 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -305,9 +305,9 @@ enum cmn_filter_select {
> SEL_NONE,
> SEL_OCCUP1_ID,
> SEL_CLASS_OCCUP_ID,
> - SEL_CBUSY_SNTHROTTLE_SEL,
> SEL_HBT_LBT_SEL,
> SEL_SN_HOME_SEL,
> + SEL_CBUSY_SNTHROTTLE_SEL,
> SEL_SNP_VC_SEL,
> SEL_ENHANCED_HBT_LBT_SEL,
> SEL_EVICT_STATE_SEL,
> @@ -978,10 +978,14 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
> _CMN_EVENT_HNS(_model, _name##_all, _event, _sel, 0), \
> _CMN_EVENT_HNS(_model, _name##_hbt, _event, _sel, 1), \
> _CMN_EVENT_HNS(_model, _name##_lbt, _event, _sel, 2)
> -#define _CMN_EVENT_HNS_HBT2(_model, _name, _event, _fsel1, f1) \
> - _CMN_EVENT_HNS(_model, _name##_all, _event, _fsel1, f1, SEL_HBT_LBT_SEL, 0), \
> - _CMN_EVENT_HNS(_model, _name##_hbt, _event, _fsel1, f1, SEL_HBT_LBT_SEL, 1), \
> - _CMN_EVENT_HNS(_model, _name##_lbt, _event, _fsel1, f1, SEL_HBT_LBT_SEL, 2)
> +#define _CMN_EVENT_HNS_EVICT(_model, _name, _event, _fsel1, f1) \
> + _CMN_EVENT_HNS(_model, _name##_all, _event, _fsel1, f1, SEL_EVICT_STATE_SEL, 0), \
> + _CMN_EVENT_HNS(_model, _name##_eu, _event, _fsel1, f1, SEL_EVICT_STATE_SEL, 1), \
> + _CMN_EVENT_HNS(_model, _name##_en, _event, _fsel1, f1, SEL_EVICT_STATE_SEL, 2), \
> + _CMN_EVENT_HNS(_model, _name##_su, _event, _fsel1, f1, SEL_EVICT_STATE_SEL, 3), \
> + _CMN_EVENT_HNS(_model, _name##_sn, _event, _fsel1, f1, SEL_EVICT_STATE_SEL, 4), \
> + _CMN_EVENT_HNS(_model, _name##_mu, _event, _fsel1, f1, SEL_EVICT_STATE_SEL, 5), \
> + _CMN_EVENT_HNS(_model, _name##_mn, _event, _fsel1, f1, SEL_EVICT_STATE_SEL, 6)
>
> #define CMN_EVENT_HNS_OCC(_model, _name, _event) \
> CMN_EVENT_HN_OCC(_model, hns_##_name, CMN_TYPE_HNS, _event), \
> @@ -1014,13 +1018,9 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
> _CMN_EVENT_HNS(CMNS3R2, _name##_ccglcn, _event, SEL_ENHANCED_HBT_LBT_SEL, 5), \
> _CMN_EVENT_HNS(CMNS3R2, _name##_ccgrn, _event, SEL_ENHANCED_HBT_LBT_SEL, 6)
> #define CMN_EVENT_HNS_EVICT(_model, _name, _event) \
> - _CMN_EVENT_HNS_HBT2(_model, _name##_all, _event, SEL_EVICT_STATE_SEL, 0), \
> - _CMN_EVENT_HNS_HBT2(_model, _name##_eu, _event, SEL_EVICT_STATE_SEL, 1), \
> - _CMN_EVENT_HNS_HBT2(_model, _name##_en, _event, SEL_EVICT_STATE_SEL, 2), \
> - _CMN_EVENT_HNS_HBT2(_model, _name##_su, _event, SEL_EVICT_STATE_SEL, 3), \
> - _CMN_EVENT_HNS_HBT2(_model, _name##_sn, _event, SEL_EVICT_STATE_SEL, 4), \
> - _CMN_EVENT_HNS_HBT2(_model, _name##_mu, _event, SEL_EVICT_STATE_SEL, 5), \
> - _CMN_EVENT_HNS_HBT2(_model, _name##_mn, _event, SEL_EVICT_STATE_SEL, 6)
> + _CMN_EVENT_HNS_EVICT(_model, _name##_all, _event, SEL_HBT_LBT_SEL, 0), \
> + _CMN_EVENT_HNS_EVICT(_model, _name##_hbt, _event, SEL_HBT_LBT_SEL, 1), \
> + _CMN_EVENT_HNS_EVICT(_model, _name##_lbt, _event, SEL_HBT_LBT_SEL, 2)
>
> #define CMN_EVENT_HNSR0_HBT(_name, _event) \
> _CMN_EVENT_HNS_HBT(CMN700 | CMNS3R01, _name, _event, SEL_HBT_LBT_SEL)
> @@ -1856,10 +1856,12 @@ static void arm_cmn_val_add_event(struct arm_cmn *cmn, struct arm_cmn_val *val,
>
> val->dtm_count[dtm]++;
>
> + if (sel == SEL_EVICT_STATE_SEL) {
> + val->filter[dtm][sel] = CMN_EVENT_FILTER2(event) + 1;
> + sel = SEL_HBT_LBT_SEL;
> + }
> if (sel)
> val->filter[dtm][sel] = CMN_EVENT_FILTER(event) + 1;
> - if (sel == SEL_EVICT_STATE_SEL)
> - val->filter[dtm][SEL_HBT_LBT_SEL] = CMN_EVENT_FILTER2(event) + 1;
>
> if (type != CMN_TYPE_WP)
> continue;
> @@ -1910,14 +1912,17 @@ static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event)
> if (val->dtm_count[dtm] == CMN_DTM_NUM_COUNTERS)
> goto done;
>
> + if (sel == SEL_EVICT_STATE_SEL) {
> + if (val->filter[dtm][sel] &&
> + val->filter[dtm][sel] != CMN_EVENT_FILTER2(event) + 1)
> + goto done;
> + sel = SEL_HBT_LBT_SEL;
> + }
> +
> if (sel && val->filter[dtm][sel] &&
> val->filter[dtm][sel] != CMN_EVENT_FILTER(event) + 1)
> goto done;
>
> - if (sel == SEL_EVICT_STATE_SEL && val->filter[dtm][SEL_HBT_LBT_SEL] &&
> - val->filter[dtm][SEL_HBT_LBT_SEL] != CMN_EVENT_FILTER2(event) + 1)
> - goto done;
> -
> if (type != CMN_TYPE_WP)
> continue;
>
> @@ -2077,16 +2082,19 @@ static void arm_cmn_event_clear(struct arm_cmn *cmn, struct perf_event *event,
> static int arm_cmn_set_event_filter(struct arm_cmn_node *dn, struct perf_event *event)
> {
> enum cmn_filter_select fsel = to_cmn_hw(event)->filter_sel;
> + bool evict_state = fsel == SEL_EVICT_STATE_SEL;
> int ret = 0;
>
> + if (evict_state) {
> + ret = arm_cmn_set_event_sel_hi(dn, fsel, CMN_EVENT_FILTER2(event));
> + fsel = SEL_HBT_LBT_SEL;
> + }
> if (fsel)
> ret = arm_cmn_set_event_sel_hi(dn, fsel, CMN_EVENT_FILTER(event));
>
> - if (fsel == SEL_EVICT_STATE_SEL && !ret) {
> - ret = arm_cmn_set_event_sel_hi(dn, SEL_HBT_LBT_SEL, CMN_EVENT_FILTER2(event));
> - if (ret)
> - dn->filter[fsel].count--;
> - }
> + if (ret && evict_state)
> + dn->filter[SEL_EVICT_STATE_SEL].count--;
> +
> return ret;
> }
>
> --
> 2.54.0.dirty
>
>
More information about the linux-arm-kernel
mailing list