mirror of
https://github.com/torvalds/linux.git
synced 2026-09-26 10:02:02 +02:00
perf/arm-cmn: Fix multi-filter encoding
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: 09178f536b ("perf/arm-cmn: Plumb in new filter types")
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
fdb9ebc7fb
commit
406aa2b186
|
|
@ -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)
|
||||
|
|
@ -1860,10 +1860,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;
|
||||
|
|
@ -1914,14 +1916,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;
|
||||
|
||||
|
|
@ -1950,7 +1955,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;
|
||||
}
|
||||
|
|
@ -2081,16 +2086,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user