Linux Perf Users
 help / color / mirror / Atom feed
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
>
>

      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