From 09178f536bb9c659953364639de6564848fa1c21 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Tue, 28 Jul 2026 16:59:24 +0100 Subject: [PATCH] perf/arm-cmn: Plumb in new filter types Add the logic to handle events with the upcoming new filter controls. Since for now we will have the sole invariant of all EVICT_STATE_SEL events having HBT_LBT_SEL as a secondary filter, for the sake of simplicity we can just special-case that, and save the complication of a full multi-filter abstraction until unavoidably necessary. Reviewed-by: Leo Yan Signed-off-by: Robin Murphy Reviewed-by: Ilkka Koskinen Signed-off-by: Will Deacon --- drivers/perf/arm-cmn.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index 74bc2aae4a06..e25f46c38c23 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -166,12 +166,14 @@ #define CMN_CONFIG_FILTER GENMASK_ULL(30, 27) #define CMN_CONFIG_BYNODEID BIT_ULL(31) #define CMN_CONFIG_NODEID GENMASK_ULL(47, 32) +#define CMN_CONFIG_FILTER2 GENMASK_ULL(51, 48) #define CMN_EVENT_TYPE(event) FIELD_GET(CMN_CONFIG_TYPE, (event)->attr.config) #define CMN_EVENT_EVENTID(event) FIELD_GET(CMN_CONFIG_EVENTID, (event)->attr.config) #define CMN_EVENT_FILTER(event) FIELD_GET(CMN_CONFIG_FILTER, (event)->attr.config) #define CMN_EVENT_BYNODEID(event) FIELD_GET(CMN_CONFIG_BYNODEID, (event)->attr.config) #define CMN_EVENT_NODEID(event) FIELD_GET(CMN_CONFIG_NODEID, (event)->attr.config) +#define CMN_EVENT_FILTER2(event) FIELD_GET(CMN_CONFIG_FILTER2, (event)->attr.config) #define CMN_CONFIG_WP_COMBINE GENMASK_ULL(30, 27) #define CMN_CONFIG_WP_DEV_SEL GENMASK_ULL(50, 48) @@ -284,6 +286,9 @@ enum cmn_filter_select { SEL_CBUSY_SNTHROTTLE_SEL, SEL_HBT_LBT_SEL, SEL_SN_HOME_SEL, + SEL_SNP_VC_SEL, + SEL_ENHANCED_HBT_LBT_SEL, + SEL_EVICT_STATE_SEL, SEL_MAX }; @@ -1377,6 +1382,7 @@ static struct attribute *arm_cmn_format_attrs[] = { CMN_FORMAT_ATTR(filter, CMN_CONFIG_FILTER), CMN_FORMAT_ATTR(bynodeid, CMN_CONFIG_BYNODEID), CMN_FORMAT_ATTR(nodeid, CMN_CONFIG_NODEID), + CMN_FORMAT_ATTR(filter2, CMN_CONFIG_FILTER2), CMN_FORMAT_ATTR(wp_dev_sel, CMN_CONFIG_WP_DEV_SEL), CMN_FORMAT_ATTR(wp_chn_sel, CMN_CONFIG_WP_CHN_SEL), @@ -1745,6 +1751,8 @@ static void arm_cmn_val_add_event(struct arm_cmn *cmn, struct arm_cmn_val *val, 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; @@ -1799,6 +1807,10 @@ static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event) 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; @@ -1943,6 +1955,8 @@ static void arm_cmn_event_clear(struct arm_cmn *cmn, struct perf_event *event, if (hw->filter_sel) hw->dn[i].filter[hw->filter_sel].count--; + if (hw->filter_sel == SEL_EVICT_STATE_SEL) + hw->dn[i].filter[SEL_HBT_LBT_SEL].count--; dtm->pmu_config_low &= ~CMN__PMEVCNT_PAIRED(dtm_idx); writel_relaxed(dtm->pmu_config_low, dtm->base + CMN_DTM_PMU_CONFIG); @@ -1961,6 +1975,11 @@ static int arm_cmn_set_event_filter(struct arm_cmn_node *dn, struct perf_event * 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--; + } return ret; }