From: Ilkka Koskinen <ilkka@os.amperecomputing.com>
To: Robin Murphy <robin.murphy@arm.com>
Cc: will@kernel.org, mark.rutland@arm.com,
linux-arm-kernel@lists.infradead.org,
linux-perf-users@vger.kernel.org, ilkka@os.amperecomputing.com,
leo.yan@arm.com
Subject: Re: [PATCH v2 5/5] perf/arm-cmn: Support CMN S3 r2
Date: Mon, 3 Aug 2026 19:33:50 -0700 (PDT) [thread overview]
Message-ID: <f85da4a6-bec8-af41-d63a-d894d057a344@os.amperecomputing.com> (raw)
In-Reply-To: <86b7093bc5de0f2aedc63fc4826ce911cb22d16f.1785252273.git.robin.murphy@arm.com>
On Tue, 28 Jul 2026, Robin Murphy wrote:
> If you were disappointed at how minimal the initial CMN S3 support
> looked compared to previous versions, then oh boy is it time to put your
> party hats on... The biggest batch of incompatible changes yet comes not
> with a new CMN product, but a point release of an existing one. We've
> got new filters, loads of changes to existing events, register fields
> moved around for no good reason, and much, much more! On the upside, we
> do at least gain a means of working around the isolation feature.
That's just great...
>
> As such, for the sake of sanity in the driver it is easiest to split it
> into a distict "model" for our internal abstractions despite it bearing
> the same part number as r0/r1.
>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
The patch looks good to me:
Reviewed-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Cheers, Ilkka
> ---
>
> v2: No change
>
> drivers/perf/arm-cmn.c | 270 +++++++++++++++++++++++++++++------------
> 1 file changed, 193 insertions(+), 77 deletions(-)
>
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index e25f46c38c23..a03e2a8ca41e 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -29,6 +29,7 @@
> #define CMN_CI_CHILD_PTR_OFFSET GENMASK_ULL(31, 16)
>
> #define CMN_CHILD_NODE_ADDR GENMASK(29, 0)
> +#define CMN_CHILD_NODE_ISOLATED BIT(30)
> #define CMN_CHILD_NODE_EXTERNAL BIT(31)
>
> /* Some implementations use a mesh larger than the architectural max of 12 */
> @@ -48,11 +49,16 @@
>
> #define CMN_CFGM_INFO_GLOBAL 0x0900
> #define CMN_INFO_MULTIPLE_DTM_EN BIT_ULL(63)
> +#define CMN_S3_R2_MULTIPLE_DTM_EN BIT_ULL(59)
> #define CMN_INFO_RSP_VC_NUM GENMASK_ULL(53, 52)
> #define CMN_INFO_DAT_VC_NUM GENMASK_ULL(51, 50)
> #define CMN_INFO_DEVICE_ISO_ENABLE BIT_ULL(44)
>
> #define CMN_CFGM_INFO_GLOBAL_1 0x0908
> +#define CMN_S3_R2_RSP_VC_NUM GENMASK_ULL(11, 9)
> +#define CMN_S3_R2_DAT_VC_NUM GENMASK_ULL(8, 6)
> +#define CMN_S3_R2_SNP_VC_NUM GENMASK_ULL(5, 3)
> +#define CMN_S3_R2_REQ_VC_NUM GENMASK_ULL(2, 0)
> #define CMN_INFO_SNP_VC_NUM GENMASK_ULL(3, 2)
> #define CMN_INFO_REQ_VC_NUM GENMASK_ULL(1, 0)
>
> @@ -78,6 +84,16 @@
> /* Technically this is 4 bits wide on DNs, but we only use 2 there anyway */
> #define CMN__PMU_OCCUP1_ID GENMASK_ULL(34, 32)
>
> +/* But then... */
> +#define CMN__PMU_EVICT_STATE_SEL GENMASK_ULL(54, 52)
> +#define CMN__PMU_ENHANCED_HBT_LBT_SEL GENMASK_ULL(51, 48)
> +#define CMN__PMU_SNP_VC_SEL GENMASK_ULL(47, 46)
> +#define CMN__S3_R2_CBUSY_SNTHROTTLE_SEL GENMASK_ULL(45, 42)
> +#define CMN__S3_R2_SN_HOME_SEL GENMASK_ULL(41, 40)
> +#define CMN__S3_R2_HBT_LBT_SEL GENMASK_ULL(39, 38)
> +#define CMN__S3_R2_CLASS_OCCUP_ID GENMASK_ULL(37, 36)
> +#define CMN__S3_R2_OCCUP1_ID GENMASK_ULL(35, 32)
> +
> /* Some types are designed to coexist with another device in the same node */
> #define CMN_CCLA_PMU_EVENT_SEL 0x008
> #define CMN_HNP_PMU_EVENT_SEL 0x008
> @@ -202,12 +218,14 @@ enum cmn_model {
> CMN650 = 2,
> CI700 = 4,
> CMN700 = 8,
> - CMNS3 = 16,
> + CMNS3R01 = 16,
> + CMNS3R2 = 32,
> /* ...and then we can use bitmap tricks for commonality */
> CMN_ANY = -1,
> NOT_CMN600 = -2,
> CMN_700ON = ~(CMN700 - 1),
> CMN_650ON = CMN_700ON | CMN650,
> + CMNS3 = CMNS3R01 | CMNS3R2,
> };
>
> /* Actual part numbers and revision IDs defined by the hardware */
> @@ -243,6 +261,10 @@ enum cmn_revision {
> REV_CMNS3_R0P0 = 0,
> REV_CMNS3_R0P1,
> REV_CMNS3_R1P0,
> + REV_CMNS3_R2P0,
> + REV_CMNS3_R2P1,
> + REV_CMNS3_R2P2,
> + REV_CMNS3_R2P5,
> REV_CI700_R0P0 = 0,
> REV_CI700_R1P0,
> REV_CI700_R2P0,
> @@ -429,7 +451,9 @@ static enum cmn_model arm_cmn_model(const struct arm_cmn *cmn)
> case PART_CI700:
> return CI700;
> case PART_CMN_S3:
> - return CMNS3;
> + if (cmn->rev >= REV_CMNS3_R2P0)
> + return CMNS3R2;
> + return CMNS3R01;
> default:
> return 0;
> };
> @@ -609,8 +633,10 @@ enum cmn_filter_type {
> FILT_OCCUP1_ID,
> FILT_HNF_700,
> FILT_HNS,
> + FILT_HNS_S3R2,
> };
> #define CMN_FILTER(_sel) [SEL_##_sel] = CMN__PMU_##_sel
> +#define CMN_FILTER_V2(_sel) [SEL_##_sel] = CMN__S3_R2_##_sel
>
> static const u64 arm_cmn_filters[][SEL_MAX] = {
> [FILT_NONE] = {},
> @@ -632,6 +658,17 @@ static const u64 arm_cmn_filters[][SEL_MAX] = {
> CMN_FILTER(HBT_LBT_SEL),
> CMN_FILTER(SN_HOME_SEL)
> },
> + /* Newer HN-S */
> + [FILT_HNS_S3R2] = {
> + CMN_FILTER_V2(OCCUP1_ID),
> + CMN_FILTER_V2(CLASS_OCCUP_ID),
> + CMN_FILTER_V2(CBUSY_SNTHROTTLE_SEL),
> + CMN_FILTER_V2(HBT_LBT_SEL),
> + CMN_FILTER_V2(SN_HOME_SEL),
> + CMN_FILTER(SNP_VC_SEL),
> + CMN_FILTER(ENHANCED_HBT_LBT_SEL),
> + CMN_FILTER(EVICT_STATE_SEL)
> + }
> };
>
> static enum cmn_filter_type arm_cmn_filter(enum cmn_node_type node,
> @@ -651,7 +688,9 @@ static enum cmn_filter_type arm_cmn_filter(enum cmn_node_type node,
> return FILT_OCCUP1_ID;
> return FILT_HNF_700;
> case CMN_TYPE_HNS:
> - return FILT_HNS;
> + if (model < CMNS3R2)
> + return FILT_HNS;
> + return FILT_HNS_S3R2;
> };
> }
>
> @@ -732,7 +771,7 @@ struct arm_cmn_event_attr {
> enum cmn_model model;
> enum cmn_node_type type;
> u16 eventid;
> - struct arm_cmn_filter_attr filter[1];
> + struct arm_cmn_filter_attr filter[2];
> };
>
> struct arm_cmn_format_attr {
> @@ -741,16 +780,16 @@ struct arm_cmn_format_attr {
> int config;
> };
>
> -#define _CMN_EVENT_ATTR(_model, _name, _type, _eventid, _fa, _fb, ...) \
> +#define _CMN_EVENT_ATTR(_model, _name, _type, _eventid, _fa, _fb, _fc, _fd, ...) \
> (&((struct arm_cmn_event_attr[]) {{ \
> .attr = __ATTR(_name, 0444, arm_cmn_event_show, NULL), \
> .model = _model, \
> .type = _type, \
> .eventid = _eventid, \
> - .filter = {{_fa, _fb}}, \
> + .filter = {{_fa, _fb}, {_fc, _fd}}, \
> }})[0].attr.attr)
> #define CMN_EVENT_ATTR(_model, _name, _type, _eventid, _filter...) \
> - _CMN_EVENT_ATTR(_model, _name, _type, _eventid, ##_filter, 0, 0)
> + _CMN_EVENT_ATTR(_model, _name, _type, _eventid, ##_filter, 0, 0, 0, 0)
>
> static ssize_t arm_cmn_event_show(struct device *dev,
> struct device_attribute *attr, char *buf)
> @@ -769,6 +808,10 @@ static ssize_t arm_cmn_event_show(struct device *dev,
> "type=0x%x,eventid=0x%x,wp_dev_sel=?,wp_chn_sel=?,wp_grp=?,wp_val=?,wp_mask=?\n",
> eattr->type, eattr->eventid);
>
> + if (filter[1].sel)
> + return sysfs_emit(buf, "type=0x%x,eventid=0x%x,filter=0x%x,filter2=0x%x\n",
> + eattr->type, eattr->eventid, filter[0].val, filter[1].val);
> +
> if (filter[0].sel)
> return sysfs_emit(buf, "type=0x%x,eventid=0x%x,filter=0x%x\n",
> eattr->type, eattr->eventid, filter[0].val);
> @@ -887,8 +930,8 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
> CMN_EVENT_ATTR(_model, ccha_##_name, CMN_TYPE_CCHA, _event)
> #define CMN_EVENT_CCLA(_name, _event) \
> CMN_EVENT_ATTR(CMN_ANY, ccla_##_name, CMN_TYPE_CCLA, _event)
> -#define CMN_EVENT_HNS(_name, _event) \
> - CMN_EVENT_ATTR(CMN_ANY, hns_##_name, CMN_TYPE_HNS, _event)
> +#define _CMN_EVENT_HNS(_model, _name, _event, _filter...) \
> + CMN_EVENT_ATTR(_model, hns_##_name, CMN_TYPE_HNS, _event, ##_filter)
>
> #define CMN_EVENT_DVM_OCC(_model, _name, _event) \
> CMN_EVENT_DVM(_model, _name##_all, _event, SEL_OCCUP1_ID, 0), \
> @@ -913,7 +956,12 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
> CMN_EVENT_ATTR(_model, _name##_group1_read, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 3), \
> CMN_EVENT_ATTR(_model, _name##_group1_write, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 4), \
> CMN_EVENT_ATTR(_model, _name##_read, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 5), \
> - CMN_EVENT_ATTR(_model, _name##_write, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 6)
> + CMN_EVENT_ATTR(_model, _name##_write, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 6), \
> + CMN_EVENT_ATTR(CMNS3R2, _name##_ccg_read, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 9), \
> + CMN_EVENT_ATTR(CMNS3R2, _name##_ccg_write, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 10), \
> + CMN_EVENT_ATTR(CMNS3R2, _name##_lbt_read, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 11), \
> + CMN_EVENT_ATTR(CMNS3R2, _name##_lbt_write, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 12), \
> + CMN_EVENT_ATTR(CMNS3R2, _name##_lbt, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 13)
>
> #define CMN_EVENT_HNF_OCC(_model, _name, _event) \
> CMN_EVENT_HN_OCC(_model, hnf_##_name, CMN_TYPE_HNF, _event)
> @@ -922,23 +970,75 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
> #define CMN_EVENT_HNF_SNT(_model, _name, _event) \
> CMN_EVENT_HN_SNT(_model, hnf_##_name, CMN_TYPE_HNF, _event)
>
> -#define CMN_EVENT_HNS_OCC(_name, _event) \
> - CMN_EVENT_HN_OCC(CMN_ANY, hns_##_name, CMN_TYPE_HNS, _event), \
> - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_rxsnp, CMN_TYPE_HNS, _event, SEL_OCCUP1_ID, 5), \
> - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_lbt, CMN_TYPE_HNS, _event, SEL_OCCUP1_ID, 6), \
> - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_hbt, CMN_TYPE_HNS, _event, SEL_OCCUP1_ID, 7)
> +#define CMN_EVENT_HNS(_name, _event) \
> + _CMN_EVENT_HNS(CMN_ANY, _name, _event)
> +#define CMN_EVENT_HNSR0(_name, _event) \
> + _CMN_EVENT_HNS(CMN700 | CMNS3R01, _name, _event)
> +#define _CMN_EVENT_HNS_HBT(_model, _name, _event, _sel) \
> + _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_OCC(_model, _name, _event) \
> + CMN_EVENT_HN_OCC(_model, hns_##_name, CMN_TYPE_HNS, _event), \
> + _CMN_EVENT_HNS(_model, _name##_rxsnp, _event, SEL_OCCUP1_ID, 5), \
> + _CMN_EVENT_HNS(_model, _name##_lbt, _event, SEL_OCCUP1_ID, 6), \
> + _CMN_EVENT_HNS(_model, _name##_hbt, _event, SEL_OCCUP1_ID, 7), \
> + _CMN_EVENT_HNS(CMNS3R2, _name##_rnf, _event, SEL_OCCUP1_ID, 8), \
> + _CMN_EVENT_HNS(CMNS3R2, _name##_rni, _event, SEL_OCCUP1_ID, 9), \
> + _CMN_EVENT_HNS(CMNS3R2, _name##_ccglcn, _event, SEL_OCCUP1_ID, 10), \
> + _CMN_EVENT_HNS(CMNS3R2, _name##_ccgrn, _event, SEL_OCCUP1_ID, 11)
> #define CMN_EVENT_HNS_CLS( _name, _event) \
> CMN_EVENT_HN_CLS(CMN_ANY, hns_##_name, CMN_TYPE_HNS, _event)
> -#define CMN_EVENT_HNS_SNT(_name, _event) \
> - CMN_EVENT_HN_SNT(CMN_ANY, hns_##_name, CMN_TYPE_HNS, _event)
> -#define CMN_EVENT_HNS_HBT(_name, _event) \
> - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_all, CMN_TYPE_HNS, _event, SEL_HBT_LBT_SEL, 0), \
> - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_hbt, CMN_TYPE_HNS, _event, SEL_HBT_LBT_SEL, 1), \
> - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_lbt, CMN_TYPE_HNS, _event, SEL_HBT_LBT_SEL, 2)
> -#define CMN_EVENT_HNS_SNH(_name, _event) \
> - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_all, CMN_TYPE_HNS, _event, SEL_SN_HOME_SEL, 0), \
> - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_sn, CMN_TYPE_HNS, _event, SEL_SN_HOME_SEL, 1), \
> - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_home, CMN_TYPE_HNS, _event, SEL_SN_HOME_SEL, 2)
> +#define CMN_EVENT_HNSR0_CLS( _name, _event) \
> + CMN_EVENT_HN_CLS(CMN700 | CMNS3R01, hns_##_name, CMN_TYPE_HNS, _event)
> +#define CMN_EVENT_HNS_SNT(_model, _name, _event) \
> + CMN_EVENT_HN_SNT(_model, hns_##_name, CMN_TYPE_HNS, _event)
> +#define CMN_EVENT_HNS_SNH(_model, _name, _event) \
> + _CMN_EVENT_HNS(_model, _name##_all, _event, SEL_SN_HOME_SEL, 0), \
> + _CMN_EVENT_HNS(_model, _name##_sn, _event, SEL_SN_HOME_SEL, 1), \
> + _CMN_EVENT_HNS(_model, _name##_home, _event, SEL_SN_HOME_SEL, 2)
> +#define CMN_EVENT_HNS_VC(_name, _event) \
> + CMN_EVENT_HNSR0(_name, _event), \
> + _CMN_EVENT_HNS(CMNS3R2, _name##_vc0, _event, SEL_SNP_VC_SEL, 0), \
> + _CMN_EVENT_HNS(CMNS3R2, _name##_vc1, _event, SEL_SNP_VC_SEL, 1), \
> + _CMN_EVENT_HNS(CMNS3R2, _name##_vc2, _event, SEL_SNP_VC_SEL, 2)
> +#define CMN_EVENT_HNS_ENHBT(_name, _event) \
> + _CMN_EVENT_HNS_HBT(CMNS3R2, _name, _event, SEL_ENHANCED_HBT_LBT_SEL), \
> + _CMN_EVENT_HNS(CMNS3R2, _name##_rnf, _event, SEL_ENHANCED_HBT_LBT_SEL, 3), \
> + _CMN_EVENT_HNS(CMNS3R2, _name##_rni, _event, SEL_ENHANCED_HBT_LBT_SEL, 4), \
> + _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)
> +
> +#define CMN_EVENT_HNSR0_HBT(_name, _event) \
> + _CMN_EVENT_HNS_HBT(CMN700 | CMNS3R01, _name, _event, SEL_HBT_LBT_SEL)
> +#define CMN_EVENT_HNS_R2SNH(_name, _event) \
> + CMN_EVENT_HNSR0(_name, _event), \
> + CMN_EVENT_HNS_SNH(CMNS3R2, _name, _event)
> +#define CMN_EVENT_HNS_R2HBT(_name, _event) \
> + CMN_EVENT_HNSR0(_name, _event), \
> + _CMN_EVENT_HNS_HBT(CMNS3R2, _name, _event, SEL_HBT_LBT_SEL)
> +#define CMN_EVENT_HNS_HBT_ENHBT(_name, _event) \
> + CMN_EVENT_HNSR0_HBT(_name, _event), \
> + CMN_EVENT_HNS_ENHBT(_name, _event)
> +#define CMN_EVENT_HNS_HBT_OCC(_name, _event) \
> + CMN_EVENT_HNSR0_HBT(_name, _event), \
> + CMN_EVENT_HNS_OCC(CMNS3R2, _name, _event)
> +#define CMN_EVENT_HNS_HBT_EVICT(_name, _event) \
> + CMN_EVENT_HNSR0_HBT(_name, _event), \
> + CMN_EVENT_HNS_EVICT(CMNS3R2, _name, _event)
>
> #define _CMN_EVENT_XP_MESH(_name, _event) \
> __CMN_EVENT_XP(e_##_name, (_event) | (0 << 2)), \
> @@ -1288,65 +1388,72 @@ static struct attribute *arm_cmn_event_attrs[] = {
> CMN_EVENT_CCLA(pfwd_sndr_stalls_static_crd, 0x2a),
> CMN_EVENT_CCLA(pfwd_sndr_stalls_dynmaic_crd, 0x2b),
>
> - CMN_EVENT_HNS_HBT(cache_miss, 0x01),
> - CMN_EVENT_HNS_HBT(slc_sf_cache_access, 0x02),
> - CMN_EVENT_HNS_HBT(cache_fill, 0x03),
> - CMN_EVENT_HNS_HBT(pocq_retry, 0x04),
> - CMN_EVENT_HNS_HBT(pocq_reqs_recvd, 0x05),
> - CMN_EVENT_HNS_HBT(sf_hit, 0x06),
> - CMN_EVENT_HNS_HBT(sf_evictions, 0x07),
> - CMN_EVENT_HNS(dir_snoops_sent, 0x08),
> - CMN_EVENT_HNS(brd_snoops_sent, 0x09),
> - CMN_EVENT_HNS_HBT(slc_eviction, 0x0a),
> - CMN_EVENT_HNS_HBT(slc_fill_invalid_way, 0x0b),
> - CMN_EVENT_HNS(mc_retries_local, 0x0c),
> - CMN_EVENT_HNS_SNH(mc_reqs_local, 0x0d),
> + CMN_EVENT_HNS_HBT_ENHBT(cache_miss, 0x01),
> + CMN_EVENT_HNS_HBT_ENHBT(slc_sf_cache_access, 0x02),
> + CMN_EVENT_HNS_HBT_ENHBT(cache_fill, 0x03),
> + CMN_EVENT_HNS_HBT_OCC(pocq_retry, 0x04),
> + CMN_EVENT_HNS_HBT_OCC(pocq_reqs_recvd, 0x05),
> + CMN_EVENT_HNS_HBT_ENHBT(sf_hit, 0x06),
> + CMN_EVENT_HNS_HBT_EVICT(sf_evictions, 0x07),
> + CMN_EVENT_HNS_VC(dir_snoops_sent, 0x08),
> + CMN_EVENT_HNS_VC(brd_snoops_sent, 0x09),
> + CMN_EVENT_HNS_HBT_EVICT(slc_eviction, 0x0a),
> + CMN_EVENT_HNS_HBT_ENHBT(slc_fill_invalid_way, 0x0b),
> + CMN_EVENT_HNS_R2SNH(mc_retries_local, 0x0c),
> + CMN_EVENT_HNS_SNH(CMN_ANY, mc_reqs_local, 0x0d),
> CMN_EVENT_HNS(qos_hh_retry, 0x0e),
> - CMN_EVENT_HNS_OCC(qos_pocq_occupancy, 0x0f),
> - CMN_EVENT_HNS(pocq_addrhaz, 0x10),
> - CMN_EVENT_HNS(pocq_atomic_addrhaz, 0x11),
> - CMN_EVENT_HNS(ld_st_swp_adq_full, 0x12),
> - CMN_EVENT_HNS(cmp_adq_full, 0x13),
> + CMN_EVENT_HNS_OCC(CMN_ANY, qos_pocq_occupancy, 0x0f),
> + CMN_EVENT_HNS_HBT_ENHBT(pocq_addrhaz, 0x10),
> + CMN_EVENT_HNS_HBT_ENHBT(pocq_atomic_addrhaz, 0x11),
> + CMN_EVENT_HNSR0(ld_st_swp_adq_full, 0x12),
> + CMN_EVENT_HNSR0(cmp_adq_full, 0x13),
> CMN_EVENT_HNS(txdat_stall, 0x14),
> CMN_EVENT_HNS(txrsp_stall, 0x15),
> - CMN_EVENT_HNS(seq_full, 0x16),
> + CMN_EVENT_HNSR0(seq_full, 0x16),
> CMN_EVENT_HNS(seq_hit, 0x17),
> - CMN_EVENT_HNS(snp_sent, 0x18),
> - CMN_EVENT_HNS(sfbi_dir_snp_sent, 0x19),
> - CMN_EVENT_HNS(sfbi_brd_snp_sent, 0x1a),
> + CMN_EVENT_HNS_VC(snp_sent, 0x18),
> + CMN_EVENT_HNS_VC(sfbi_dir_snp_sent, 0x19),
> + CMN_EVENT_HNS_VC(sfbi_brd_snp_sent, 0x1a),
> CMN_EVENT_HNS(intv_dirty, 0x1c),
> - CMN_EVENT_HNS(stash_snp_sent, 0x1d),
> - CMN_EVENT_HNS(stash_data_pull, 0x1e),
> - CMN_EVENT_HNS(snp_fwded, 0x1f),
> - CMN_EVENT_HNS(atomic_fwd, 0x20),
> + CMN_EVENT_HNSR0(stash_snp_sent, 0x1d),
> + CMN_EVENT_HNSR0(stash_data_pull, 0x1e),
> + CMN_EVENT_HNS_VC(snp_fwded, 0x1f),
> + CMN_EVENT_HNSR0(atomic_fwd, 0x20),
> CMN_EVENT_HNS(mpam_hardlim, 0x21),
> CMN_EVENT_HNS(mpam_softlim, 0x22),
> - CMN_EVENT_HNS(snp_sent_cluster, 0x23),
> - CMN_EVENT_HNS(sf_imprecise_evict, 0x24),
> + CMN_EVENT_HNS_VC(snp_sent_cluster, 0x23),
> + CMN_EVENT_HNS_R2HBT(sf_imprecise_evict, 0x24),
> CMN_EVENT_HNS(sf_evict_shared_line, 0x25),
> CMN_EVENT_HNS_CLS(pocq_class_occup, 0x26),
> CMN_EVENT_HNS_CLS(pocq_class_retry, 0x27),
> CMN_EVENT_HNS_CLS(class_mc_reqs_local, 0x28),
> - CMN_EVENT_HNS_CLS(class_cgnt_cmin, 0x29),
> - CMN_EVENT_HNS_SNT(sn_throttle, 0x2a),
> - CMN_EVENT_HNS_SNT(sn_throttle_min, 0x2b),
> + CMN_EVENT_HNSR0_CLS(class_cgnt_cmin, 0x29),
> + CMN_EVENT_HNS_SNT(CMN_ANY, sn_throttle, 0x2a),
> + CMN_EVENT_HNS_SNT(CMN_ANY, sn_throttle_min, 0x2b),
> CMN_EVENT_HNS(sf_precise_to_imprecise, 0x2c),
> CMN_EVENT_HNS(snp_intv_cln, 0x2d),
> CMN_EVENT_HNS(nc_excl, 0x2e),
> - CMN_EVENT_HNS(excl_mon_ovfl, 0x2f),
> + CMN_EVENT_HNSR0(excl_mon_ovfl, 0x2f),
> CMN_EVENT_HNS(snp_req_recvd, 0x30),
> CMN_EVENT_HNS(snp_req_byp_pocq, 0x31),
> CMN_EVENT_HNS(dir_ccgha_snp_sent, 0x32),
> CMN_EVENT_HNS(brd_ccgha_snp_sent, 0x33),
> - CMN_EVENT_HNS(ccgha_snp_stall, 0x34),
> + CMN_EVENT_HNSR0(ccgha_snp_stall, 0x34),
> CMN_EVENT_HNS(lbt_req_hardlim, 0x35),
> CMN_EVENT_HNS(hbt_req_hardlim, 0x36),
> CMN_EVENT_HNS(sf_reupdate, 0x37),
> - CMN_EVENT_HNS(excl_sf_imprecise, 0x38),
> + CMN_EVENT_HNS_R2HBT(excl_sf_imprecise, 0x38),
> CMN_EVENT_HNS(snp_pocq_addrhaz, 0x39),
> - CMN_EVENT_HNS(mc_retries_remote, 0x3a),
> - CMN_EVENT_HNS_SNH(mc_reqs_remote, 0x3b),
> + CMN_EVENT_HNS_R2SNH(mc_retries_remote, 0x3a),
> + CMN_EVENT_HNS_SNH(CMN_ANY, mc_reqs_remote, 0x3b),
> CMN_EVENT_HNS_CLS(class_mc_reqs_remote, 0x3c),
> + CMN_EVENT_HNS_ENHBT(readonce_hazard_detected, 0x3d),
> + CMN_EVENT_HNS_ENHBT(readonce_fwd_data_completed, 0x3e),
> + CMN_EVENT_HNS_SNT(CMNS3R2, cbusy00, 0x40),
> + CMN_EVENT_HNS_SNT(CMNS3R2, cbusy01, 0x41),
> + CMN_EVENT_HNS_SNT(CMNS3R2, cbusy10, 0x42),
> + CMN_EVENT_HNS_SNT(CMNS3R2, cbusy11, 0x43),
> + CMN_EVENT_HNS_ENHBT(ro_rnsd_new_alloc_hint, 0x44),
>
> NULL
> };
> @@ -2431,21 +2538,33 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
> /*
> * With the device isolation feature, if firmware has neglected to enable
> * an XP port then we risk locking up if we try to access anything behind
> - * it; however we also have no way to tell from Non-Secure whether any
> - * given port is disabled or not, so the only way to win is not to play...
> + * it; however prior to CMN S3 r2p0 we also have no way to tell from
> + * Non-Secure whether any given port is disabled or not, so in that case
> + * the only way to win is not to play...
> */
> reg = readq_relaxed(cfg_region + CMN_CFGM_INFO_GLOBAL);
> - if (reg & CMN_INFO_DEVICE_ISO_ENABLE) {
> + if (reg & CMN_INFO_DEVICE_ISO_ENABLE && model == CMNS3R01) {
> dev_err(cmn->dev, "Device isolation enabled, not continuing due to risk of lockup\n");
> return -ENODEV;
> }
> - cmn->multi_dtm = reg & CMN_INFO_MULTIPLE_DTM_EN;
> - cmn->rsp_vc_num = FIELD_GET(CMN_INFO_RSP_VC_NUM, reg);
> - cmn->dat_vc_num = FIELD_GET(CMN_INFO_DAT_VC_NUM, reg);
> + if (model < CMNS3R2) {
> + cmn->multi_dtm = reg & CMN_INFO_MULTIPLE_DTM_EN;
> + cmn->rsp_vc_num = FIELD_GET(CMN_INFO_RSP_VC_NUM, reg);
> + cmn->dat_vc_num = FIELD_GET(CMN_INFO_DAT_VC_NUM, reg);
> + } else {
> + cmn->multi_dtm = reg & CMN_S3_R2_MULTIPLE_DTM_EN;
> + }
>
> reg = readq_relaxed(cfg_region + CMN_CFGM_INFO_GLOBAL_1);
> - cmn->snp_vc_num = FIELD_GET(CMN_INFO_SNP_VC_NUM, reg);
> - cmn->req_vc_num = FIELD_GET(CMN_INFO_REQ_VC_NUM, reg);
> + if (model < CMNS3R2) {
> + cmn->snp_vc_num = FIELD_GET(CMN_INFO_SNP_VC_NUM, reg);
> + cmn->req_vc_num = FIELD_GET(CMN_INFO_REQ_VC_NUM, reg);
> + } else {
> + cmn->rsp_vc_num = FIELD_GET(CMN_S3_R2_RSP_VC_NUM, reg);
> + cmn->dat_vc_num = FIELD_GET(CMN_S3_R2_DAT_VC_NUM, reg);
> + cmn->snp_vc_num = FIELD_GET(CMN_S3_R2_SNP_VC_NUM, reg);
> + cmn->req_vc_num = FIELD_GET(CMN_S3_R2_REQ_VC_NUM, reg);
> + }
>
> reg = readq_relaxed(cfg_region + CMN_CHILD_INFO);
> child_count = FIELD_GET(CMN_CI_CHILD_COUNT, reg);
> @@ -2545,15 +2664,12 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
> reg = readq_relaxed(xp_region + child_poff + j * 8);
> /*
> * Don't even try to touch anything external, since in general
> - * we haven't a clue how to power up arbitrary CHI requesters.
> - * As of CMN-600r1 these could only be RN-SAMs or CXLAs,
> - * neither of which have any PMU events anyway.
> - * (Actually, CXLAs do seem to have grown some events in r1p2,
> - * but they don't go to regular XP DTMs, and they depend on
> - * secure configuration which we can't easily deal with)
> + * we haven't a clue how to power up arbitrary CHI requesters,
> + * and none of them have standard PMU events anyway. Isolated
> + * nodes effectively just do not exist at all from our PoV.
> */
> - if (reg & CMN_CHILD_NODE_EXTERNAL) {
> - dev_dbg(cmn->dev, "ignoring external node %llx\n", reg);
> + if (reg & (CMN_CHILD_NODE_EXTERNAL | CMN_CHILD_NODE_ISOLATED)) {
> + dev_dbg(cmn->dev, "ignoring external/isolated node %llx\n", reg);
> continue;
> }
> /*
> --
> 2.54.0.dirty
>
>
prev parent reply other threads:[~2026-08-04 2:33 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-28 15:59 [PATCH v2 0/5] perf/arm-cmn: Support CMN S3 r2 Robin Murphy
2026-07-28 15:59 ` [PATCH v2 1/5] perf/arm-cmn: Rename filter variables for clarity Robin Murphy
2026-07-29 17:20 ` Jonathan Cameron
2026-07-29 18:39 ` Robin Murphy
2026-07-28 15:59 ` [PATCH v2 2/5] perf/arm-cmn: Refactor event filter programming Robin Murphy
2026-07-28 15:59 ` [PATCH v2 3/5] perf/arm-cmn: Refactor event filter data Robin Murphy
2026-08-04 2:18 ` Ilkka Koskinen
2026-07-28 15:59 ` [PATCH v2 4/5] perf/arm-cmn: Plumb in new filter types Robin Murphy
2026-07-28 16:43 ` sashiko-bot
2026-08-04 2:22 ` Ilkka Koskinen
2026-07-28 15:59 ` [PATCH v2 5/5] perf/arm-cmn: Support CMN S3 r2 Robin Murphy
2026-07-28 16:57 ` sashiko-bot
2026-07-28 17:16 ` Robin Murphy
2026-08-04 2:33 ` Ilkka Koskinen [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f85da4a6-bec8-af41-d63a-d894d057a344@os.amperecomputing.com \
--to=ilkka@os.amperecomputing.com \
--cc=leo.yan@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=robin.murphy@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox