* [PATCH v2] perf/arm-cmn: Fix multi-filter encoding
@ 2026-09-15 12:24 Robin Murphy
2026-09-15 12:32 ` sashiko-bot
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Robin Murphy @ 2026-09-15 12:24 UTC (permalink / raw)
To: will; +Cc: mark.rutland, ilkka, leo.yan, linux-perf-users, linux-arm-kernel
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@arm.com>
---
v2: Also fix filter lookup order and missing return in set_event_filter
drivers/perf/arm-cmn.c | 58 +++++++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 24 deletions(-)
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index b162de3d9d16..33e8a040c903 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;
@@ -1946,7 +1951,7 @@ static enum cmn_filter_select arm_cmn_event_filter(const struct arm_cmn *cmn,
for (int i = 0; i < ARRAY_SIZE(arm_cmn_event_attrs) - 1; i++) {
e = container_of(arm_cmn_event_attrs[i], typeof(*e), attr.attr);
if (e->model & model && e->type == type && e->eventid == eventid)
- return e->filter[0].sel;
+ return e->filter[1].sel ?: e->filter[0].sel;
}
return SEL_NONE;
}
@@ -2077,16 +2082,21 @@ 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));
+ if (ret)
+ return ret;
+ 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
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v2] perf/arm-cmn: Fix multi-filter encoding 2026-09-15 12:24 [PATCH v2] perf/arm-cmn: Fix multi-filter encoding Robin Murphy @ 2026-09-15 12:32 ` sashiko-bot 2026-09-16 9:31 ` Leo Yan ` (2 subsequent siblings) 3 siblings, 0 replies; 6+ messages in thread From: sashiko-bot @ 2026-09-15 12:32 UTC (permalink / raw) To: Robin Murphy; +Cc: linux-perf-users > 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@arm.com> Sashiko has reviewed this patch and found no issues. It looks great! -- Sashiko AI review · https://sashiko.dev/#/patchset/ec590cd4cc61b54d6ad3b306b69777ad7729c9d6.1789475062.git.robin.murphy@arm.com?part=1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] perf/arm-cmn: Fix multi-filter encoding 2026-09-15 12:24 [PATCH v2] perf/arm-cmn: Fix multi-filter encoding Robin Murphy 2026-09-15 12:32 ` sashiko-bot @ 2026-09-16 9:31 ` Leo Yan 2026-09-16 15:27 ` Robin Murphy 2026-09-17 1:51 ` Ilkka Koskinen 2026-09-18 12:28 ` Will Deacon 3 siblings, 1 reply; 6+ messages in thread From: Leo Yan @ 2026-09-16 9:31 UTC (permalink / raw) To: Robin Murphy Cc: will, mark.rutland, ilkka, linux-perf-users, linux-arm-kernel On Tue, Sep 15, 2026 at 01:24:22PM +0100, 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@arm.com> It's hard to say how useful my review is, but I went through the patch and also asked AI to explain the rationale. It makes sense to me: Reviewed-by: Leo Yan <leo.yan@arm.com> Seems we could implement a generic way to navigate filters based on the hardware bitfield ordering, e.g. filter_next(sel) and filter_prev(sel). This can be deferred until we have more combined filters. Thanks, Leo ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] perf/arm-cmn: Fix multi-filter encoding 2026-09-16 9:31 ` Leo Yan @ 2026-09-16 15:27 ` Robin Murphy 0 siblings, 0 replies; 6+ messages in thread From: Robin Murphy @ 2026-09-16 15:27 UTC (permalink / raw) To: Leo Yan; +Cc: will, mark.rutland, ilkka, linux-perf-users, linux-arm-kernel On 16/09/2026 10:31 am, Leo Yan wrote: > On Tue, Sep 15, 2026 at 01:24:22PM +0100, 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@arm.com> > > It's hard to say how useful my review is, but I went through the patch > and also asked AI to explain the rationale. It makes sense to me: > > Reviewed-by: Leo Yan <leo.yan@arm.com> > > Seems we could implement a generic way to navigate filters based on > the hardware bitfield ordering, e.g. filter_next(sel) and > filter_prev(sel). This can be deferred until we have more combined > filters. Yup, that's the direction this was always heading - in the (near-ish) future we definitely are going to have to support different events having overlapping combinations of multiple filters, and even more cases of one event having different filters per CMN model. Thus one option I realised I'd like to keep open, in case arrays get too clunky, is to encode cmn_filter_select values in a bitmap, wherein a mapping of bits to CMN_EVENT_FILTER*() fields could always be implied based on this consistent ordering. Thanks, Robin. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] perf/arm-cmn: Fix multi-filter encoding 2026-09-15 12:24 [PATCH v2] perf/arm-cmn: Fix multi-filter encoding Robin Murphy 2026-09-15 12:32 ` sashiko-bot 2026-09-16 9:31 ` Leo Yan @ 2026-09-17 1:51 ` Ilkka Koskinen 2026-09-18 12:28 ` Will Deacon 3 siblings, 0 replies; 6+ messages in thread From: Ilkka Koskinen @ 2026-09-17 1:51 UTC (permalink / raw) To: Robin Murphy Cc: will, mark.rutland, ilkka, leo.yan, linux-perf-users, linux-arm-kernel On Tue, 15 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@arm.com> Uh, I just realized I replied to v1 although I reviewed v2... Anyway, this patch looks good to me Reviewed-by: Ilkka Koskinen <ilkka@os.amperecomputing.com> > --- > > v2: Also fix filter lookup order and missing return in set_event_filter > > drivers/perf/arm-cmn.c | 58 +++++++++++++++++++++++++----------------- > 1 file changed, 34 insertions(+), 24 deletions(-) > > diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c > index b162de3d9d16..33e8a040c903 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; > > @@ -1946,7 +1951,7 @@ static enum cmn_filter_select arm_cmn_event_filter(const struct arm_cmn *cmn, > for (int i = 0; i < ARRAY_SIZE(arm_cmn_event_attrs) - 1; i++) { > e = container_of(arm_cmn_event_attrs[i], typeof(*e), attr.attr); > if (e->model & model && e->type == type && e->eventid == eventid) > - return e->filter[0].sel; > + return e->filter[1].sel ?: e->filter[0].sel; > } > return SEL_NONE; > } > @@ -2077,16 +2082,21 @@ 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)); > + if (ret) > + return ret; > + 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 > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] perf/arm-cmn: Fix multi-filter encoding 2026-09-15 12:24 [PATCH v2] perf/arm-cmn: Fix multi-filter encoding Robin Murphy ` (2 preceding siblings ...) 2026-09-17 1:51 ` Ilkka Koskinen @ 2026-09-18 12:28 ` Will Deacon 3 siblings, 0 replies; 6+ messages in thread From: Will Deacon @ 2026-09-18 12:28 UTC (permalink / raw) To: Robin Murphy Cc: catalin.marinas, mark.rutland, kernel-team, Will Deacon, ilkka, leo.yan, linux-perf-users, linux-arm-kernel On Tue, 15 Sep 2026 13:24:22 +0100, 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. > > [...] Applied to arm64 (for-next/fixes), thanks! [1/1] perf/arm-cmn: Fix multi-filter encoding https://git.kernel.org/arm64/c/406aa2b186d3 Cheers, -- Will https://fixes.arm64.dev https://next.arm64.dev https://will.arm64.dev ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-18 12:28 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-15 12:24 [PATCH v2] perf/arm-cmn: Fix multi-filter encoding Robin Murphy 2026-09-15 12:32 ` sashiko-bot 2026-09-16 9:31 ` Leo Yan 2026-09-16 15:27 ` Robin Murphy 2026-09-17 1:51 ` Ilkka Koskinen 2026-09-18 12:28 ` Will Deacon
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox