All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700
@ 2022-04-18 22:57 Robin Murphy
  2022-04-18 22:57   ` Robin Murphy
                   ` (6 more replies)
  0 siblings, 7 replies; 23+ messages in thread
From: Robin Murphy @ 2022-04-18 22:57 UTC (permalink / raw)
  To: will; +Cc: mark.rutland, linux-arm-kernel

Hi Will,

As promised last time, here are the patches adding yet more inscrutable
support for the other new members of the CMN family. I'm not sure if any
of the folks who want this are the kind to give upstream feedback, but
we can always live in hope... A colleague has kindly managed to briefly
sanity-check the CMN-700 support under RTL emulation, but otherwise I've
only been able to test the refactorings in terms of not breaking my
little CMN-600 platform. Still, I'm pretty confident that that's caught
all the stupids, and the rest is mostly just yet more events, so I
don't think anything's particularly high-risk here.

Cheers,
Robin.


Robin Murphy (4):
  dt-bindings: perf: arm-cmn: Add CMN-650 and CMN-700
  perf/arm-cmn: Add CMN-650 support
  perf/arm-cmn: Refactor occupancy filter selector
  perf/arm-cmn: Add CMN-700 support

 .../devicetree/bindings/perf/arm,cmn.yaml     |   2 +
 drivers/perf/arm-cmn.c                        | 606 ++++++++++++++----
 2 files changed, 485 insertions(+), 123 deletions(-)

-- 
2.35.3.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/4] dt-bindings: perf: arm-cmn: Add CMN-650 and CMN-700
  2022-04-18 22:57 [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Robin Murphy
@ 2022-04-18 22:57   ` Robin Murphy
  2022-04-18 22:57 ` [PATCH 2/4] perf/arm-cmn: Add CMN-650 support Robin Murphy
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 23+ messages in thread
From: Robin Murphy @ 2022-04-18 22:57 UTC (permalink / raw)
  To: will; +Cc: mark.rutland, linux-arm-kernel, devicetree

If you were to guess from the product names that CMN-650 and CMN-700 are
the next two evolutionary steps of Arm's enterprise-level interconnect
following on from CMN-600, you'd be pleasantly correct. Add them to the
DT binding.

CC: devicetree@vger.kernel.org
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 Documentation/devicetree/bindings/perf/arm,cmn.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/perf/arm,cmn.yaml b/Documentation/devicetree/bindings/perf/arm,cmn.yaml
index 2d4219ec7eda..2e51072e794a 100644
--- a/Documentation/devicetree/bindings/perf/arm,cmn.yaml
+++ b/Documentation/devicetree/bindings/perf/arm,cmn.yaml
@@ -14,6 +14,8 @@ properties:
   compatible:
     enum:
       - arm,cmn-600
+      - arm,cmn-650
+      - arm,cmn-700
       - arm,ci-700
 
   reg:
-- 
2.35.3.dirty


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 1/4] dt-bindings: perf: arm-cmn: Add CMN-650 and CMN-700
@ 2022-04-18 22:57   ` Robin Murphy
  0 siblings, 0 replies; 23+ messages in thread
From: Robin Murphy @ 2022-04-18 22:57 UTC (permalink / raw)
  To: will; +Cc: mark.rutland, linux-arm-kernel, devicetree

If you were to guess from the product names that CMN-650 and CMN-700 are
the next two evolutionary steps of Arm's enterprise-level interconnect
following on from CMN-600, you'd be pleasantly correct. Add them to the
DT binding.

CC: devicetree@vger.kernel.org
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 Documentation/devicetree/bindings/perf/arm,cmn.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/perf/arm,cmn.yaml b/Documentation/devicetree/bindings/perf/arm,cmn.yaml
index 2d4219ec7eda..2e51072e794a 100644
--- a/Documentation/devicetree/bindings/perf/arm,cmn.yaml
+++ b/Documentation/devicetree/bindings/perf/arm,cmn.yaml
@@ -14,6 +14,8 @@ properties:
   compatible:
     enum:
       - arm,cmn-600
+      - arm,cmn-650
+      - arm,cmn-700
       - arm,ci-700
 
   reg:
-- 
2.35.3.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/4] perf/arm-cmn: Add CMN-650 support
  2022-04-18 22:57 [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Robin Murphy
  2022-04-18 22:57   ` Robin Murphy
@ 2022-04-18 22:57 ` Robin Murphy
  2022-04-19 23:05   ` Ilkka Koskinen
  2022-04-21  7:25   ` Ilkka Koskinen
  2022-04-18 22:57 ` [PATCH 3/4] perf/arm-cmn: Refactor occupancy filter selector Robin Murphy
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 23+ messages in thread
From: Robin Murphy @ 2022-04-18 22:57 UTC (permalink / raw)
  To: will; +Cc: mark.rutland, linux-arm-kernel

Add the identifiers and events for CMN-650, which slots into its
evolutionary position between CMN-600 and the 700-series products.
Imagine CMN-600 made bigger, and with most of the rough edges smoothed
off, but that then balanced out by some bonkers PMU functionality for
the new HN-P enhancement in CMN-650r2.

Most of the CXG events are actually common to newer revisions of CMN-600
too, so they're arguably a little late; oh well.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/perf/arm-cmn.c | 222 ++++++++++++++++++++++++++++++++---------
 1 file changed, 176 insertions(+), 46 deletions(-)

diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index 9c1d82be7a2f..cce8516d465c 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -39,7 +39,7 @@
 #define CMN_CHILD_NODE_ADDR		GENMASK(27, 0)
 #define CMN_CHILD_NODE_EXTERNAL		BIT(31)
 
-#define CMN_MAX_DIMENSION		8
+#define CMN_MAX_DIMENSION		12
 #define CMN_MAX_XPS			(CMN_MAX_DIMENSION * CMN_MAX_DIMENSION)
 #define CMN_MAX_DTMS			(CMN_MAX_XPS + (CMN_MAX_DIMENSION - 1) * 4)
 
@@ -65,7 +65,9 @@
 
 /* For most nodes, this is all there is */
 #define CMN_PMU_EVENT_SEL		0x000
-#define CMN_PMU_EVENTn_ID_SHIFT(n)	((n) * 8)
+
+/* HN-Ps are weird... */
+#define CMN_HNP_PMU_EVENT_SEL		0x008
 
 /* DTMs live in the PMU space of XP registers */
 #define CMN_DTM_WPn(n)			(0x1A0 + (n) * 0x18)
@@ -177,9 +179,12 @@
 
 
 enum cmn_model {
-	CMN_ANY = -1,
 	CMN600 = 1,
-	CI700 = 2,
+	CMN650 = 2,
+	CI700 = 8,
+	/* ...and then we can use bitmap tricks for commonality */
+	CMN_ANY = -1,
+	NOT_CMN600 = -2,
 };
 
 /* CMN-600 r0px shouldn't exist in silicon, thankfully */
@@ -191,6 +196,11 @@ enum cmn_revision {
 	CMN600_R2P0,
 	CMN600_R3P0,
 	CMN600_R3P1,
+	CMN650_R0P0 = 0,
+	CMN650_R1P0,
+	CMN650_R1P1,
+	CMN650_R2P0,
+	CMN650_R1P2,
 	CI700_R0P0 = 0,
 	CI700_R1P0,
 	CI700_R2P0,
@@ -211,6 +221,7 @@ enum cmn_node_type {
 	CMN_TYPE_RND = 0xd,
 	CMN_TYPE_RNSAM = 0xf,
 	CMN_TYPE_MTSX,
+	CMN_TYPE_HNP,
 	CMN_TYPE_CXRA = 0x100,
 	CMN_TYPE_CXHA = 0x101,
 	CMN_TYPE_CXLA = 0x102,
@@ -307,9 +318,7 @@ struct arm_cmn_nodeid {
 
 static int arm_cmn_xyidbits(const struct arm_cmn *cmn)
 {
-	int dim = max(cmn->mesh_x, cmn->mesh_y);
-
-	return dim > 4 ? 3 : 2;
+	return fls((cmn->mesh_x - 1) | (cmn->mesh_y - 1) | 2);
 }
 
 static struct arm_cmn_nodeid arm_cmn_nid(const struct arm_cmn *cmn, u16 id)
@@ -362,6 +371,7 @@ static struct dentry *arm_cmn_debugfs;
 static const char *arm_cmn_device_type(u8 type)
 {
 	switch(type) {
+		case 0x00: return "        |";
 		case 0x01: return "  RN-I  |";
 		case 0x02: return "  RN-D  |";
 		case 0x04: return " RN-F_B |";
@@ -371,6 +381,7 @@ static const char *arm_cmn_device_type(u8 type)
 		case 0x08: return "  HN-T  |";
 		case 0x09: return "  HN-I  |";
 		case 0x0a: return "  HN-D  |";
+		case 0x0b: return "  HN-P  |";
 		case 0x0c: return "  SN-F  |";
 		case 0x0d: return "  SBSX  |";
 		case 0x0e: return "  HN-F  |";
@@ -383,8 +394,10 @@ static const char *arm_cmn_device_type(u8 type)
 		case 0x15: return "RN-F_D_E|";
 		case 0x16: return " RN-F_C |";
 		case 0x17: return "RN-F_C_E|";
+		case 0x18: return " RN-F_E |";
+		case 0x19: return "RN-F_E_E|";
 		case 0x1c: return "  MTSX  |";
-		default:   return "        |";
+		default:   return "  ????  |";
 	}
 }
 
@@ -492,7 +505,7 @@ static void arm_cmn_debugfs_init(struct arm_cmn *cmn, int id) {}
 
 struct arm_cmn_hw_event {
 	struct arm_cmn_node *dn;
-	u64 dtm_idx[2];
+	u64 dtm_idx[4];
 	unsigned int dtc_idx;
 	u8 dtcs_used;
 	u8 num_dns;
@@ -545,8 +558,7 @@ static bool arm_cmn_is_occup_event(enum cmn_model model,
 				   enum cmn_node_type type, unsigned int id)
 {
 	if (type == CMN_TYPE_DVM)
-		return (model == CMN600 && id == 0x05) ||
-		       (model == CI700 && id == 0x0c);
+		return model == CMN600 ? id == 0x05 : id == 0x0c;
 	return type == CMN_TYPE_HNF && id == 0x0f;
 }
 
@@ -580,20 +592,25 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 	struct device *dev = kobj_to_dev(kobj);
 	struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev));
 	struct arm_cmn_event_attr *eattr;
+	enum cmn_node_type type;
+	u16 eventid;
 
 	eattr = container_of(attr, typeof(*eattr), attr.attr);
 
 	if (!(eattr->model & cmn->model))
 		return 0;
 
+	type = eattr->type;
+	eventid = eattr->eventid;
+
 	/* Watchpoints aren't nodes, so avoid confusion */
-	if (eattr->type == CMN_TYPE_WP)
+	if (type == CMN_TYPE_WP)
 		return attr->mode;
 
 	/* Hide XP events for unused interfaces/channels */
-	if (eattr->type == CMN_TYPE_XP) {
-		unsigned int intf = (eattr->eventid >> 2) & 7;
-		unsigned int chan = eattr->eventid >> 5;
+	if (type == CMN_TYPE_XP) {
+		unsigned int intf = (eventid >> 2) & 7;
+		unsigned int chan = eventid >> 5;
 
 		if ((intf & 4) && !(cmn->ports_used & BIT(intf & 3)))
 			return 0;
@@ -607,12 +624,29 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 	}
 
 	/* Revision-specific differences */
-	if (cmn->model == CMN600 && cmn->rev < CMN600_R1P2) {
-		if (eattr->type == CMN_TYPE_HNF && eattr->eventid == 0x1b)
-			return 0;
+	if (cmn->model == CMN600) {
+		if (cmn->rev < CMN600_R1P3) {
+			if (type == CMN_TYPE_CXRA && eventid > 0x10)
+				return 0;
+		}
+		if (cmn->rev < CMN600_R1P2) {
+			if (type == CMN_TYPE_HNF && eventid == 0x1b)
+				return 0;
+			if (type == CMN_TYPE_CXRA || type == CMN_TYPE_CXHA)
+				return 0;
+		}
+	} else if (cmn->model == CMN650) {
+		if (cmn->rev < CMN650_R2P0 || cmn->rev == CMN650_R1P2) {
+			if (type == CMN_TYPE_HNF && eventid > 0x22)
+				return 0;
+			if (type == CMN_TYPE_SBSX && eventid == 0x17)
+				return 0;
+			if (type == CMN_TYPE_RNI && eventid > 0x10)
+				return 0;
+		}
 	}
 
-	if (!arm_cmn_node(cmn, eattr->type))
+	if (!arm_cmn_node(cmn, type))
 		return 0;
 
 	return attr->mode;
@@ -626,6 +660,8 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 	CMN_EVENT_ATTR(_model, hnf_##_name, CMN_TYPE_HNF, _event, _occup)
 #define CMN_EVENT_HNI(_name, _event)				\
 	CMN_EVENT_ATTR(CMN_ANY, hni_##_name, CMN_TYPE_HNI, _event, 0)
+#define CMN_EVENT_HNP(_name, _event)				\
+	CMN_EVENT_ATTR(CMN_ANY, hnp_##_name, CMN_TYPE_HNP, _event, 0)
 #define __CMN_EVENT_XP(_name, _event)				\
 	CMN_EVENT_ATTR(CMN_ANY, mxp_##_name, CMN_TYPE_XP, _event, 0)
 #define CMN_EVENT_SBSX(_model, _name, _event)			\
@@ -634,6 +670,10 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 	CMN_EVENT_ATTR(_model, rnid_##_name, CMN_TYPE_RNI, _event, 0)
 #define CMN_EVENT_MTSX(_name, _event)				\
 	CMN_EVENT_ATTR(CMN_ANY, mtsx_##_name, CMN_TYPE_MTSX, _event, 0)
+#define CMN_EVENT_CXRA(_model, _name, _event)				\
+	CMN_EVENT_ATTR(_model, cxra_##_name, CMN_TYPE_CXRA, _event, 0)
+#define CMN_EVENT_CXHA(_name, _event)				\
+	CMN_EVENT_ATTR(CMN_ANY, cxha_##_name, CMN_TYPE_CXHA, _event, 0)
 
 #define CMN_EVENT_DVM(_model, _name, _event)			\
 	_CMN_EVENT_DVM(_model, _name, _event, 0)
@@ -675,20 +715,20 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	_CMN_EVENT_DVM(CMN600, rxreq_trk_occupancy_all, 0x05, 0),
 	_CMN_EVENT_DVM(CMN600, rxreq_trk_occupancy_dvmop, 0x05, 1),
 	_CMN_EVENT_DVM(CMN600, rxreq_trk_occupancy_dvmsync, 0x05, 2),
-	CMN_EVENT_DVM(CI700, dvmop_tlbi,		0x01),
-	CMN_EVENT_DVM(CI700, dvmop_bpi,			0x02),
-	CMN_EVENT_DVM(CI700, dvmop_pici,		0x03),
-	CMN_EVENT_DVM(CI700, dvmop_vici,		0x04),
-	CMN_EVENT_DVM(CI700, dvmsync,			0x05),
-	CMN_EVENT_DVM(CI700, vmid_filtered,		0x06),
-	CMN_EVENT_DVM(CI700, rndop_filtered,		0x07),
-	CMN_EVENT_DVM(CI700, retry,			0x08),
-	CMN_EVENT_DVM(CI700, txsnp_flitv,		0x09),
-	CMN_EVENT_DVM(CI700, txsnp_stall,		0x0a),
-	CMN_EVENT_DVM(CI700, trkfull,			0x0b),
-	_CMN_EVENT_DVM(CI700, trk_occupancy_all,	0x0c, 0),
-	_CMN_EVENT_DVM(CI700, trk_occupancy_dvmop,	0x0c, 1),
-	_CMN_EVENT_DVM(CI700, trk_occupancy_dvmsync,	0x0c, 2),
+	CMN_EVENT_DVM(NOT_CMN600, dvmop_tlbi,		0x01),
+	CMN_EVENT_DVM(NOT_CMN600, dvmop_bpi,		0x02),
+	CMN_EVENT_DVM(NOT_CMN600, dvmop_pici,		0x03),
+	CMN_EVENT_DVM(NOT_CMN600, dvmop_vici,		0x04),
+	CMN_EVENT_DVM(NOT_CMN600, dvmsync,		0x05),
+	CMN_EVENT_DVM(NOT_CMN600, vmid_filtered,	0x06),
+	CMN_EVENT_DVM(NOT_CMN600, rndop_filtered,	0x07),
+	CMN_EVENT_DVM(NOT_CMN600, retry,		0x08),
+	CMN_EVENT_DVM(NOT_CMN600, txsnp_flitv,		0x09),
+	CMN_EVENT_DVM(NOT_CMN600, txsnp_stall,		0x0a),
+	CMN_EVENT_DVM(NOT_CMN600, trkfull,		0x0b),
+	_CMN_EVENT_DVM(NOT_CMN600, trk_occupancy_all,	0x0c, 0),
+	_CMN_EVENT_DVM(NOT_CMN600, trk_occupancy_dvmop,	0x0c, 1),
+	_CMN_EVENT_DVM(NOT_CMN600, trk_occupancy_dvmsync, 0x0c, 2),
 
 	CMN_EVENT_HNF(CMN_ANY, cache_miss,		0x01),
 	CMN_EVENT_HNF(CMN_ANY, slc_sf_cache_access,	0x02),
@@ -725,9 +765,12 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_HNF(CMN_ANY, stash_snp_sent,		0x1d),
 	CMN_EVENT_HNF(CMN_ANY, stash_data_pull,		0x1e),
 	CMN_EVENT_HNF(CMN_ANY, snp_fwded,		0x1f),
-	CMN_EVENT_HNF(CI700, atomic_fwd,		0x20),
-	CMN_EVENT_HNF(CI700, mpam_hardlim,		0x21),
-	CMN_EVENT_HNF(CI700, mpam_softlim,		0x22),
+	CMN_EVENT_HNF(NOT_CMN600, atomic_fwd,		0x20),
+	CMN_EVENT_HNF(NOT_CMN600, mpam_hardlim,		0x21),
+	CMN_EVENT_HNF(NOT_CMN600, mpam_softlim,		0x22),
+	CMN_EVENT_HNF(CMN650, snp_sent_cluster,		0x23),
+	CMN_EVENT_HNF(CMN650, sf_imprecise_evict,	0x24),
+	CMN_EVENT_HNF(CMN650, sf_evict_shared_line,	0x25),
 
 	CMN_EVENT_HNI(rrt_rd_occ_cnt_ovfl,		0x20),
 	CMN_EVENT_HNI(rrt_wr_occ_cnt_ovfl,		0x21),
@@ -749,6 +792,27 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_HNI(nonpcie_serialization,		0x31),
 	CMN_EVENT_HNI(pcie_serialization,		0x32),
 
+	/*
+	 * HN-P events squat on top of the HN-I similarly to DVM events, except
+	 * for being crammed into the same physical node as well. And of course
+	 * where would the fun be if the same events were in the same order...
+	 */
+	CMN_EVENT_HNP(rrt_wr_occ_cnt_ovfl,		0x01),
+	CMN_EVENT_HNP(rdt_wr_occ_cnt_ovfl,		0x02),
+	CMN_EVENT_HNP(wdb_occ_cnt_ovfl,			0x03),
+	CMN_EVENT_HNP(rrt_wr_alloc,			0x04),
+	CMN_EVENT_HNP(rdt_wr_alloc,			0x05),
+	CMN_EVENT_HNP(wdb_alloc,			0x06),
+	CMN_EVENT_HNP(awvalid_no_awready,		0x07),
+	CMN_EVENT_HNP(awready_no_awvalid,		0x08),
+	CMN_EVENT_HNP(wvalid_no_wready,			0x09),
+	CMN_EVENT_HNP(rrt_rd_occ_cnt_ovfl,		0x11),
+	CMN_EVENT_HNP(rdt_rd_occ_cnt_ovfl,		0x12),
+	CMN_EVENT_HNP(rrt_rd_alloc,			0x13),
+	CMN_EVENT_HNP(rdt_rd_alloc,			0x14),
+	CMN_EVENT_HNP(arvalid_no_arready,		0x15),
+	CMN_EVENT_HNP(arready_no_arvalid,		0x16),
+
 	CMN_EVENT_XP(txflit_valid,			0x01),
 	CMN_EVENT_XP(txflit_stall,			0x02),
 	CMN_EVENT_XP(partial_dat_flit,			0x03),
@@ -768,7 +832,7 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_SBSX(CMN_ANY, wdb_occ_cnt_ovfl,	0x14),
 	CMN_EVENT_SBSX(CMN_ANY, rd_axi_trkr_occ_cnt_ovfl, 0x15),
 	CMN_EVENT_SBSX(CMN_ANY, cmo_axi_trkr_occ_cnt_ovfl, 0x16),
-	CMN_EVENT_SBSX(CI700, rdb_occ_cnt_ovfl,		0x17),
+	CMN_EVENT_SBSX(NOT_CMN600, rdb_occ_cnt_ovfl,	0x17),
 	CMN_EVENT_SBSX(CMN_ANY, arvalid_no_arready,	0x21),
 	CMN_EVENT_SBSX(CMN_ANY, awvalid_no_awready,	0x22),
 	CMN_EVENT_SBSX(CMN_ANY, wvalid_no_wready,	0x23),
@@ -795,12 +859,12 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_RNID(CMN600, rdb_replay,		0x12),
 	CMN_EVENT_RNID(CMN600, rdb_hybrid,		0x13),
 	CMN_EVENT_RNID(CMN600, rdb_ord,			0x14),
-	CMN_EVENT_RNID(CI700, padb_occ_ovfl,		0x11),
-	CMN_EVENT_RNID(CI700, rpdb_occ_ovfl,		0x12),
-	CMN_EVENT_RNID(CI700, rrt_occup_ovfl_slice1,	0x13),
-	CMN_EVENT_RNID(CI700, rrt_occup_ovfl_slice2,	0x14),
-	CMN_EVENT_RNID(CI700, rrt_occup_ovfl_slice3,	0x15),
-	CMN_EVENT_RNID(CI700, wrt_throttled,		0x16),
+	CMN_EVENT_RNID(NOT_CMN600, padb_occ_ovfl,	0x11),
+	CMN_EVENT_RNID(NOT_CMN600, rpdb_occ_ovfl,	0x12),
+	CMN_EVENT_RNID(NOT_CMN600, rrt_occup_ovfl_slice1, 0x13),
+	CMN_EVENT_RNID(NOT_CMN600, rrt_occup_ovfl_slice2, 0x14),
+	CMN_EVENT_RNID(NOT_CMN600, rrt_occup_ovfl_slice3, 0x15),
+	CMN_EVENT_RNID(NOT_CMN600, wrt_throttled,	0x16),
 
 	CMN_EVENT_MTSX(tc_lookup,			0x01),
 	CMN_EVENT_MTSX(tc_fill,				0x02),
@@ -815,6 +879,42 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_MTSX(tcq_occ_cnt_ovfl,		0x0b),
 	CMN_EVENT_MTSX(tdb_occ_cnt_ovfl,		0x0c),
 
+	CMN_EVENT_CXRA(CMN_ANY, rht_occ,		0x01),
+	CMN_EVENT_CXRA(CMN_ANY, sht_occ,		0x02),
+	CMN_EVENT_CXRA(CMN_ANY, rdb_occ,		0x03),
+	CMN_EVENT_CXRA(CMN_ANY, wdb_occ,		0x04),
+	CMN_EVENT_CXRA(CMN_ANY, ssb_occ,		0x05),
+	CMN_EVENT_CXRA(CMN_ANY, snp_bcasts,		0x06),
+	CMN_EVENT_CXRA(CMN_ANY, req_chains,		0x07),
+	CMN_EVENT_CXRA(CMN_ANY, req_chain_avglen,	0x08),
+	CMN_EVENT_CXRA(CMN_ANY, chirsp_stalls,		0x09),
+	CMN_EVENT_CXRA(CMN_ANY, chidat_stalls,		0x0a),
+	CMN_EVENT_CXRA(CMN_ANY, cxreq_pcrd_stalls_link0, 0x0b),
+	CMN_EVENT_CXRA(CMN_ANY, cxreq_pcrd_stalls_link1, 0x0c),
+	CMN_EVENT_CXRA(CMN_ANY, cxreq_pcrd_stalls_link2, 0x0d),
+	CMN_EVENT_CXRA(CMN_ANY, cxdat_pcrd_stalls_link0, 0x0e),
+	CMN_EVENT_CXRA(CMN_ANY, cxdat_pcrd_stalls_link1, 0x0f),
+	CMN_EVENT_CXRA(CMN_ANY, cxdat_pcrd_stalls_link2, 0x10),
+	CMN_EVENT_CXRA(CMN_ANY, external_chirsp_stalls,	0x11),
+	CMN_EVENT_CXRA(CMN_ANY, external_chidat_stalls,	0x12),
+	CMN_EVENT_CXRA(NOT_CMN600, cxmisc_pcrd_stalls_link0, 0x13),
+	CMN_EVENT_CXRA(NOT_CMN600, cxmisc_pcrd_stalls_link1, 0x14),
+	CMN_EVENT_CXRA(NOT_CMN600, cxmisc_pcrd_stalls_link2, 0x15),
+
+	CMN_EVENT_CXHA(rddatbyp,			0x21),
+	CMN_EVENT_CXHA(chirsp_up_stall,			0x22),
+	CMN_EVENT_CXHA(chidat_up_stall,			0x23),
+	CMN_EVENT_CXHA(snppcrd_link0_stall,		0x24),
+	CMN_EVENT_CXHA(snppcrd_link1_stall,		0x25),
+	CMN_EVENT_CXHA(snppcrd_link2_stall,		0x26),
+	CMN_EVENT_CXHA(reqtrk_occ,			0x27),
+	CMN_EVENT_CXHA(rdb_occ,				0x28),
+	CMN_EVENT_CXHA(rdbyp_occ,			0x29),
+	CMN_EVENT_CXHA(wdb_occ,				0x2a),
+	CMN_EVENT_CXHA(snptrk_occ,			0x2b),
+	CMN_EVENT_CXHA(sdb_occ,				0x2c),
+	CMN_EVENT_CXHA(snphaz_occ,			0x2d),
+
 	NULL
 };
 
@@ -1652,6 +1752,16 @@ static void arm_cmn_init_node_info(struct arm_cmn *cmn, u32 offset, struct arm_c
 			node->type, node->logid, offset);
 }
 
+static enum cmn_node_type arm_cmn_subtype(enum cmn_node_type type)
+{
+	switch (type) {
+	case CMN_TYPE_HNP:
+		return CMN_TYPE_HNI;
+	default:
+		return CMN_TYPE_INVALID;
+	}
+}
+
 static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 {
 	void __iomem *cfg_region;
@@ -1692,8 +1802,13 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 		cmn->num_dns += FIELD_GET(CMN_CI_CHILD_COUNT, reg);
 	}
 
-	/* Cheeky +1 to help terminate pointer-based iteration later */
-	dn = devm_kcalloc(cmn->dev, cmn->num_dns + 1, sizeof(*dn), GFP_KERNEL);
+	/*
+	 * Some nodes effectively have two separate types, which we'll handle
+	 * by creating one of each internally. For a (very) safe initial upper
+	 * bound, account for double the number of non-XP nodes.
+	 */
+	dn = devm_kcalloc(cmn->dev, cmn->num_dns * 2 - cmn->num_xps,
+			  sizeof(*dn), GFP_KERNEL);
 	if (!dn)
 		return -ENOMEM;
 
@@ -1802,6 +1917,18 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 			case CMN_TYPE_RNSAM:
 			case CMN_TYPE_CXLA:
 				break;
+			/*
+			 * Split "optimised" combination nodes into separate
+			 * types for the different event sets. Offsetting the
+			 * base address lets us handle the second pmu_event_sel
+			 * register via the normal mechanism later.
+			 */
+			case CMN_TYPE_HNP:
+				dn[1] = dn[0];
+				dn[0].pmu_base += CMN_HNP_PMU_EVENT_SEL;
+				dn[1].type = arm_cmn_subtype(dn->type);
+				dn += 2;
+				break;
 			/* Something has gone horribly wrong */
 			default:
 				dev_err(cmn->dev, "invalid device node type: 0x%x\n", dn->type);
@@ -1810,9 +1937,10 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 		}
 	}
 
-	/* Correct for any nodes we skipped */
+	/* Correct for any nodes we added or skipped */
 	cmn->num_dns = dn - cmn->dns;
 
+	/* Cheeky +1 to help terminate pointer-based iteration later */
 	sz = (void *)(dn + 1) - (void *)cmn->dns;
 	dn = devm_krealloc(cmn->dev, cmn->dns, sz, GFP_KERNEL);
 	if (dn)
@@ -1970,6 +2098,7 @@ static int arm_cmn_remove(struct platform_device *pdev)
 #ifdef CONFIG_OF
 static const struct of_device_id arm_cmn_of_match[] = {
 	{ .compatible = "arm,cmn-600", .data = (void *)CMN600 },
+	{ .compatible = "arm,cmn-650", .data = (void *)CMN650 },
 	{ .compatible = "arm,ci-700", .data = (void *)CI700 },
 	{}
 };
@@ -1979,6 +2108,7 @@ MODULE_DEVICE_TABLE(of, arm_cmn_of_match);
 #ifdef CONFIG_ACPI
 static const struct acpi_device_id arm_cmn_acpi_match[] = {
 	{ "ARMHC600", CMN600 },
+	{ "ARMHC650", CMN650 },
 	{}
 };
 MODULE_DEVICE_TABLE(acpi, arm_cmn_acpi_match);
-- 
2.35.3.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 3/4] perf/arm-cmn: Refactor occupancy filter selector
  2022-04-18 22:57 [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Robin Murphy
  2022-04-18 22:57   ` Robin Murphy
  2022-04-18 22:57 ` [PATCH 2/4] perf/arm-cmn: Add CMN-650 support Robin Murphy
@ 2022-04-18 22:57 ` Robin Murphy
  2022-04-18 22:57 ` [PATCH 4/4] perf/arm-cmn: Add CMN-700 support Robin Murphy
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 23+ messages in thread
From: Robin Murphy @ 2022-04-18 22:57 UTC (permalink / raw)
  To: will; +Cc: mark.rutland, linux-arm-kernel

So far, DNs and HN-Fs have each had one event ralated to occupancy
trackers which are filtered by a separate field. CMN-700 raises the
stakes by introducing two more sets of HN-F events with corresponding
additional filter fields. Prepare for this by refactoring our filter
selection and tracking logic to account for multiple filter types
coexisting on the same node. This need not affect the uAPI, which can
just continue to encode any per-event filter setting in the "occupid"
config field, even if it's technically not the most accurate name for
some of them.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/perf/arm-cmn.c | 170 ++++++++++++++++++++++++-----------------
 1 file changed, 98 insertions(+), 72 deletions(-)

diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index cce8516d465c..f9788224df54 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -65,6 +65,8 @@
 
 /* For most nodes, this is all there is */
 #define CMN_PMU_EVENT_SEL		0x000
+/* Technically this is 4 bits wide on DNs, but we only use 2 there anyway */
+#define CMN__PMU_OCCUP1_ID		GENMASK_ULL(34, 32)
 
 /* HN-Ps are weird... */
 #define CMN_HNP_PMU_EVENT_SEL		0x008
@@ -229,6 +231,12 @@ enum cmn_node_type {
 	CMN_TYPE_WP = 0x7770
 };
 
+enum cmn_filter_select {
+	SEL_NONE = -1,
+	SEL_OCCUP1ID,
+	SEL_MAX
+};
+
 struct arm_cmn_node {
 	void __iomem *pmu_base;
 	u16 id, logid;
@@ -238,9 +246,9 @@ struct arm_cmn_node {
 	union {
 		/* DN/HN-F/CXHA */
 		struct {
-			u8 occupid_val;
-			u8 occupid_count;
-		};
+			u8 val : 4;
+			u8 count : 4;
+		} occupid[SEL_MAX];
 		/* XP */
 		u8 dtc;
 	};
@@ -510,6 +518,7 @@ struct arm_cmn_hw_event {
 	u8 dtcs_used;
 	u8 num_dns;
 	u8 dtm_offset;
+	enum cmn_filter_select filter_sel;
 };
 
 #define for_each_hw_dn(hw, dn, i) \
@@ -535,6 +544,7 @@ struct arm_cmn_event_attr {
 	struct device_attribute attr;
 	enum cmn_model model;
 	enum cmn_node_type type;
+	enum cmn_filter_select fsel;
 	u8 eventid;
 	u8 occupid;
 };
@@ -545,22 +555,17 @@ struct arm_cmn_format_attr {
 	int config;
 };
 
-#define CMN_EVENT_ATTR(_model, _name, _type, _eventid, _occupid)	\
+#define _CMN_EVENT_ATTR(_model, _name, _type, _eventid, _occupid, _fsel)\
 	(&((struct arm_cmn_event_attr[]) {{				\
 		.attr = __ATTR(_name, 0444, arm_cmn_event_show, NULL),	\
 		.model = _model,					\
 		.type = _type,						\
 		.eventid = _eventid,					\
 		.occupid = _occupid,					\
+		.fsel = _fsel,						\
 	}})[0].attr.attr)
-
-static bool arm_cmn_is_occup_event(enum cmn_model model,
-				   enum cmn_node_type type, unsigned int id)
-{
-	if (type == CMN_TYPE_DVM)
-		return model == CMN600 ? id == 0x05 : id == 0x0c;
-	return type == CMN_TYPE_HNF && id == 0x0f;
-}
+#define CMN_EVENT_ATTR(_model, _name, _type, _eventid)			\
+	_CMN_EVENT_ATTR(_model, _name, _type, _eventid, 0, SEL_NONE)
 
 static ssize_t arm_cmn_event_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
@@ -577,7 +582,7 @@ 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 (arm_cmn_is_occup_event(eattr->model, eattr->type, eattr->eventid))
+	if (eattr->fsel > SEL_NONE)
 		return sysfs_emit(buf, "type=0x%x,eventid=0x%x,occupid=0x%x\n",
 				  eattr->type, eattr->eventid, eattr->occupid);
 
@@ -652,33 +657,37 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 	return attr->mode;
 }
 
-#define _CMN_EVENT_DVM(_model, _name, _event, _occup)		\
-	CMN_EVENT_ATTR(_model, dn_##_name, CMN_TYPE_DVM, _event, _occup)
+#define _CMN_EVENT_DVM(_model, _name, _event, _occup, _fsel)	\
+	_CMN_EVENT_ATTR(_model, dn_##_name, CMN_TYPE_DVM, _event, _occup, _fsel)
 #define CMN_EVENT_DTC(_name)					\
-	CMN_EVENT_ATTR(CMN_ANY, dtc_##_name, CMN_TYPE_DTC, 0, 0)
-#define _CMN_EVENT_HNF(_model, _name, _event, _occup)		\
-	CMN_EVENT_ATTR(_model, hnf_##_name, CMN_TYPE_HNF, _event, _occup)
+	CMN_EVENT_ATTR(CMN_ANY, dtc_##_name, CMN_TYPE_DTC, 0)
+#define _CMN_EVENT_HNF(_model, _name, _event, _occup, _fsel)		\
+	_CMN_EVENT_ATTR(_model, hnf_##_name, CMN_TYPE_HNF, _event, _occup, _fsel)
 #define CMN_EVENT_HNI(_name, _event)				\
-	CMN_EVENT_ATTR(CMN_ANY, hni_##_name, CMN_TYPE_HNI, _event, 0)
+	CMN_EVENT_ATTR(CMN_ANY, hni_##_name, CMN_TYPE_HNI, _event)
 #define CMN_EVENT_HNP(_name, _event)				\
-	CMN_EVENT_ATTR(CMN_ANY, hnp_##_name, CMN_TYPE_HNP, _event, 0)
+	CMN_EVENT_ATTR(CMN_ANY, hnp_##_name, CMN_TYPE_HNP, _event)
 #define __CMN_EVENT_XP(_name, _event)				\
-	CMN_EVENT_ATTR(CMN_ANY, mxp_##_name, CMN_TYPE_XP, _event, 0)
+	CMN_EVENT_ATTR(CMN_ANY, mxp_##_name, CMN_TYPE_XP, _event)
 #define CMN_EVENT_SBSX(_model, _name, _event)			\
-	CMN_EVENT_ATTR(_model, sbsx_##_name, CMN_TYPE_SBSX, _event, 0)
+	CMN_EVENT_ATTR(_model, sbsx_##_name, CMN_TYPE_SBSX, _event)
 #define CMN_EVENT_RNID(_model, _name, _event)			\
-	CMN_EVENT_ATTR(_model, rnid_##_name, CMN_TYPE_RNI, _event, 0)
+	CMN_EVENT_ATTR(_model, rnid_##_name, CMN_TYPE_RNI, _event)
 #define CMN_EVENT_MTSX(_name, _event)				\
-	CMN_EVENT_ATTR(CMN_ANY, mtsx_##_name, CMN_TYPE_MTSX, _event, 0)
+	CMN_EVENT_ATTR(CMN_ANY, mtsx_##_name, CMN_TYPE_MTSX, _event)
 #define CMN_EVENT_CXRA(_model, _name, _event)				\
-	CMN_EVENT_ATTR(_model, cxra_##_name, CMN_TYPE_CXRA, _event, 0)
+	CMN_EVENT_ATTR(_model, cxra_##_name, CMN_TYPE_CXRA, _event)
 #define CMN_EVENT_CXHA(_name, _event)				\
-	CMN_EVENT_ATTR(CMN_ANY, cxha_##_name, CMN_TYPE_CXHA, _event, 0)
+	CMN_EVENT_ATTR(CMN_ANY, cxha_##_name, CMN_TYPE_CXHA, _event)
 
 #define CMN_EVENT_DVM(_model, _name, _event)			\
-	_CMN_EVENT_DVM(_model, _name, _event, 0)
+	_CMN_EVENT_DVM(_model, _name, _event, 0, SEL_NONE)
+#define CMN_EVENT_DVM_OCC(_model, _name, _event)			\
+	_CMN_EVENT_DVM(_model, _name##_all, _event, 0, SEL_OCCUP1ID),	\
+	_CMN_EVENT_DVM(_model, _name##_dvmop, _event, 1, SEL_OCCUP1ID),	\
+	_CMN_EVENT_DVM(_model, _name##_dvmsync, _event, 2, SEL_OCCUP1ID)
 #define CMN_EVENT_HNF(_model, _name, _event)			\
-	_CMN_EVENT_HNF(_model, _name, _event, 0)
+	_CMN_EVENT_HNF(_model, _name, _event, 0, SEL_NONE)
 #define _CMN_EVENT_XP(_name, _event)				\
 	__CMN_EVENT_XP(e_##_name, (_event) | (0 << 2)),		\
 	__CMN_EVENT_XP(w_##_name, (_event) | (1 << 2)),		\
@@ -712,9 +721,7 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_DVM(CMN600, rxreq_dvmsync,		0x02),
 	CMN_EVENT_DVM(CMN600, rxreq_dvmop_vmid_filtered, 0x03),
 	CMN_EVENT_DVM(CMN600, rxreq_retried,		0x04),
-	_CMN_EVENT_DVM(CMN600, rxreq_trk_occupancy_all, 0x05, 0),
-	_CMN_EVENT_DVM(CMN600, rxreq_trk_occupancy_dvmop, 0x05, 1),
-	_CMN_EVENT_DVM(CMN600, rxreq_trk_occupancy_dvmsync, 0x05, 2),
+	CMN_EVENT_DVM_OCC(CMN600, rxreq_trk_occupancy,	0x05),
 	CMN_EVENT_DVM(NOT_CMN600, dvmop_tlbi,		0x01),
 	CMN_EVENT_DVM(NOT_CMN600, dvmop_bpi,		0x02),
 	CMN_EVENT_DVM(NOT_CMN600, dvmop_pici,		0x03),
@@ -726,9 +733,7 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_DVM(NOT_CMN600, txsnp_flitv,		0x09),
 	CMN_EVENT_DVM(NOT_CMN600, txsnp_stall,		0x0a),
 	CMN_EVENT_DVM(NOT_CMN600, trkfull,		0x0b),
-	_CMN_EVENT_DVM(NOT_CMN600, trk_occupancy_all,	0x0c, 0),
-	_CMN_EVENT_DVM(NOT_CMN600, trk_occupancy_dvmop,	0x0c, 1),
-	_CMN_EVENT_DVM(NOT_CMN600, trk_occupancy_dvmsync, 0x0c, 2),
+	CMN_EVENT_DVM_OCC(NOT_CMN600, trk_occupancy,	0x0c),
 
 	CMN_EVENT_HNF(CMN_ANY, cache_miss,		0x01),
 	CMN_EVENT_HNF(CMN_ANY, slc_sf_cache_access,	0x02),
@@ -744,11 +749,11 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_HNF(CMN_ANY, mc_retries,		0x0c),
 	CMN_EVENT_HNF(CMN_ANY, mc_reqs,			0x0d),
 	CMN_EVENT_HNF(CMN_ANY, qos_hh_retry,		0x0e),
-	_CMN_EVENT_HNF(CMN_ANY, qos_pocq_occupancy_all,	0x0f, 0),
-	_CMN_EVENT_HNF(CMN_ANY, qos_pocq_occupancy_read, 0x0f, 1),
-	_CMN_EVENT_HNF(CMN_ANY, qos_pocq_occupancy_write, 0x0f, 2),
-	_CMN_EVENT_HNF(CMN_ANY, qos_pocq_occupancy_atomic, 0x0f, 3),
-	_CMN_EVENT_HNF(CMN_ANY, qos_pocq_occupancy_stash, 0x0f, 4),
+	_CMN_EVENT_HNF(CMN_ANY, qos_pocq_occupancy_all,	0x0f, 0, SEL_OCCUP1ID),
+	_CMN_EVENT_HNF(CMN_ANY, qos_pocq_occupancy_read, 0x0f, 1, SEL_OCCUP1ID),
+	_CMN_EVENT_HNF(CMN_ANY, qos_pocq_occupancy_write, 0x0f, 2, SEL_OCCUP1ID),
+	_CMN_EVENT_HNF(CMN_ANY, qos_pocq_occupancy_atomic, 0x0f, 3, SEL_OCCUP1ID),
+	_CMN_EVENT_HNF(CMN_ANY, qos_pocq_occupancy_stash, 0x0f, 4, SEL_OCCUP1ID),
 	CMN_EVENT_HNF(CMN_ANY, pocq_addrhaz,		0x10),
 	CMN_EVENT_HNF(CMN_ANY, pocq_atomic_addrhaz,	0x11),
 	CMN_EVENT_HNF(CMN_ANY, ld_st_swp_adq_full,	0x12),
@@ -817,8 +822,8 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_XP(txflit_stall,			0x02),
 	CMN_EVENT_XP(partial_dat_flit,			0x03),
 	/* We treat watchpoints as a special made-up class of XP events */
-	CMN_EVENT_ATTR(CMN_ANY, watchpoint_up, CMN_TYPE_WP, CMN_WP_UP, 0),
-	CMN_EVENT_ATTR(CMN_ANY, watchpoint_down, CMN_TYPE_WP, CMN_WP_DOWN, 0),
+	CMN_EVENT_ATTR(CMN_ANY, watchpoint_up, CMN_TYPE_WP, CMN_WP_UP),
+	CMN_EVENT_ATTR(CMN_ANY, watchpoint_down, CMN_TYPE_WP, CMN_WP_DOWN),
 
 	CMN_EVENT_SBSX(CMN_ANY, rd_req,			0x01),
 	CMN_EVENT_SBSX(CMN_ANY, wr_req,			0x02),
@@ -1132,6 +1137,26 @@ static void arm_cmn_event_read(struct perf_event *event)
 	local64_add(delta, &event->count);
 }
 
+static int arm_cmn_set_event_sel_hi(struct arm_cmn_node *dn,
+				    enum cmn_filter_select fsel, u8 occupid)
+{
+	u64 reg;
+
+	if (fsel == SEL_NONE)
+		return 0;
+
+	if (!dn->occupid[fsel].count) {
+		dn->occupid[fsel].val = occupid;
+		reg = FIELD_PREP(CMN__PMU_OCCUP1_ID,
+				 dn->occupid[SEL_OCCUP1ID].val);
+		writel_relaxed(reg >> 32, dn->pmu_base + CMN_PMU_EVENT_SEL + 4);
+	} else if (dn->occupid[fsel].val != occupid) {
+		return -EBUSY;
+	}
+	dn->occupid[fsel].count++;
+	return 0;
+}
+
 static void arm_cmn_event_start(struct perf_event *event, int flags)
 {
 	struct arm_cmn *cmn = to_cmn(event->pmu);
@@ -1195,7 +1220,7 @@ static void arm_cmn_event_stop(struct perf_event *event, int flags)
 
 struct arm_cmn_val {
 	u8 dtm_count[CMN_MAX_DTMS];
-	u8 occupid[CMN_MAX_DTMS];
+	u8 occupid[CMN_MAX_DTMS][SEL_MAX];
 	u8 wp[CMN_MAX_DTMS][4];
 	int dtc_count;
 	bool cycles;
@@ -1208,7 +1233,6 @@ static void arm_cmn_val_add_event(struct arm_cmn *cmn, struct arm_cmn_val *val,
 	struct arm_cmn_node *dn;
 	enum cmn_node_type type;
 	int i;
-	u8 occupid;
 
 	if (is_software_event(event))
 		return;
@@ -1220,16 +1244,14 @@ static void arm_cmn_val_add_event(struct arm_cmn *cmn, struct arm_cmn_val *val,
 	}
 
 	val->dtc_count++;
-	if (arm_cmn_is_occup_event(cmn->model, type, CMN_EVENT_EVENTID(event)))
-		occupid = CMN_EVENT_OCCUPID(event) + 1;
-	else
-		occupid = 0;
 
 	for_each_hw_dn(hw, dn, i) {
-		int wp_idx, dtm = dn->dtm;
+		int wp_idx, dtm = dn->dtm, sel = hw->filter_sel;
 
 		val->dtm_count[dtm]++;
-		val->occupid[dtm] = occupid;
+
+		if (sel > SEL_NONE)
+			val->occupid[dtm][sel] = CMN_EVENT_OCCUPID(event) + 1;
 
 		if (type != CMN_TYPE_WP)
 			continue;
@@ -1247,7 +1269,6 @@ static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event)
 	enum cmn_node_type type;
 	struct arm_cmn_val *val;
 	int i, ret = -EINVAL;
-	u8 occupid;
 
 	if (leader == event)
 		return 0;
@@ -1272,18 +1293,14 @@ static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event)
 	if (val->dtc_count == CMN_DT_NUM_COUNTERS)
 		goto done;
 
-	if (arm_cmn_is_occup_event(cmn->model, type, CMN_EVENT_EVENTID(event)))
-		occupid = CMN_EVENT_OCCUPID(event) + 1;
-	else
-		occupid = 0;
-
 	for_each_hw_dn(hw, dn, i) {
-		int wp_idx, wp_cmb, dtm = dn->dtm;
+		int wp_idx, wp_cmb, dtm = dn->dtm, sel = hw->filter_sel;
 
 		if (val->dtm_count[dtm] == CMN_DTM_NUM_COUNTERS)
 			goto done;
 
-		if (occupid && val->occupid[dtm] && occupid != val->occupid[dtm])
+		if (sel > SEL_NONE && val->occupid[dtm][sel] &&
+		    val->occupid[dtm][sel] != CMN_EVENT_OCCUPID(event) + 1)
 			goto done;
 
 		if (type != CMN_TYPE_WP)
@@ -1304,6 +1321,22 @@ static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event)
 	return ret;
 }
 
+static enum cmn_filter_select arm_cmn_filter_sel(enum cmn_model model,
+						 enum cmn_node_type type,
+						 unsigned int eventid)
+{
+	struct arm_cmn_event_attr *e;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(arm_cmn_event_attrs); 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->fsel;
+	}
+	return SEL_NONE;
+}
+
+
 static int arm_cmn_event_init(struct perf_event *event)
 {
 	struct arm_cmn *cmn = to_cmn(event->pmu);
@@ -1328,11 +1361,11 @@ static int arm_cmn_event_init(struct perf_event *event)
 	if (type == CMN_TYPE_DTC)
 		return 0;
 
+	eventid = CMN_EVENT_EVENTID(event);
 	/* For watchpoints we need the actual XP node here */
 	if (type == CMN_TYPE_WP) {
 		type = CMN_TYPE_XP;
 		/* ...and we need a "real" direction */
-		eventid = CMN_EVENT_EVENTID(event);
 		if (eventid != CMN_WP_UP && eventid != CMN_WP_DOWN)
 			return -EINVAL;
 		/* ...but the DTM may depend on which port we're watching */
@@ -1340,6 +1373,9 @@ static int arm_cmn_event_init(struct perf_event *event)
 			hw->dtm_offset = CMN_EVENT_WP_DEV_SEL(event) / 2;
 	}
 
+	/* This is sufficiently annoying to recalculate, so cache it */
+	hw->filter_sel = arm_cmn_filter_sel(cmn->model, type, eventid);
+
 	bynodeid = CMN_EVENT_BYNODEID(event);
 	nodeid = CMN_EVENT_NODEID(event);
 
@@ -1381,8 +1417,8 @@ static void arm_cmn_event_clear(struct arm_cmn *cmn, struct perf_event *event,
 		if (type == CMN_TYPE_WP)
 			dtm->wp_event[arm_cmn_wp_idx(event)] = -1;
 
-		if (arm_cmn_is_occup_event(cmn->model, type, CMN_EVENT_EVENTID(event)))
-			hw->dn[i].occupid_count--;
+		if (hw->filter_sel > SEL_NONE)
+			hw->dn[i].occupid[hw->filter_sel].count--;
 
 		dtm->pmu_config_low &= ~CMN__PMEVCNT_PAIRED(dtm_idx);
 		writel_relaxed(dtm->pmu_config_low, dtm->base + CMN_DTM_PMU_CONFIG);
@@ -1462,18 +1498,8 @@ static int arm_cmn_event_add(struct perf_event *event, int flags)
 			input_sel = CMN__PMEVCNT0_INPUT_SEL_DEV + dtm_idx +
 				    (nid.port << 4) + (nid.dev << 2);
 
-			if (arm_cmn_is_occup_event(cmn->model, type, CMN_EVENT_EVENTID(event))) {
-				u8 occupid = CMN_EVENT_OCCUPID(event);
-
-				if (dn->occupid_count == 0) {
-					dn->occupid_val = occupid;
-					writel_relaxed(occupid,
-						       dn->pmu_base + CMN_PMU_EVENT_SEL + 4);
-				} else if (dn->occupid_val != occupid) {
-					goto free_dtms;
-				}
-				dn->occupid_count++;
-			}
+			if (arm_cmn_set_event_sel_hi(dn, hw->filter_sel, CMN_EVENT_OCCUPID(event)))
+				goto free_dtms;
 		}
 
 		arm_cmn_set_index(hw->dtm_idx, i, dtm_idx);
-- 
2.35.3.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 4/4] perf/arm-cmn: Add CMN-700 support
  2022-04-18 22:57 [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Robin Murphy
                   ` (2 preceding siblings ...)
  2022-04-18 22:57 ` [PATCH 3/4] perf/arm-cmn: Refactor occupancy filter selector Robin Murphy
@ 2022-04-18 22:57 ` Robin Murphy
  2022-04-21  7:54 ` [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Ilkka Koskinen
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 23+ messages in thread
From: Robin Murphy @ 2022-04-18 22:57 UTC (permalink / raw)
  To: will; +Cc: mark.rutland, linux-arm-kernel

Add the identifiers, events, and subtleties for CMN-700. Highlights
include yet more options for doubling up CHI channels, which finally
grows event IDs beyond 8 bits for XPs, and a new set of CML gateway
nodes adding support for CXL as well as CCIX, where the Link Agent is
now internal to the CMN mesh so we gain regular PMU events for that too.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/perf/arm-cmn.c | 236 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 220 insertions(+), 16 deletions(-)

diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index f9788224df54..62f3842d1a47 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -52,6 +52,10 @@
 #define CMN_INFO_RSP_VC_NUM		GENMASK_ULL(53, 52)
 #define CMN_INFO_DAT_VC_NUM		GENMASK_ULL(51, 50)
 
+#define CMN_CFGM_INFO_GLOBAL_1		0x908
+#define CMN_INFO_SNP_VC_NUM		GENMASK_ULL(3, 2)
+#define CMN_INFO_REQ_VC_NUM		GENMASK_ULL(1, 0)
+
 /* XPs also have some local topology info which has uses too */
 #define CMN_MXP__CONNECT_INFO_P0	0x0008
 #define CMN_MXP__CONNECT_INFO_P1	0x0010
@@ -65,6 +69,8 @@
 
 /* For most nodes, this is all there is */
 #define CMN_PMU_EVENT_SEL		0x000
+#define CMN__PMU_CBUSY_SNTHROTTLE_SEL	GENMASK_ULL(44, 42)
+#define CMN__PMU_CLASS_OCCUP_ID		GENMASK_ULL(36, 35)
 /* Technically this is 4 bits wide on DNs, but we only use 2 there anyway */
 #define CMN__PMU_OCCUP1_ID		GENMASK_ULL(34, 32)
 
@@ -74,7 +80,8 @@
 /* DTMs live in the PMU space of XP registers */
 #define CMN_DTM_WPn(n)			(0x1A0 + (n) * 0x18)
 #define CMN_DTM_WPn_CONFIG(n)		(CMN_DTM_WPn(n) + 0x00)
-#define CMN_DTM_WPn_CONFIG_WP_DEV_SEL2	GENMASK_ULL(18,17)
+#define CMN_DTM_WPn_CONFIG_WP_CHN_NUM	GENMASK_ULL(20, 19)
+#define CMN_DTM_WPn_CONFIG_WP_DEV_SEL2	GENMASK_ULL(18, 17)
 #define CMN_DTM_WPn_CONFIG_WP_COMBINE	BIT(9)
 #define CMN_DTM_WPn_CONFIG_WP_EXCLUSIVE	BIT(8)
 #define CMN600_WPn_CONFIG_WP_COMBINE	BIT(6)
@@ -147,8 +154,8 @@
 
 /* Event attributes */
 #define CMN_CONFIG_TYPE			GENMASK_ULL(15, 0)
-#define CMN_CONFIG_EVENTID		GENMASK_ULL(23, 16)
-#define CMN_CONFIG_OCCUPID		GENMASK_ULL(27, 24)
+#define CMN_CONFIG_EVENTID		GENMASK_ULL(26, 16)
+#define CMN_CONFIG_OCCUPID		GENMASK_ULL(30, 27)
 #define CMN_CONFIG_BYNODEID		BIT_ULL(31)
 #define CMN_CONFIG_NODEID		GENMASK_ULL(47, 32)
 
@@ -183,10 +190,12 @@
 enum cmn_model {
 	CMN600 = 1,
 	CMN650 = 2,
+	CMN700 = 4,
 	CI700 = 8,
 	/* ...and then we can use bitmap tricks for commonality */
 	CMN_ANY = -1,
 	NOT_CMN600 = -2,
+	CMN_650ON = CMN650 | CMN700,
 };
 
 /* CMN-600 r0px shouldn't exist in silicon, thankfully */
@@ -203,6 +212,9 @@ enum cmn_revision {
 	CMN650_R1P1,
 	CMN650_R2P0,
 	CMN650_R1P2,
+	CMN700_R0P0 = 0,
+	CMN700_R1P0,
+	CMN700_R2P0,
 	CI700_R0P0 = 0,
 	CI700_R1P0,
 	CI700_R2P0,
@@ -225,8 +237,12 @@ enum cmn_node_type {
 	CMN_TYPE_MTSX,
 	CMN_TYPE_HNP,
 	CMN_TYPE_CXRA = 0x100,
-	CMN_TYPE_CXHA = 0x101,
-	CMN_TYPE_CXLA = 0x102,
+	CMN_TYPE_CXHA,
+	CMN_TYPE_CXLA,
+	CMN_TYPE_CCRA,
+	CMN_TYPE_CCHA,
+	CMN_TYPE_CCLA,
+	CMN_TYPE_CCLA_RNI,
 	/* Not a real node type */
 	CMN_TYPE_WP = 0x7770
 };
@@ -234,6 +250,8 @@ enum cmn_node_type {
 enum cmn_filter_select {
 	SEL_NONE = -1,
 	SEL_OCCUP1ID,
+	SEL_CLASS_OCCUP_ID,
+	SEL_CBUSY_SNTHROTTLE_SEL,
 	SEL_MAX
 };
 
@@ -255,6 +273,8 @@ struct arm_cmn_node {
 	union {
 		u8 event[4];
 		__le32 event_sel;
+		u16 event_w[4];
+		__le64 event_sel_w;
 	};
 };
 
@@ -297,6 +317,8 @@ struct arm_cmn {
 	struct {
 		unsigned int rsp_vc_num : 2;
 		unsigned int dat_vc_num : 2;
+		unsigned int snp_vc_num : 2;
+		unsigned int req_vc_num : 2;
 	};
 
 	struct arm_cmn_node *xps;
@@ -405,6 +427,8 @@ static const char *arm_cmn_device_type(u8 type)
 		case 0x18: return " RN-F_E |";
 		case 0x19: return "RN-F_E_E|";
 		case 0x1c: return "  MTSX  |";
+		case 0x1d: return "  HN-V  |";
+		case 0x1e: return "  CCG   |";
 		default:   return "  ????  |";
 	}
 }
@@ -518,6 +542,7 @@ struct arm_cmn_hw_event {
 	u8 dtcs_used;
 	u8 num_dns;
 	u8 dtm_offset;
+	bool wide_sel;
 	enum cmn_filter_select filter_sel;
 };
 
@@ -545,7 +570,7 @@ struct arm_cmn_event_attr {
 	enum cmn_model model;
 	enum cmn_node_type type;
 	enum cmn_filter_select fsel;
-	u8 eventid;
+	u16 eventid;
 	u8 occupid;
 };
 
@@ -624,7 +649,9 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 			return 0;
 
 		if ((chan == 5 && cmn->rsp_vc_num < 2) ||
-		    (chan == 6 && cmn->dat_vc_num < 2))
+		    (chan == 6 && cmn->dat_vc_num < 2) ||
+		    (chan == 7 && cmn->snp_vc_num < 2) ||
+		    (chan == 8 && cmn->req_vc_num < 2))
 			return 0;
 	}
 
@@ -649,6 +676,19 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 			if (type == CMN_TYPE_RNI && eventid > 0x10)
 				return 0;
 		}
+	} else if (cmn->model == CMN700) {
+		if (cmn->rev < CMN700_R2P0) {
+			if (type == CMN_TYPE_HNF && eventid > 0x2c)
+				return 0;
+			if (type == CMN_TYPE_CCHA && eventid > 0x74)
+				return 0;
+			if (type == CMN_TYPE_CCLA && eventid > 0x27)
+				return 0;
+		}
+		if (cmn->rev < CMN700_R1P0) {
+			if (type == CMN_TYPE_HNF && eventid > 0x2b)
+				return 0;
+		}
 	}
 
 	if (!arm_cmn_node(cmn, type))
@@ -679,6 +719,14 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 	CMN_EVENT_ATTR(_model, cxra_##_name, CMN_TYPE_CXRA, _event)
 #define CMN_EVENT_CXHA(_name, _event)				\
 	CMN_EVENT_ATTR(CMN_ANY, cxha_##_name, CMN_TYPE_CXHA, _event)
+#define CMN_EVENT_CCRA(_name, _event)				\
+	CMN_EVENT_ATTR(CMN_ANY, ccra_##_name, CMN_TYPE_CCRA, _event)
+#define CMN_EVENT_CCHA(_name, _event)				\
+	CMN_EVENT_ATTR(CMN_ANY, 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_CCLA_RNI(_name, _event)				\
+	CMN_EVENT_ATTR(CMN_ANY, ccla_rni_##_name, CMN_TYPE_CCLA_RNI, _event)
 
 #define CMN_EVENT_DVM(_model, _name, _event)			\
 	_CMN_EVENT_DVM(_model, _name, _event, 0, SEL_NONE)
@@ -688,6 +736,20 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 	_CMN_EVENT_DVM(_model, _name##_dvmsync, _event, 2, SEL_OCCUP1ID)
 #define CMN_EVENT_HNF(_model, _name, _event)			\
 	_CMN_EVENT_HNF(_model, _name, _event, 0, SEL_NONE)
+#define CMN_EVENT_HNF_CLS(_model, _name, _event)			\
+	_CMN_EVENT_HNF(_model, _name##_class0, _event, 0, SEL_CLASS_OCCUP_ID), \
+	_CMN_EVENT_HNF(_model, _name##_class1, _event, 1, SEL_CLASS_OCCUP_ID), \
+	_CMN_EVENT_HNF(_model, _name##_class2, _event, 2, SEL_CLASS_OCCUP_ID), \
+	_CMN_EVENT_HNF(_model, _name##_class3, _event, 3, SEL_CLASS_OCCUP_ID)
+#define CMN_EVENT_HNF_SNT(_model, _name, _event)			\
+	_CMN_EVENT_HNF(_model, _name##_all, _event, 0, SEL_CBUSY_SNTHROTTLE_SEL), \
+	_CMN_EVENT_HNF(_model, _name##_group0_read, _event, 1, SEL_CBUSY_SNTHROTTLE_SEL), \
+	_CMN_EVENT_HNF(_model, _name##_group0_write, _event, 2, SEL_CBUSY_SNTHROTTLE_SEL), \
+	_CMN_EVENT_HNF(_model, _name##_group1_read, _event, 3, SEL_CBUSY_SNTHROTTLE_SEL), \
+	_CMN_EVENT_HNF(_model, _name##_group1_write, _event, 4, SEL_CBUSY_SNTHROTTLE_SEL), \
+	_CMN_EVENT_HNF(_model, _name##_read, _event, 5, SEL_CBUSY_SNTHROTTLE_SEL), \
+	_CMN_EVENT_HNF(_model, _name##_write, _event, 6, SEL_CBUSY_SNTHROTTLE_SEL)
+
 #define _CMN_EVENT_XP(_name, _event)				\
 	__CMN_EVENT_XP(e_##_name, (_event) | (0 << 2)),		\
 	__CMN_EVENT_XP(w_##_name, (_event) | (1 << 2)),		\
@@ -706,7 +768,9 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 	_CMN_EVENT_XP(dat_##_name, (_event) | (3 << 5)),	\
 	_CMN_EVENT_XP(pub_##_name, (_event) | (4 << 5)),	\
 	_CMN_EVENT_XP(rsp2_##_name, (_event) | (5 << 5)),	\
-	_CMN_EVENT_XP(dat2_##_name, (_event) | (6 << 5))
+	_CMN_EVENT_XP(dat2_##_name, (_event) | (6 << 5)),	\
+	_CMN_EVENT_XP(snp2_##_name, (_event) | (7 << 5)),	\
+	_CMN_EVENT_XP(req2_##_name, (_event) | (8 << 5))
 
 
 static struct attribute *arm_cmn_event_attrs[] = {
@@ -734,6 +798,14 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_DVM(NOT_CMN600, txsnp_stall,		0x0a),
 	CMN_EVENT_DVM(NOT_CMN600, trkfull,		0x0b),
 	CMN_EVENT_DVM_OCC(NOT_CMN600, trk_occupancy,	0x0c),
+	CMN_EVENT_DVM_OCC(CMN700, trk_occupancy_cxha,	0x0d),
+	CMN_EVENT_DVM_OCC(CMN700, trk_occupancy_pdn,	0x0e),
+	CMN_EVENT_DVM(CMN700, trk_alloc,		0x0f),
+	CMN_EVENT_DVM(CMN700, trk_cxha_alloc,		0x10),
+	CMN_EVENT_DVM(CMN700, trk_pdn_alloc,		0x11),
+	CMN_EVENT_DVM(CMN700, txsnp_stall_limit,	0x12),
+	CMN_EVENT_DVM(CMN700, rxsnp_stall_starv,	0x13),
+	CMN_EVENT_DVM(CMN700, txsnp_sync_stall_op,	0x14),
 
 	CMN_EVENT_HNF(CMN_ANY, cache_miss,		0x01),
 	CMN_EVENT_HNF(CMN_ANY, slc_sf_cache_access,	0x02),
@@ -773,9 +845,19 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_HNF(NOT_CMN600, atomic_fwd,		0x20),
 	CMN_EVENT_HNF(NOT_CMN600, mpam_hardlim,		0x21),
 	CMN_EVENT_HNF(NOT_CMN600, mpam_softlim,		0x22),
-	CMN_EVENT_HNF(CMN650, snp_sent_cluster,		0x23),
-	CMN_EVENT_HNF(CMN650, sf_imprecise_evict,	0x24),
-	CMN_EVENT_HNF(CMN650, sf_evict_shared_line,	0x25),
+	CMN_EVENT_HNF(CMN_650ON, snp_sent_cluster,	0x23),
+	CMN_EVENT_HNF(CMN_650ON, sf_imprecise_evict,	0x24),
+	CMN_EVENT_HNF(CMN_650ON, sf_evict_shared_line,	0x25),
+	CMN_EVENT_HNF_CLS(CMN700, pocq_class_occup,	0x26),
+	CMN_EVENT_HNF_CLS(CMN700, pocq_class_retry,	0x27),
+	CMN_EVENT_HNF_CLS(CMN700, class_mc_reqs,	0x28),
+	CMN_EVENT_HNF_CLS(CMN700, class_cgnt_cmin,	0x29),
+	CMN_EVENT_HNF_SNT(CMN700, sn_throttle,		0x2a),
+	CMN_EVENT_HNF_SNT(CMN700, sn_throttle_min,	0x2b),
+	CMN_EVENT_HNF(CMN700, sf_precise_to_imprecise,	0x2c),
+	CMN_EVENT_HNF(CMN700, snp_intv_cln,		0x2d),
+	CMN_EVENT_HNF(CMN700, nc_excl,			0x2e),
+	CMN_EVENT_HNF(CMN700, excl_mon_ovfl,		0x2f),
 
 	CMN_EVENT_HNI(rrt_rd_occ_cnt_ovfl,		0x20),
 	CMN_EVENT_HNI(rrt_wr_occ_cnt_ovfl,		0x21),
@@ -870,6 +952,19 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_RNID(NOT_CMN600, rrt_occup_ovfl_slice2, 0x14),
 	CMN_EVENT_RNID(NOT_CMN600, rrt_occup_ovfl_slice3, 0x15),
 	CMN_EVENT_RNID(NOT_CMN600, wrt_throttled,	0x16),
+	CMN_EVENT_RNID(CMN700, ldb_full,		0x17),
+	CMN_EVENT_RNID(CMN700, rrt_rd_req_occup_ovfl_slice0, 0x18),
+	CMN_EVENT_RNID(CMN700, rrt_rd_req_occup_ovfl_slice1, 0x19),
+	CMN_EVENT_RNID(CMN700, rrt_rd_req_occup_ovfl_slice2, 0x1a),
+	CMN_EVENT_RNID(CMN700, rrt_rd_req_occup_ovfl_slice3, 0x1b),
+	CMN_EVENT_RNID(CMN700, rrt_burst_occup_ovfl_slice0, 0x1c),
+	CMN_EVENT_RNID(CMN700, rrt_burst_occup_ovfl_slice1, 0x1d),
+	CMN_EVENT_RNID(CMN700, rrt_burst_occup_ovfl_slice2, 0x1e),
+	CMN_EVENT_RNID(CMN700, rrt_burst_occup_ovfl_slice3, 0x1f),
+	CMN_EVENT_RNID(CMN700, rrt_burst_alloc,		0x20),
+	CMN_EVENT_RNID(CMN700, awid_hash,		0x21),
+	CMN_EVENT_RNID(CMN700, atomic_alloc,		0x22),
+	CMN_EVENT_RNID(CMN700, atomic_occ_ovfl,		0x23),
 
 	CMN_EVENT_MTSX(tc_lookup,			0x01),
 	CMN_EVENT_MTSX(tc_fill,				0x02),
@@ -920,6 +1015,82 @@ static struct attribute *arm_cmn_event_attrs[] = {
 	CMN_EVENT_CXHA(sdb_occ,				0x2c),
 	CMN_EVENT_CXHA(snphaz_occ,			0x2d),
 
+	CMN_EVENT_CCRA(rht_occ,				0x41),
+	CMN_EVENT_CCRA(sht_occ,				0x42),
+	CMN_EVENT_CCRA(rdb_occ,				0x43),
+	CMN_EVENT_CCRA(wdb_occ,				0x44),
+	CMN_EVENT_CCRA(ssb_occ,				0x45),
+	CMN_EVENT_CCRA(snp_bcasts,			0x46),
+	CMN_EVENT_CCRA(req_chains,			0x47),
+	CMN_EVENT_CCRA(req_chain_avglen,		0x48),
+	CMN_EVENT_CCRA(chirsp_stalls,			0x49),
+	CMN_EVENT_CCRA(chidat_stalls,			0x4a),
+	CMN_EVENT_CCRA(cxreq_pcrd_stalls_link0,		0x4b),
+	CMN_EVENT_CCRA(cxreq_pcrd_stalls_link1,		0x4c),
+	CMN_EVENT_CCRA(cxreq_pcrd_stalls_link2,		0x4d),
+	CMN_EVENT_CCRA(cxdat_pcrd_stalls_link0,		0x4e),
+	CMN_EVENT_CCRA(cxdat_pcrd_stalls_link1,		0x4f),
+	CMN_EVENT_CCRA(cxdat_pcrd_stalls_link2,		0x50),
+	CMN_EVENT_CCRA(external_chirsp_stalls,		0x51),
+	CMN_EVENT_CCRA(external_chidat_stalls,		0x52),
+	CMN_EVENT_CCRA(cxmisc_pcrd_stalls_link0,	0x53),
+	CMN_EVENT_CCRA(cxmisc_pcrd_stalls_link1,	0x54),
+	CMN_EVENT_CCRA(cxmisc_pcrd_stalls_link2,	0x55),
+	CMN_EVENT_CCRA(rht_alloc,			0x56),
+	CMN_EVENT_CCRA(sht_alloc,			0x57),
+	CMN_EVENT_CCRA(rdb_alloc,			0x58),
+	CMN_EVENT_CCRA(wdb_alloc,			0x59),
+	CMN_EVENT_CCRA(ssb_alloc,			0x5a),
+
+	CMN_EVENT_CCHA(rddatbyp,			0x61),
+	CMN_EVENT_CCHA(chirsp_up_stall,			0x62),
+	CMN_EVENT_CCHA(chidat_up_stall,			0x63),
+	CMN_EVENT_CCHA(snppcrd_link0_stall,		0x64),
+	CMN_EVENT_CCHA(snppcrd_link1_stall,		0x65),
+	CMN_EVENT_CCHA(snppcrd_link2_stall,		0x66),
+	CMN_EVENT_CCHA(reqtrk_occ,			0x67),
+	CMN_EVENT_CCHA(rdb_occ,				0x68),
+	CMN_EVENT_CCHA(rdbyp_occ,			0x69),
+	CMN_EVENT_CCHA(wdb_occ,				0x6a),
+	CMN_EVENT_CCHA(snptrk_occ,			0x6b),
+	CMN_EVENT_CCHA(sdb_occ,				0x6c),
+	CMN_EVENT_CCHA(snphaz_occ,			0x6d),
+	CMN_EVENT_CCHA(reqtrk_alloc,			0x6e),
+	CMN_EVENT_CCHA(rdb_alloc,			0x6f),
+	CMN_EVENT_CCHA(rdbyp_alloc,			0x70),
+	CMN_EVENT_CCHA(wdb_alloc,			0x71),
+	CMN_EVENT_CCHA(snptrk_alloc,			0x72),
+	CMN_EVENT_CCHA(sdb_alloc,			0x73),
+	CMN_EVENT_CCHA(snphaz_alloc,			0x74),
+	CMN_EVENT_CCHA(pb_rhu_req_occ,			0x75),
+	CMN_EVENT_CCHA(pb_rhu_req_alloc,		0x76),
+	CMN_EVENT_CCHA(pb_rhu_pcie_req_occ,		0x77),
+	CMN_EVENT_CCHA(pb_rhu_pcie_req_alloc,		0x78),
+	CMN_EVENT_CCHA(pb_pcie_wr_req_occ,		0x79),
+	CMN_EVENT_CCHA(pb_pcie_wr_req_alloc,		0x7a),
+	CMN_EVENT_CCHA(pb_pcie_reg_req_occ,		0x7b),
+	CMN_EVENT_CCHA(pb_pcie_reg_req_alloc,		0x7c),
+	CMN_EVENT_CCHA(pb_pcie_rsvd_req_occ,		0x7d),
+	CMN_EVENT_CCHA(pb_pcie_rsvd_req_alloc,		0x7e),
+	CMN_EVENT_CCHA(pb_rhu_dat_occ,			0x7f),
+	CMN_EVENT_CCHA(pb_rhu_dat_alloc,		0x80),
+	CMN_EVENT_CCHA(pb_rhu_pcie_dat_occ,		0x81),
+	CMN_EVENT_CCHA(pb_rhu_pcie_dat_alloc,		0x82),
+	CMN_EVENT_CCHA(pb_pcie_wr_dat_occ,		0x83),
+	CMN_EVENT_CCHA(pb_pcie_wr_dat_alloc,		0x84),
+
+	CMN_EVENT_CCLA(rx_cxs,				0x21),
+	CMN_EVENT_CCLA(tx_cxs,				0x22),
+	CMN_EVENT_CCLA(rx_cxs_avg_size,			0x23),
+	CMN_EVENT_CCLA(tx_cxs_avg_size,			0x24),
+	CMN_EVENT_CCLA(tx_cxs_lcrd_backpressure,	0x25),
+	CMN_EVENT_CCLA(link_crdbuf_occ,			0x26),
+	CMN_EVENT_CCLA(link_crdbuf_alloc,		0x27),
+	CMN_EVENT_CCLA(pfwd_rcvr_cxs,			0x28),
+	CMN_EVENT_CCLA(pfwd_sndr_num_flits,		0x29),
+	CMN_EVENT_CCLA(pfwd_sndr_stalls_static_crd,	0x2a),
+	CMN_EVENT_CCLA(pfwd_sndr_stalls_dynmaic_crd,	0x2b),
+
 	NULL
 };
 
@@ -1147,7 +1318,11 @@ static int arm_cmn_set_event_sel_hi(struct arm_cmn_node *dn,
 
 	if (!dn->occupid[fsel].count) {
 		dn->occupid[fsel].val = occupid;
-		reg = FIELD_PREP(CMN__PMU_OCCUP1_ID,
+		reg = FIELD_PREP(CMN__PMU_CBUSY_SNTHROTTLE_SEL,
+				 dn->occupid[SEL_CBUSY_SNTHROTTLE_SEL].val) |
+		      FIELD_PREP(CMN__PMU_CLASS_OCCUP_ID,
+				 dn->occupid[SEL_CLASS_OCCUP_ID].val) |
+		      FIELD_PREP(CMN__PMU_OCCUP1_ID,
 				 dn->occupid[SEL_OCCUP1ID].val);
 		writel_relaxed(reg >> 32, dn->pmu_base + CMN_PMU_EVENT_SEL + 4);
 	} else if (dn->occupid[fsel].val != occupid) {
@@ -1157,6 +1332,18 @@ static int arm_cmn_set_event_sel_hi(struct arm_cmn_node *dn,
 	return 0;
 }
 
+static void arm_cmn_set_event_sel_lo(struct arm_cmn_node *dn, int dtm_idx,
+				     int eventid, bool wide_sel)
+{
+	if (wide_sel) {
+		dn->event_w[dtm_idx] = eventid;
+		writeq_relaxed(le64_to_cpu(dn->event_sel_w), dn->pmu_base + CMN_PMU_EVENT_SEL);
+	} else {
+		dn->event[dtm_idx] = eventid;
+		writel_relaxed(le32_to_cpu(dn->event_sel), dn->pmu_base + CMN_PMU_EVENT_SEL);
+	}
+}
+
 static void arm_cmn_event_start(struct perf_event *event, int flags)
 {
 	struct arm_cmn *cmn = to_cmn(event->pmu);
@@ -1183,8 +1370,8 @@ static void arm_cmn_event_start(struct perf_event *event, int flags)
 	} else for_each_hw_dn(hw, dn, i) {
 		int dtm_idx = arm_cmn_get_index(hw->dtm_idx, i);
 
-		dn->event[dtm_idx] = CMN_EVENT_EVENTID(event);
-		writel_relaxed(le32_to_cpu(dn->event_sel), dn->pmu_base + CMN_PMU_EVENT_SEL);
+		arm_cmn_set_event_sel_lo(dn, dtm_idx, CMN_EVENT_EVENTID(event),
+					 hw->wide_sel);
 	}
 }
 
@@ -1211,8 +1398,7 @@ static void arm_cmn_event_stop(struct perf_event *event, int flags)
 	} else for_each_hw_dn(hw, dn, i) {
 		int dtm_idx = arm_cmn_get_index(hw->dtm_idx, i);
 
-		dn->event[dtm_idx] = 0;
-		writel_relaxed(le32_to_cpu(dn->event_sel), dn->pmu_base + CMN_PMU_EVENT_SEL);
+		arm_cmn_set_event_sel_lo(dn, dtm_idx, 0, hw->wide_sel);
 	}
 
 	arm_cmn_event_read(event);
@@ -1371,6 +1557,8 @@ static int arm_cmn_event_init(struct perf_event *event)
 		/* ...but the DTM may depend on which port we're watching */
 		if (cmn->multi_dtm)
 			hw->dtm_offset = CMN_EVENT_WP_DEV_SEL(event) / 2;
+	} else if (type == CMN_TYPE_XP && cmn->model == CMN700) {
+		hw->wide_sel = true;
 	}
 
 	/* This is sufficiently annoying to recalculate, so cache it */
@@ -1748,6 +1936,10 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
 		/* To the PMU, RN-Ds don't add anything over RN-Is, so smoosh them together */
 		if (dn->type == CMN_TYPE_RND)
 			dn->type = CMN_TYPE_RNI;
+
+		/* We split the RN-I off already, so let the CCLA part match CCLA events */
+		if (dn->type == CMN_TYPE_CCLA_RNI)
+			dn->type = CMN_TYPE_CCLA;
 	}
 
 	writel_relaxed(CMN_DT_DTC_CTL_DT_EN, cmn->dtc[0].base + CMN_DT_DTC_CTL);
@@ -1783,6 +1975,8 @@ static enum cmn_node_type arm_cmn_subtype(enum cmn_node_type type)
 	switch (type) {
 	case CMN_TYPE_HNP:
 		return CMN_TYPE_HNI;
+	case CMN_TYPE_CCLA_RNI:
+		return CMN_TYPE_RNI;
 	default:
 		return CMN_TYPE_INVALID;
 	}
@@ -1812,6 +2006,10 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 	cmn->rsp_vc_num = FIELD_GET(CMN_INFO_RSP_VC_NUM, reg);
 	cmn->dat_vc_num = FIELD_GET(CMN_INFO_DAT_VC_NUM, reg);
 
+	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);
+
 	reg = readq_relaxed(cfg_region + CMN_CHILD_INFO);
 	child_count = FIELD_GET(CMN_CI_CHILD_COUNT, reg);
 	child_poff = FIELD_GET(CMN_CI_CHILD_PTR_OFFSET, reg);
@@ -1935,6 +2133,9 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 			case CMN_TYPE_MTSX:
 			case CMN_TYPE_CXRA:
 			case CMN_TYPE_CXHA:
+			case CMN_TYPE_CCRA:
+			case CMN_TYPE_CCHA:
+			case CMN_TYPE_CCLA:
 				dn++;
 				break;
 			/* Nothing to see here */
@@ -1950,6 +2151,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 			 * register via the normal mechanism later.
 			 */
 			case CMN_TYPE_HNP:
+			case CMN_TYPE_CCLA_RNI:
 				dn[1] = dn[0];
 				dn[0].pmu_base += CMN_HNP_PMU_EVENT_SEL;
 				dn[1].type = arm_cmn_subtype(dn->type);
@@ -2125,6 +2327,7 @@ static int arm_cmn_remove(struct platform_device *pdev)
 static const struct of_device_id arm_cmn_of_match[] = {
 	{ .compatible = "arm,cmn-600", .data = (void *)CMN600 },
 	{ .compatible = "arm,cmn-650", .data = (void *)CMN650 },
+	{ .compatible = "arm,cmn-700", .data = (void *)CMN700 },
 	{ .compatible = "arm,ci-700", .data = (void *)CI700 },
 	{}
 };
@@ -2135,6 +2338,7 @@ MODULE_DEVICE_TABLE(of, arm_cmn_of_match);
 static const struct acpi_device_id arm_cmn_acpi_match[] = {
 	{ "ARMHC600", CMN600 },
 	{ "ARMHC650", CMN650 },
+	{ "ARMHC700", CMN700 },
 	{}
 };
 MODULE_DEVICE_TABLE(acpi, arm_cmn_acpi_match);
-- 
2.35.3.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] perf/arm-cmn: Add CMN-650 support
  2022-04-18 22:57 ` [PATCH 2/4] perf/arm-cmn: Add CMN-650 support Robin Murphy
@ 2022-04-19 23:05   ` Ilkka Koskinen
  2022-04-19 23:47     ` Ilkka Koskinen
  2022-04-20 10:12     ` Robin Murphy
  2022-04-21  7:25   ` Ilkka Koskinen
  1 sibling, 2 replies; 23+ messages in thread
From: Ilkka Koskinen @ 2022-04-19 23:05 UTC (permalink / raw)
  To: Robin Murphy; +Cc: will, mark.rutland, linux-arm-kernel


Hi Robin,

I need to go through your patches more carefully, but I do have a couple 
of comments already:

On Mon, 18 Apr 2022, Robin Murphy wrote:
> Add the identifiers and events for CMN-650, which slots into its
> evolutionary position between CMN-600 and the 700-series products.
> Imagine CMN-600 made bigger, and with most of the rough edges smoothed
> off, but that then balanced out by some bonkers PMU functionality for
> the new HN-P enhancement in CMN-650r2.
>
> Most of the CXG events are actually common to newer revisions of CMN-600
> too, so they're arguably a little late; oh well.
>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
> drivers/perf/arm-cmn.c | 222 ++++++++++++++++++++++++++++++++---------
> 1 file changed, 176 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index 9c1d82be7a2f..cce8516d465c 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -39,7 +39,7 @@
> #define CMN_CHILD_NODE_ADDR		GENMASK(27, 0)
> #define CMN_CHILD_NODE_EXTERNAL		BIT(31)
>
> -#define CMN_MAX_DIMENSION		8
> +#define CMN_MAX_DIMENSION		12

I wonder if it made sense to dynamically allocate the arrays later in the 
code instead of allocating them in stack, especially if mesh topologies 
keeps growing fast. That would probably avoid setting max dimension 
altogether if one could use num_xps, num_dns etc. Just for future 
thoughts...


> #define CMN_MAX_XPS			(CMN_MAX_DIMENSION * CMN_MAX_DIMENSION)
> #define CMN_MAX_DTMS			(CMN_MAX_XPS + (CMN_MAX_DIMENSION - 1) * 4)

<snip>

> @@ -1692,8 +1802,13 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
> 		cmn->num_dns += FIELD_GET(CMN_CI_CHILD_COUNT, reg);

How about checking if child count is bigger than the maximum mesh size 
before this for loop? It would help in case someone would work on enabling 
support for new, bigger models and would forget to update 
CMN_MAX_DIMENSION...

> 	}
>
> -	/* Cheeky +1 to help terminate pointer-based iteration later */
> -	dn = devm_kcalloc(cmn->dev, cmn->num_dns + 1, sizeof(*dn), GFP_KERNEL);
> +	/*
> +	 * Some nodes effectively have two separate types, which we'll handle
> +	 * by creating one of each internally. For a (very) safe initial upper
> +	 * bound, account for double the number of non-XP nodes.
> +	 */
> +	dn = devm_kcalloc(cmn->dev, cmn->num_dns * 2 - cmn->num_xps,
> +			  sizeof(*dn), GFP_KERNEL);
> 	if (!dn)
> 		return -ENOMEM;
>

<snip>

> @@ -1970,6 +2098,7 @@ static int arm_cmn_remove(struct platform_device *pdev)
> #ifdef CONFIG_OF
> static const struct of_device_id arm_cmn_of_match[] = {
> 	{ .compatible = "arm,cmn-600", .data = (void *)CMN600 },
> +	{ .compatible = "arm,cmn-650", .data = (void *)CMN650 },
> 	{ .compatible = "arm,ci-700", .data = (void *)CI700 },
> 	{}
> };
> @@ -1979,6 +2108,7 @@ MODULE_DEVICE_TABLE(of, arm_cmn_of_match);
> #ifdef CONFIG_ACPI
> static const struct acpi_device_id arm_cmn_acpi_match[] = {
> 	{ "ARMHC600", CMN600 },
> +	{ "ARMHC650", CMN650 },

Not the great place for this comment but there probably isn't any better.

Based on DEN0093 v1.1, CMN's DSDT entries have been changed since CMN-600. 
ROOTNODEBASE seems to be specific for CMN-600. Moreover, if you compare 
the address maps in TRMs' Discovery chapters, you can see the difference.

I'm thinking, at the minimal the second platform_get_resource() call has 
to be skipped and zero returned in arm_cmn600_acpi_probe(), if the model 
is cmn650 (probably also for cmn-700)

> 	{}
> };
> MODULE_DEVICE_TABLE(acpi, arm_cmn_acpi_match);

Cheers, Ilkka

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] perf/arm-cmn: Add CMN-650 support
  2022-04-19 23:05   ` Ilkka Koskinen
@ 2022-04-19 23:47     ` Ilkka Koskinen
  2022-04-20  9:26       ` Will Deacon
  2022-04-20 10:12     ` Robin Murphy
  1 sibling, 1 reply; 23+ messages in thread
From: Ilkka Koskinen @ 2022-04-19 23:47 UTC (permalink / raw)
  To: Ilkka Koskinen; +Cc: Robin Murphy, will, mark.rutland, linux-arm-kernel



On Tue, 19 Apr 2022, Ilkka Koskinen wrote:
>
> Hi Robin,
>
> I need to go through your patches more carefully, but I do have a couple of 
> comments already:
>
> On Mon, 18 Apr 2022, Robin Murphy wrote:
>> Add the identifiers and events for CMN-650, which slots into its
>> evolutionary position between CMN-600 and the 700-series products.
>> Imagine CMN-600 made bigger, and with most of the rough edges smoothed
>> off, but that then balanced out by some bonkers PMU functionality for
>> the new HN-P enhancement in CMN-650r2.
>> 
>> Most of the CXG events are actually common to newer revisions of CMN-600
>> too, so they're arguably a little late; oh well.
>> 
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>> drivers/perf/arm-cmn.c | 222 ++++++++++++++++++++++++++++++++---------
>> 1 file changed, 176 insertions(+), 46 deletions(-)
>> 
>> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
>> index 9c1d82be7a2f..cce8516d465c 100644
>> --- a/drivers/perf/arm-cmn.c
>> +++ b/drivers/perf/arm-cmn.c


>> @@ -1979,6 +2108,7 @@ MODULE_DEVICE_TABLE(of, arm_cmn_of_match);
>> #ifdef CONFIG_ACPI
>> static const struct acpi_device_id arm_cmn_acpi_match[] = {
>> 	{ "ARMHC600", CMN600 },
>> +	{ "ARMHC650", CMN650 },
>
> Not the great place for this comment but there probably isn't any better.
>
> Based on DEN0093 v1.1, CMN's DSDT entries have been changed since CMN-600. 
> ROOTNODEBASE seems to be specific for CMN-600. Moreover, if you compare the 
> address maps in TRMs' Discovery chapters, you can see the difference.
>
> I'm thinking, at the minimal the second platform_get_resource() call has to 
> be skipped and zero returned in arm_cmn600_acpi_probe(), if the model is 
> cmn650 (probably also for cmn-700)

Uh, if only I had read the code more carefully, I had noticed that's what 
the driver does indeed.


Anyway, so far it everything works fine. I test the driver a little more 
(and review the patches more carefully) and will let know how it goes.

--Ilkka

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] perf/arm-cmn: Add CMN-650 support
  2022-04-19 23:47     ` Ilkka Koskinen
@ 2022-04-20  9:26       ` Will Deacon
  0 siblings, 0 replies; 23+ messages in thread
From: Will Deacon @ 2022-04-20  9:26 UTC (permalink / raw)
  To: Ilkka Koskinen; +Cc: Robin Murphy, mark.rutland, linux-arm-kernel

On Tue, Apr 19, 2022 at 04:47:11PM -0700, Ilkka Koskinen wrote:
> On Tue, 19 Apr 2022, Ilkka Koskinen wrote:
> > On Mon, 18 Apr 2022, Robin Murphy wrote:
> > > Add the identifiers and events for CMN-650, which slots into its
> > > evolutionary position between CMN-600 and the 700-series products.
> > > Imagine CMN-600 made bigger, and with most of the rough edges smoothed
> > > off, but that then balanced out by some bonkers PMU functionality for
> > > the new HN-P enhancement in CMN-650r2.
> > > 
> > > Most of the CXG events are actually common to newer revisions of CMN-600
> > > too, so they're arguably a little late; oh well.
> > > 
> > > Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> > > ---
> > > drivers/perf/arm-cmn.c | 222 ++++++++++++++++++++++++++++++++---------
> > > 1 file changed, 176 insertions(+), 46 deletions(-)
> > > 
> > > diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> > > index 9c1d82be7a2f..cce8516d465c 100644
> > > --- a/drivers/perf/arm-cmn.c
> > > +++ b/drivers/perf/arm-cmn.c
> 
> 
> > > @@ -1979,6 +2108,7 @@ MODULE_DEVICE_TABLE(of, arm_cmn_of_match);
> > > #ifdef CONFIG_ACPI
> > > static const struct acpi_device_id arm_cmn_acpi_match[] = {
> > > 	{ "ARMHC600", CMN600 },
> > > +	{ "ARMHC650", CMN650 },
> > 
> > Not the great place for this comment but there probably isn't any better.
> > 
> > Based on DEN0093 v1.1, CMN's DSDT entries have been changed since
> > CMN-600. ROOTNODEBASE seems to be specific for CMN-600. Moreover, if you
> > compare the address maps in TRMs' Discovery chapters, you can see the
> > difference.
> > 
> > I'm thinking, at the minimal the second platform_get_resource() call has
> > to be skipped and zero returned in arm_cmn600_acpi_probe(), if the model
> > is cmn650 (probably also for cmn-700)
> 
> Uh, if only I had read the code more carefully, I had noticed that's what
> the driver does indeed.
> 
> 
> Anyway, so far it everything works fine. I test the driver a little more
> (and review the patches more carefully) and will let know how it goes.

Thanks for giving it a spin!

Please reply with a Tested-by if/when you're happy with them, then I can
queue them up (you've still got a couple of weeks, so no rush).

Cheers,

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] perf/arm-cmn: Add CMN-650 support
  2022-04-19 23:05   ` Ilkka Koskinen
  2022-04-19 23:47     ` Ilkka Koskinen
@ 2022-04-20 10:12     ` Robin Murphy
  2022-04-21  7:09       ` Ilkka Koskinen
  1 sibling, 1 reply; 23+ messages in thread
From: Robin Murphy @ 2022-04-20 10:12 UTC (permalink / raw)
  To: Ilkka Koskinen; +Cc: will, mark.rutland, linux-arm-kernel

On 2022-04-20 00:05, Ilkka Koskinen wrote:
> 
> Hi Robin,
> 
> I need to go through your patches more carefully, but I do have a couple 
> of comments already:

Thanks for having a look!

> On Mon, 18 Apr 2022, Robin Murphy wrote:
>> Add the identifiers and events for CMN-650, which slots into its
>> evolutionary position between CMN-600 and the 700-series products.
>> Imagine CMN-600 made bigger, and with most of the rough edges smoothed
>> off, but that then balanced out by some bonkers PMU functionality for
>> the new HN-P enhancement in CMN-650r2.
>>
>> Most of the CXG events are actually common to newer revisions of CMN-600
>> too, so they're arguably a little late; oh well.
>>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>> drivers/perf/arm-cmn.c | 222 ++++++++++++++++++++++++++++++++---------
>> 1 file changed, 176 insertions(+), 46 deletions(-)
>>
>> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
>> index 9c1d82be7a2f..cce8516d465c 100644
>> --- a/drivers/perf/arm-cmn.c
>> +++ b/drivers/perf/arm-cmn.c
>> @@ -39,7 +39,7 @@
>> #define CMN_CHILD_NODE_ADDR        GENMASK(27, 0)
>> #define CMN_CHILD_NODE_EXTERNAL        BIT(31)
>>
>> -#define CMN_MAX_DIMENSION        8
>> +#define CMN_MAX_DIMENSION        12
> 
> I wonder if it made sense to dynamically allocate the arrays later in 
> the code instead of allocating them in stack, especially if mesh 
> topologies keeps growing fast. That would probably avoid setting max 
> dimension altogether if one could use num_xps, num_dns etc. Just for 
> future thoughts...

Note that the group validation structure *is* dynamically allocated 
since the last update, since it was already getting a bit big for the 
stack; it's just not dynamically *sized*. That's a compromise to keep 
the validation code as simple and efficient as it reasonably can be. I'm 
not entirely convinced that extra complexity and runtime overhead for 
everyone is worth it for the sake of making it slightly easier to catch 
an obvious bug if someone makes out-of-tree hacks to the driver. This is 
not the only place which needs updating (or at least checking) if the 
maximum number of possible DTMs really does increase again.

>> #define CMN_MAX_XPS            (CMN_MAX_DIMENSION * CMN_MAX_DIMENSION)
>> #define CMN_MAX_DTMS            (CMN_MAX_XPS + (CMN_MAX_DIMENSION - 1) 
>> * 4)
> 
> <snip>
> 
>> @@ -1692,8 +1802,13 @@ static int arm_cmn_discover(struct arm_cmn 
>> *cmn, unsigned int rgn_offset)
>>         cmn->num_dns += FIELD_GET(CMN_CI_CHILD_COUNT, reg);
> 
> How about checking if child count is bigger than the maximum mesh size 
> before this for loop? It would help in case someone would work on 
> enabling support for new, bigger models and would forget to update 
> CMN_MAX_DIMENSION...

Hmm, I guess we do already warn and bail out if we find a mystery node 
type that implies we're being lied to, but TBH that was always more to 
avoid compilers moaning about the switch statement lacking a default 
case than because I thought it's a necessary check in itself. Ultimately 
if someone lies to the driver and claims that a CMN product is a 
different CMN product, it's already not going to work properly due to 
the subtle differences in the hardware, so I'd argue that potential 
memory corruption due to overrunning array bounds in various places is 
really just part and parcel of "not working properly".

CMN-700 r0 and r2 seemed clear that 12x12 is the largest supported 
dimension; r1 seemed a bit ambiguous between what the TRM said and what 
I could find in the actual product deliverables, so I can double-check 
with the hardware team if you like - or if you already know better, 
please do feel free to correct my assumption :)

>>     }
>>
>> -    /* Cheeky +1 to help terminate pointer-based iteration later */
>> -    dn = devm_kcalloc(cmn->dev, cmn->num_dns + 1, sizeof(*dn), 
>> GFP_KERNEL);
>> +    /*
>> +     * Some nodes effectively have two separate types, which we'll 
>> handle
>> +     * by creating one of each internally. For a (very) safe initial 
>> upper
>> +     * bound, account for double the number of non-XP nodes.
>> +     */
>> +    dn = devm_kcalloc(cmn->dev, cmn->num_dns * 2 - cmn->num_xps,
>> +              sizeof(*dn), GFP_KERNEL);
>>     if (!dn)
>>         return -ENOMEM;
>>
> 
> <snip>
> 
>> @@ -1970,6 +2098,7 @@ static int arm_cmn_remove(struct platform_device 
>> *pdev)
>> #ifdef CONFIG_OF
>> static const struct of_device_id arm_cmn_of_match[] = {
>>     { .compatible = "arm,cmn-600", .data = (void *)CMN600 },
>> +    { .compatible = "arm,cmn-650", .data = (void *)CMN650 },
>>     { .compatible = "arm,ci-700", .data = (void *)CI700 },
>>     {}
>> };
>> @@ -1979,6 +2108,7 @@ MODULE_DEVICE_TABLE(of, arm_cmn_of_match);
>> #ifdef CONFIG_ACPI
>> static const struct acpi_device_id arm_cmn_acpi_match[] = {
>>     { "ARMHC600", CMN600 },
>> +    { "ARMHC650", CMN650 },
> 
> Not the great place for this comment but there probably isn't any better.
> 
> Based on DEN0093 v1.1, CMN's DSDT entries have been changed since 
> CMN-600. ROOTNODEBASE seems to be specific for CMN-600. Moreover, if you 
> compare the address maps in TRMs' Discovery chapters, you can see the 
> difference.
> 
> I'm thinking, at the minimal the second platform_get_resource() call has 
> to be skipped and zero returned in arm_cmn600_acpi_probe(), if the model 
> is cmn650 (probably also for cmn-700)

As you've already found, things prefixed with "arm_cmn600_" vs. 
"arm_cmn_" *are* specific to CMN-600, and the CI-700 update reworked 
this area such that everything else simply probes in a firmware-agnostic 
manner. It may have been a bit subtle since CI-700 doesn't have an ACPI 
binding, but it was very much intended to cover these future ACPI 
additions as well.

Thanks,
Robin.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] perf/arm-cmn: Add CMN-650 support
  2022-04-20 10:12     ` Robin Murphy
@ 2022-04-21  7:09       ` Ilkka Koskinen
  0 siblings, 0 replies; 23+ messages in thread
From: Ilkka Koskinen @ 2022-04-21  7:09 UTC (permalink / raw)
  To: Robin Murphy; +Cc: Ilkka Koskinen, will, mark.rutland, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 6329 bytes --]



On Wed, 20 Apr 2022, Robin Murphy wrote:
> On 2022-04-20 00:05, Ilkka Koskinen wrote:
>> 
>> Hi Robin,
>> 
>> I need to go through your patches more carefully, but I do have a couple of 
>> comments already:
>
> Thanks for having a look!
>
>> On Mon, 18 Apr 2022, Robin Murphy wrote:
>>> Add the identifiers and events for CMN-650, which slots into its
>>> evolutionary position between CMN-600 and the 700-series products.
>>> Imagine CMN-600 made bigger, and with most of the rough edges smoothed
>>> off, but that then balanced out by some bonkers PMU functionality for
>>> the new HN-P enhancement in CMN-650r2.
>>> 
>>> Most of the CXG events are actually common to newer revisions of CMN-600
>>> too, so they're arguably a little late; oh well.
>>> 
>>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>>> ---
>>> drivers/perf/arm-cmn.c | 222 ++++++++++++++++++++++++++++++++---------
>>> 1 file changed, 176 insertions(+), 46 deletions(-)
>>> 
>>> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
>>> index 9c1d82be7a2f..cce8516d465c 100644
>>> --- a/drivers/perf/arm-cmn.c
>>> +++ b/drivers/perf/arm-cmn.c
>>> @@ -39,7 +39,7 @@
>>> #define CMN_CHILD_NODE_ADDR        GENMASK(27, 0)
>>> #define CMN_CHILD_NODE_EXTERNAL        BIT(31)
>>> 
>>> -#define CMN_MAX_DIMENSION        8
>>> +#define CMN_MAX_DIMENSION        12
>> 
>> I wonder if it made sense to dynamically allocate the arrays later in the 
>> code instead of allocating them in stack, especially if mesh topologies 
>> keeps growing fast. That would probably avoid setting max dimension 
>> altogether if one could use num_xps, num_dns etc. Just for future 
>> thoughts...
>
> Note that the group validation structure *is* dynamically allocated since the 
> last update, since it was already getting a bit big for the stack; it's just 
> not dynamically *sized*. That's a compromise to keep the validation code as 
> simple and efficient as it reasonably can be. I'm not entirely convinced that 
> extra complexity and runtime overhead for everyone is worth it for the sake 
> of making it slightly easier to catch an obvious bug if someone makes 
> out-of-tree hacks to the driver. This is not the only place which needs 
> updating (or at least checking) if the maximum number of possible DTMs really 
> does increase again.

Probably not. If the mesh size grows remarkably, then it might make sense 
to revisit but it should be ok now.

>
>>> #define CMN_MAX_XPS            (CMN_MAX_DIMENSION * CMN_MAX_DIMENSION)
>>> #define CMN_MAX_DTMS            (CMN_MAX_XPS + (CMN_MAX_DIMENSION - 1) * 
>>> 4)
>> 
>> <snip>
>> 
>>> @@ -1692,8 +1802,13 @@ static int arm_cmn_discover(struct arm_cmn *cmn, 
>>> unsigned int rgn_offset)
>>>         cmn->num_dns += FIELD_GET(CMN_CI_CHILD_COUNT, reg);
>> 
>> How about checking if child count is bigger than the maximum mesh size 
>> before this for loop? It would help in case someone would work on enabling 
>> support for new, bigger models and would forget to update 
>> CMN_MAX_DIMENSION...
>
> Hmm, I guess we do already warn and bail out if we find a mystery node type 
> that implies we're being lied to, but TBH that was always more to avoid 
> compilers moaning about the switch statement lacking a default case than 
> because I thought it's a necessary check in itself. Ultimately if someone 
> lies to the driver and claims that a CMN product is a different CMN product, 
> it's already not going to work properly due to the subtle differences in the 
> hardware, so I'd argue that potential memory corruption due to overrunning 
> array bounds in various places is really just part and parcel of "not working 
> properly".
>
> CMN-700 r0 and r2 seemed clear that 12x12 is the largest supported dimension; 
> r1 seemed a bit ambiguous between what the TRM said and what I could find in 
> the actual product deliverables, so I can double-check with the hardware team 
> if you like - or if you already know better, please do feel free to correct 
> my assumption :)

That's fair point. I'm fine as it is now.

Cheers, Ilkka



>>>     }
>>> 
>>> -    /* Cheeky +1 to help terminate pointer-based iteration later */
>>> -    dn = devm_kcalloc(cmn->dev, cmn->num_dns + 1, sizeof(*dn), 
>>> GFP_KERNEL);
>>> +    /*
>>> +     * Some nodes effectively have two separate types, which we'll handle
>>> +     * by creating one of each internally. For a (very) safe initial 
>>> upper
>>> +     * bound, account for double the number of non-XP nodes.
>>> +     */
>>> +    dn = devm_kcalloc(cmn->dev, cmn->num_dns * 2 - cmn->num_xps,
>>> +              sizeof(*dn), GFP_KERNEL);
>>>     if (!dn)
>>>         return -ENOMEM;
>>> 
>> 
>> <snip>
>> 
>>> @@ -1970,6 +2098,7 @@ static int arm_cmn_remove(struct platform_device 
>>> *pdev)
>>> #ifdef CONFIG_OF
>>> static const struct of_device_id arm_cmn_of_match[] = {
>>>     { .compatible = "arm,cmn-600", .data = (void *)CMN600 },
>>> +    { .compatible = "arm,cmn-650", .data = (void *)CMN650 },
>>>     { .compatible = "arm,ci-700", .data = (void *)CI700 },
>>>     {}
>>> };
>>> @@ -1979,6 +2108,7 @@ MODULE_DEVICE_TABLE(of, arm_cmn_of_match);
>>> #ifdef CONFIG_ACPI
>>> static const struct acpi_device_id arm_cmn_acpi_match[] = {
>>>     { "ARMHC600", CMN600 },
>>> +    { "ARMHC650", CMN650 },
>> 
>> Not the great place for this comment but there probably isn't any better.
>> 
>> Based on DEN0093 v1.1, CMN's DSDT entries have been changed since CMN-600. 
>> ROOTNODEBASE seems to be specific for CMN-600. Moreover, if you compare the 
>> address maps in TRMs' Discovery chapters, you can see the difference.
>> 
>> I'm thinking, at the minimal the second platform_get_resource() call has to 
>> be skipped and zero returned in arm_cmn600_acpi_probe(), if the model is 
>> cmn650 (probably also for cmn-700)
>
> As you've already found, things prefixed with "arm_cmn600_" vs. "arm_cmn_" 
> *are* specific to CMN-600, and the CI-700 update reworked this area such that 
> everything else simply probes in a firmware-agnostic manner. It may have been 
> a bit subtle since CI-700 doesn't have an ACPI binding, but it was very much 
> intended to cover these future ACPI additions as well.
>
> Thanks,
> Robin.
>

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] perf/arm-cmn: Add CMN-650 support
  2022-04-18 22:57 ` [PATCH 2/4] perf/arm-cmn: Add CMN-650 support Robin Murphy
  2022-04-19 23:05   ` Ilkka Koskinen
@ 2022-04-21  7:25   ` Ilkka Koskinen
  2022-04-21  9:46     ` Robin Murphy
  1 sibling, 1 reply; 23+ messages in thread
From: Ilkka Koskinen @ 2022-04-21  7:25 UTC (permalink / raw)
  To: Robin Murphy; +Cc: will, mark.rutland, linux-arm-kernel


I still have a couple tiny comments. Otherwise the patch set looks good to 
me.

On Mon, 18 Apr 2022, Robin Murphy wrote:
> Add the identifiers and events for CMN-650, which slots into its
> evolutionary position between CMN-600 and the 700-series products.
> Imagine CMN-600 made bigger, and with most of the rough edges smoothed
> off, but that then balanced out by some bonkers PMU functionality for
> the new HN-P enhancement in CMN-650r2.
>
> Most of the CXG events are actually common to newer revisions of CMN-600
> too, so they're arguably a little late; oh well.
>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
> drivers/perf/arm-cmn.c | 222 ++++++++++++++++++++++++++++++++---------
> 1 file changed, 176 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index 9c1d82be7a2f..cce8516d465c 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -39,7 +39,7 @@
> #define CMN_CHILD_NODE_ADDR		GENMASK(27, 0)
> #define CMN_CHILD_NODE_EXTERNAL		BIT(31)
>
> -#define CMN_MAX_DIMENSION		8
> +#define CMN_MAX_DIMENSION		12
> #define CMN_MAX_XPS			(CMN_MAX_DIMENSION * CMN_MAX_DIMENSION)
> #define CMN_MAX_DTMS			(CMN_MAX_XPS + (CMN_MAX_DIMENSION - 1) * 4)
>
> @@ -65,7 +65,9 @@
>
> /* For most nodes, this is all there is */
> #define CMN_PMU_EVENT_SEL		0x000
> -#define CMN_PMU_EVENTn_ID_SHIFT(n)	((n) * 8)
> +
> +/* HN-Ps are weird... */
> +#define CMN_HNP_PMU_EVENT_SEL		0x008
>
> /* DTMs live in the PMU space of XP registers */
> #define CMN_DTM_WPn(n)			(0x1A0 + (n) * 0x18)
> @@ -177,9 +179,12 @@
>
>
> enum cmn_model {
> -	CMN_ANY = -1,
> 	CMN600 = 1,
> -	CI700 = 2,
> +	CMN650 = 2,
> +	CI700 = 8,
> +	/* ...and then we can use bitmap tricks for commonality */
> +	CMN_ANY = -1,
> +	NOT_CMN600 = -2,

Matter of taste, but I'd probably prefer NOT_CMN600 = ~CMN600

> };
>
> /* CMN-600 r0px shouldn't exist in silicon, thankfully */
> @@ -191,6 +196,11 @@ enum cmn_revision {
> 	CMN600_R2P0,
> 	CMN600_R3P0,
> 	CMN600_R3P1,
> +	CMN650_R0P0 = 0,
> +	CMN650_R1P0,
> +	CMN650_R1P1,
> +	CMN650_R2P0,
> +	CMN650_R1P2,
> 	CI700_R0P0 = 0,
> 	CI700_R1P0,
> 	CI700_R2P0,
> @@ -211,6 +221,7 @@ enum cmn_node_type {
> 	CMN_TYPE_RND = 0xd,
> 	CMN_TYPE_RNSAM = 0xf,
> 	CMN_TYPE_MTSX,
> +	CMN_TYPE_HNP,
> 	CMN_TYPE_CXRA = 0x100,
> 	CMN_TYPE_CXHA = 0x101,
> 	CMN_TYPE_CXLA = 0x102,
> @@ -307,9 +318,7 @@ struct arm_cmn_nodeid {

<snip>

> @@ -580,20 +592,25 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
> 	struct device *dev = kobj_to_dev(kobj);
> 	struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev));
> 	struct arm_cmn_event_attr *eattr;
> +	enum cmn_node_type type;
> +	u16 eventid;
>
> 	eattr = container_of(attr, typeof(*eattr), attr.attr);
>
> 	if (!(eattr->model & cmn->model))
> 		return 0;
>
> +	type = eattr->type;
> +	eventid = eattr->eventid;
> +
> 	/* Watchpoints aren't nodes, so avoid confusion */
> -	if (eattr->type == CMN_TYPE_WP)
> +	if (type == CMN_TYPE_WP)
> 		return attr->mode;
>
> 	/* Hide XP events for unused interfaces/channels */
> -	if (eattr->type == CMN_TYPE_XP) {
> -		unsigned int intf = (eattr->eventid >> 2) & 7;
> -		unsigned int chan = eattr->eventid >> 5;
> +	if (type == CMN_TYPE_XP) {
> +		unsigned int intf = (eventid >> 2) & 7;
> +		unsigned int chan = eventid >> 5;
>
> 		if ((intf & 4) && !(cmn->ports_used & BIT(intf & 3)))
> 			return 0;
> @@ -607,12 +624,29 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
> 	}
>
> 	/* Revision-specific differences */
> -	if (cmn->model == CMN600 && cmn->rev < CMN600_R1P2) {
> -		if (eattr->type == CMN_TYPE_HNF && eattr->eventid == 0x1b)
> -			return 0;
> +	if (cmn->model == CMN600) {
> +		if (cmn->rev < CMN600_R1P3) {
> +			if (type == CMN_TYPE_CXRA && eventid > 0x10)
> +				return 0;
> +		}
> +		if (cmn->rev < CMN600_R1P2) {
> +			if (type == CMN_TYPE_HNF && eventid == 0x1b)
> +				return 0;
> +			if (type == CMN_TYPE_CXRA || type == CMN_TYPE_CXHA)
> +				return 0;
> +		}
> +	} else if (cmn->model == CMN650) {
> +		if (cmn->rev < CMN650_R2P0 || cmn->rev == CMN650_R1P2) {
> +			if (type == CMN_TYPE_HNF && eventid > 0x22)
> +				return 0;
> +			if (type == CMN_TYPE_SBSX && eventid == 0x17)
> +				return 0;
> +			if (type == CMN_TYPE_RNI && eventid > 0x10)
> +				return 0;
> +		}

What's the plan with cmn-650 r2p0 event settings? There seem to be a few 
extra ones made visible now. I'm fine with updating this patch or taking 
care of them in a separate one, which ever makes more sense.

Cheers, Ilkka


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700
  2022-04-18 22:57 [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Robin Murphy
                   ` (3 preceding siblings ...)
  2022-04-18 22:57 ` [PATCH 4/4] perf/arm-cmn: Add CMN-700 support Robin Murphy
@ 2022-04-21  7:54 ` Ilkka Koskinen
  2022-05-06 14:43 ` Will Deacon
  2022-05-10 17:15 ` Qian Cai
  6 siblings, 0 replies; 23+ messages in thread
From: Ilkka Koskinen @ 2022-04-21  7:54 UTC (permalink / raw)
  To: Robin Murphy; +Cc: will, mark.rutland, linux-arm-kernel



On Mon, 18 Apr 2022, Robin Murphy wrote:

> Hi Will,
>
> As promised last time, here are the patches adding yet more inscrutable
> support for the other new members of the CMN family. I'm not sure if any
> of the folks who want this are the kind to give upstream feedback, but
> we can always live in hope... A colleague has kindly managed to briefly
> sanity-check the CMN-700 support under RTL emulation, but otherwise I've
> only been able to test the refactorings in terms of not breaking my
> little CMN-600 platform. Still, I'm pretty confident that that's caught
> all the stupids, and the rest is mostly just yet more events, so I
> don't think anything's particularly high-risk here.
>
> Cheers,
> Robin.

I tested the patch set on CMN-650 (and CMN-600). Apart from extra events 
on r2p0, everything seemed to work fine.

Tested-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>

>
>
> Robin Murphy (4):
>  dt-bindings: perf: arm-cmn: Add CMN-650 and CMN-700
>  perf/arm-cmn: Add CMN-650 support
>  perf/arm-cmn: Refactor occupancy filter selector
>  perf/arm-cmn: Add CMN-700 support
>
> .../devicetree/bindings/perf/arm,cmn.yaml     |   2 +
> drivers/perf/arm-cmn.c                        | 606 ++++++++++++++----
> 2 files changed, 485 insertions(+), 123 deletions(-)
>
> -- 
> 2.35.3.dirty
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] perf/arm-cmn: Add CMN-650 support
  2022-04-21  7:25   ` Ilkka Koskinen
@ 2022-04-21  9:46     ` Robin Murphy
  2022-04-21 21:26       ` Ilkka Koskinen
  0 siblings, 1 reply; 23+ messages in thread
From: Robin Murphy @ 2022-04-21  9:46 UTC (permalink / raw)
  To: Ilkka Koskinen; +Cc: will, mark.rutland, linux-arm-kernel

On 2022-04-21 08:25, Ilkka Koskinen wrote:
> 
> I still have a couple tiny comments. Otherwise the patch set looks good 
> to me.
> 
> On Mon, 18 Apr 2022, Robin Murphy wrote:
>> Add the identifiers and events for CMN-650, which slots into its
>> evolutionary position between CMN-600 and the 700-series products.
>> Imagine CMN-600 made bigger, and with most of the rough edges smoothed
>> off, but that then balanced out by some bonkers PMU functionality for
>> the new HN-P enhancement in CMN-650r2.
>>
>> Most of the CXG events are actually common to newer revisions of CMN-600
>> too, so they're arguably a little late; oh well.
>>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>> drivers/perf/arm-cmn.c | 222 ++++++++++++++++++++++++++++++++---------
>> 1 file changed, 176 insertions(+), 46 deletions(-)
>>
>> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
>> index 9c1d82be7a2f..cce8516d465c 100644
>> --- a/drivers/perf/arm-cmn.c
>> +++ b/drivers/perf/arm-cmn.c
>> @@ -39,7 +39,7 @@
>> #define CMN_CHILD_NODE_ADDR        GENMASK(27, 0)
>> #define CMN_CHILD_NODE_EXTERNAL        BIT(31)
>>
>> -#define CMN_MAX_DIMENSION        8
>> +#define CMN_MAX_DIMENSION        12
>> #define CMN_MAX_XPS            (CMN_MAX_DIMENSION * CMN_MAX_DIMENSION)
>> #define CMN_MAX_DTMS            (CMN_MAX_XPS + (CMN_MAX_DIMENSION - 1) 
>> * 4)
>>
>> @@ -65,7 +65,9 @@
>>
>> /* For most nodes, this is all there is */
>> #define CMN_PMU_EVENT_SEL        0x000
>> -#define CMN_PMU_EVENTn_ID_SHIFT(n)    ((n) * 8)
>> +
>> +/* HN-Ps are weird... */
>> +#define CMN_HNP_PMU_EVENT_SEL        0x008
>>
>> /* DTMs live in the PMU space of XP registers */
>> #define CMN_DTM_WPn(n)            (0x1A0 + (n) * 0x18)
>> @@ -177,9 +179,12 @@
>>
>>
>> enum cmn_model {
>> -    CMN_ANY = -1,
>>     CMN600 = 1,
>> -    CI700 = 2,
>> +    CMN650 = 2,
>> +    CI700 = 8,
>> +    /* ...and then we can use bitmap tricks for commonality */
>> +    CMN_ANY = -1,
>> +    NOT_CMN600 = -2,
> 
> Matter of taste, but I'd probably prefer NOT_CMN600 = ~CMN600

Sure, I had it written that way at one point during development when it 
was a separate macro, so even I'm not entirely certain why it ended up 
like this - I must have been feeling particularly whimsical that day.

>> };
>>
>> /* CMN-600 r0px shouldn't exist in silicon, thankfully */
>> @@ -191,6 +196,11 @@ enum cmn_revision {
>>     CMN600_R2P0,
>>     CMN600_R3P0,
>>     CMN600_R3P1,
>> +    CMN650_R0P0 = 0,
>> +    CMN650_R1P0,
>> +    CMN650_R1P1,
>> +    CMN650_R2P0,
>> +    CMN650_R1P2,
>>     CI700_R0P0 = 0,
>>     CI700_R1P0,
>>     CI700_R2P0,
>> @@ -211,6 +221,7 @@ enum cmn_node_type {
>>     CMN_TYPE_RND = 0xd,
>>     CMN_TYPE_RNSAM = 0xf,
>>     CMN_TYPE_MTSX,
>> +    CMN_TYPE_HNP,
>>     CMN_TYPE_CXRA = 0x100,
>>     CMN_TYPE_CXHA = 0x101,
>>     CMN_TYPE_CXLA = 0x102,
>> @@ -307,9 +318,7 @@ struct arm_cmn_nodeid {
> 
> <snip>
> 
>> @@ -580,20 +592,25 @@ static umode_t 
>> arm_cmn_event_attr_is_visible(struct kobject *kobj,
>>     struct device *dev = kobj_to_dev(kobj);
>>     struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev));
>>     struct arm_cmn_event_attr *eattr;
>> +    enum cmn_node_type type;
>> +    u16 eventid;
>>
>>     eattr = container_of(attr, typeof(*eattr), attr.attr);
>>
>>     if (!(eattr->model & cmn->model))
>>         return 0;
>>
>> +    type = eattr->type;
>> +    eventid = eattr->eventid;
>> +
>>     /* Watchpoints aren't nodes, so avoid confusion */
>> -    if (eattr->type == CMN_TYPE_WP)
>> +    if (type == CMN_TYPE_WP)
>>         return attr->mode;
>>
>>     /* Hide XP events for unused interfaces/channels */
>> -    if (eattr->type == CMN_TYPE_XP) {
>> -        unsigned int intf = (eattr->eventid >> 2) & 7;
>> -        unsigned int chan = eattr->eventid >> 5;
>> +    if (type == CMN_TYPE_XP) {
>> +        unsigned int intf = (eventid >> 2) & 7;
>> +        unsigned int chan = eventid >> 5;
>>
>>         if ((intf & 4) && !(cmn->ports_used & BIT(intf & 3)))
>>             return 0;
>> @@ -607,12 +624,29 @@ static umode_t 
>> arm_cmn_event_attr_is_visible(struct kobject *kobj,
>>     }
>>
>>     /* Revision-specific differences */
>> -    if (cmn->model == CMN600 && cmn->rev < CMN600_R1P2) {
>> -        if (eattr->type == CMN_TYPE_HNF && eattr->eventid == 0x1b)
>> -            return 0;
>> +    if (cmn->model == CMN600) {
>> +        if (cmn->rev < CMN600_R1P3) {
>> +            if (type == CMN_TYPE_CXRA && eventid > 0x10)
>> +                return 0;
>> +        }
>> +        if (cmn->rev < CMN600_R1P2) {
>> +            if (type == CMN_TYPE_HNF && eventid == 0x1b)
>> +                return 0;
>> +            if (type == CMN_TYPE_CXRA || type == CMN_TYPE_CXHA)
>> +                return 0;
>> +        }
>> +    } else if (cmn->model == CMN650) {
>> +        if (cmn->rev < CMN650_R2P0 || cmn->rev == CMN650_R1P2) {
>> +            if (type == CMN_TYPE_HNF && eventid > 0x22)
>> +                return 0;
>> +            if (type == CMN_TYPE_SBSX && eventid == 0x17)
>> +                return 0;
>> +            if (type == CMN_TYPE_RNI && eventid > 0x10)
>> +                return 0;
>> +        }
> 
> What's the plan with cmn-650 r2p0 event settings? There seem to be a few 
> extra ones made visible now. I'm fine with updating this patch or taking 
> care of them in a separate one, which ever makes more sense.

arm_cmn_event_attrs *should* contain all the events supported by r2p0, 
with the ones not present on earlier revisions then being filtered out 
here. Have I missed anything? Note that HN-Ps don't need per-event 
filtering since that node type simply doesn't exist prior to CMN-650 r2, 
so is already filtered by arm_cmn_node().

Thanks,
Robin.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] perf/arm-cmn: Add CMN-650 support
  2022-04-21  9:46     ` Robin Murphy
@ 2022-04-21 21:26       ` Ilkka Koskinen
  0 siblings, 0 replies; 23+ messages in thread
From: Ilkka Koskinen @ 2022-04-21 21:26 UTC (permalink / raw)
  To: Robin Murphy; +Cc: Ilkka Koskinen, will, mark.rutland, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 3330 bytes --]



On Thu, 21 Apr 2022, Robin Murphy wrote:

> On 2022-04-21 08:25, Ilkka Koskinen wrote:
>> 
>> I still have a couple tiny comments. Otherwise the patch set looks good to 
>> me.
>> 
>> On Mon, 18 Apr 2022, Robin Murphy wrote:
>>> Add the identifiers and events for CMN-650, which slots into its
>>> evolutionary position between CMN-600 and the 700-series products.
>>> Imagine CMN-600 made bigger, and with most of the rough edges smoothed
>>> off, but that then balanced out by some bonkers PMU functionality for
>>> the new HN-P enhancement in CMN-650r2.
>>> 
>>> Most of the CXG events are actually common to newer revisions of CMN-600
>>> too, so they're arguably a little late; oh well.
>>> 
>>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>>> ---
>>> drivers/perf/arm-cmn.c | 222 ++++++++++++++++++++++++++++++++---------
>>> 1 file changed, 176 insertions(+), 46 deletions(-)
>>> 
>>> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
>>> index 9c1d82be7a2f..cce8516d465c 100644
>>> --- a/drivers/perf/arm-cmn.c
>>> +++ b/drivers/perf/arm-cmn.c


>>> @@ -607,12 +624,29 @@ static umode_t arm_cmn_event_attr_is_visible(struct 
>>> kobject *kobj,
>>>     }
>>> 
>>>     /* Revision-specific differences */
>>> -    if (cmn->model == CMN600 && cmn->rev < CMN600_R1P2) {
>>> -        if (eattr->type == CMN_TYPE_HNF && eattr->eventid == 0x1b)
>>> -            return 0;
>>> +    if (cmn->model == CMN600) {
>>> +        if (cmn->rev < CMN600_R1P3) {
>>> +            if (type == CMN_TYPE_CXRA && eventid > 0x10)
>>> +                return 0;
>>> +        }
>>> +        if (cmn->rev < CMN600_R1P2) {
>>> +            if (type == CMN_TYPE_HNF && eventid == 0x1b)
>>> +                return 0;
>>> +            if (type == CMN_TYPE_CXRA || type == CMN_TYPE_CXHA)
>>> +                return 0;
>>> +        }
>>> +    } else if (cmn->model == CMN650) {
>>> +        if (cmn->rev < CMN650_R2P0 || cmn->rev == CMN650_R1P2) {
>>> +            if (type == CMN_TYPE_HNF && eventid > 0x22)
>>> +                return 0;
>>> +            if (type == CMN_TYPE_SBSX && eventid == 0x17)
>>> +                return 0;
>>> +            if (type == CMN_TYPE_RNI && eventid > 0x10)
>>> +                return 0;
>>> +        }
>> 
>> What's the plan with cmn-650 r2p0 event settings? There seem to be a few 
>> extra ones made visible now. I'm fine with updating this patch or taking 
>> care of them in a separate one, which ever makes more sense.
>
> arm_cmn_event_attrs *should* contain all the events supported by r2p0, with 
> the ones not present on earlier revisions then being filtered out here. Have 
> I missed anything? Note that HN-Ps don't need per-event filtering since that 
> node type simply doesn't exist prior to CMN-650 r2, so is already filtered by 
> arm_cmn_node().

Ah, I was comparing the code and perf output to HN-F and RN-I event 
summary tables in TRM. The tables are missing some of the events where as 
the event_sel register descriptions have all of them listed. So, that was 
my mistake and everything looks good.

Cheers, Ilkka

>
> Thanks,
> Robin.
>

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] dt-bindings: perf: arm-cmn: Add CMN-650 and CMN-700
  2022-04-18 22:57   ` Robin Murphy
@ 2022-04-26 20:12     ` Rob Herring
  -1 siblings, 0 replies; 23+ messages in thread
From: Rob Herring @ 2022-04-26 20:12 UTC (permalink / raw)
  To: Robin Murphy; +Cc: will, linux-arm-kernel, mark.rutland, devicetree

On Mon, 18 Apr 2022 23:57:38 +0100, Robin Murphy wrote:
> If you were to guess from the product names that CMN-650 and CMN-700 are
> the next two evolutionary steps of Arm's enterprise-level interconnect
> following on from CMN-600, you'd be pleasantly correct. Add them to the
> DT binding.
> 
> CC: devicetree@vger.kernel.org
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>  Documentation/devicetree/bindings/perf/arm,cmn.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] dt-bindings: perf: arm-cmn: Add CMN-650 and CMN-700
@ 2022-04-26 20:12     ` Rob Herring
  0 siblings, 0 replies; 23+ messages in thread
From: Rob Herring @ 2022-04-26 20:12 UTC (permalink / raw)
  To: Robin Murphy; +Cc: will, linux-arm-kernel, mark.rutland, devicetree

On Mon, 18 Apr 2022 23:57:38 +0100, Robin Murphy wrote:
> If you were to guess from the product names that CMN-650 and CMN-700 are
> the next two evolutionary steps of Arm's enterprise-level interconnect
> following on from CMN-600, you'd be pleasantly correct. Add them to the
> DT binding.
> 
> CC: devicetree@vger.kernel.org
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>  Documentation/devicetree/bindings/perf/arm,cmn.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700
  2022-04-18 22:57 [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Robin Murphy
                   ` (4 preceding siblings ...)
  2022-04-21  7:54 ` [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Ilkka Koskinen
@ 2022-05-06 14:43 ` Will Deacon
  2022-05-10 17:15 ` Qian Cai
  6 siblings, 0 replies; 23+ messages in thread
From: Will Deacon @ 2022-05-06 14:43 UTC (permalink / raw)
  To: Robin Murphy
  Cc: catalin.marinas, kernel-team, Will Deacon, mark.rutland,
	linux-arm-kernel

On Mon, 18 Apr 2022 23:57:37 +0100, Robin Murphy wrote:
> As promised last time, here are the patches adding yet more inscrutable
> support for the other new members of the CMN family. I'm not sure if any
> of the folks who want this are the kind to give upstream feedback, but
> we can always live in hope... A colleague has kindly managed to briefly
> sanity-check the CMN-700 support under RTL emulation, but otherwise I've
> only been able to test the refactorings in terms of not breaking my
> little CMN-600 platform. Still, I'm pretty confident that that's caught
> all the stupids, and the rest is mostly just yet more events, so I
> don't think anything's particularly high-risk here.
> 
> [...]

Applied to will (for-next/perf), thanks!

[1/4] dt-bindings: perf: arm-cmn: Add CMN-650 and CMN-700
      https://git.kernel.org/will/c/2b60a22b70fa
[2/4] perf/arm-cmn: Add CMN-650 support
      https://git.kernel.org/will/c/8e504d93acb6
[3/4] perf/arm-cmn: Refactor occupancy filter selector
      https://git.kernel.org/will/c/65adf71398f5
[4/4] perf/arm-cmn: Add CMN-700 support
      https://git.kernel.org/will/c/23760a014417

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700
  2022-04-18 22:57 [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Robin Murphy
                   ` (5 preceding siblings ...)
  2022-05-06 14:43 ` Will Deacon
@ 2022-05-10 17:15 ` Qian Cai
  2022-05-10 17:50   ` Robin Murphy
  6 siblings, 1 reply; 23+ messages in thread
From: Qian Cai @ 2022-05-10 17:15 UTC (permalink / raw)
  To: Robin Murphy; +Cc: will, mark.rutland, linux-arm-kernel

On Mon, Apr 18, 2022 at 11:57:37PM +0100, Robin Murphy wrote:
> Hi Will,
> 
> As promised last time, here are the patches adding yet more inscrutable
> support for the other new members of the CMN family. I'm not sure if any
> of the folks who want this are the kind to give upstream feedback, but
> we can always live in hope... A colleague has kindly managed to briefly
> sanity-check the CMN-700 support under RTL emulation, but otherwise I've
> only been able to test the refactorings in terms of not breaking my
> little CMN-600 platform. Still, I'm pretty confident that that's caught
> all the stupids, and the rest is mostly just yet more events, so I
> don't think anything's particularly high-risk here.
> 
> Cheers,
> Robin.
> 
> 
> Robin Murphy (4):
>   dt-bindings: perf: arm-cmn: Add CMN-650 and CMN-700
>   perf/arm-cmn: Add CMN-650 support
>   perf/arm-cmn: Refactor occupancy filter selector
>   perf/arm-cmn: Add CMN-700 support
> 
>  .../devicetree/bindings/perf/arm,cmn.yaml     |   2 +
>  drivers/perf/arm-cmn.c                        | 606 ++++++++++++++----
>  2 files changed, 485 insertions(+), 123 deletions(-)

Reverting this series fixed a null-ptr-deref while running some syscall
fuzzers by an unprivileged user on a Neoverse-N1 server with two CMN-600
(one for each socket).

 KASAN: null-ptr-deref in range [0x0000000000000038-0x000000000000003f]
 Mem abort info:
   ESR = 0x0000000096000004
   EC = 0x25: DABT (current EL), IL = 32 bits
   SET = 0, FnV = 0
   EA = 0, S1PTW = 0
   FSC = 0x04: level 0 translation fault
 Data abort info:
   ISV = 0, ISS = 0x00000004
   CM = 0, WnR = 0
 [dfff800000000007] address between user and kernel address ranges
 Internal error: Oops: 96000004 [#1] PREEMPT SMP
 CPU: 7 PID: 115283 Comm: trinity-c57 Not tainted 5.18.0-rc6-next-20220510-dirty #93
 pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
 pc : arm_cmn_event_init [arm_cmn]
 lr : perf_try_init_event
 sp : ffff800058eb7a00
 x29: ffff800058eb7a10 x28: ffff080232bed880 x27: ffff400ccef2e120
 x26: ffff400ccef2e280 x25: 000000000000001f x24: 0000000000000003
 x23: 0000000000000001 x22: dfff800000000000 x21: 0000000000000219
 x20: ffffb0f539491e88 x19: 0000000000000000 x18: 0000000000000000
 x17: 0000000000000000 x16: 0000000000000000 x15: 0000aaaae0821540
 x14: 0000000000000028 x13: 0000000000000000 x12: ffff70000b1d6f03
 x11: 1ffff0000b1d6f02 x10: ffff70000b1d6f02 x9 : ffffb0f572260468
 x8 : ffff800058eb7817 x7 : ffff400ccef2e200 x6 : 1fffe80199de5c40
 x5 : ffffb0f53948fa00 x4 : 0000000000000000 x3 : ffff080232bed8e0
 x2 : ffffb0f539491efc x1 : 0000000000000007 x0 : 0000000000000038
 Call trace:
  arm_cmn_event_init [arm_cmn]
  perf_try_init_event
  perf_init_event
  perf_event_alloc
  __do_sys_perf_event_open
  __arm64_sys_perf_event_open
  invoke_syscall
  el0_svc_common.constprop.0
  do_el0_svc
  el0_svc
  el0t_64_sync_handler
  el0t_64_sync
 Code: 35002a21 f9400293 9100e260 d343fc01 (38f66821)
 ---[ end trace 0000000000000000 ]---
 Kernel panic - not syncing: Oops: Fatal exception
 SMP: stopping secondary CPUs
 Kernel Offset: 0x30f569c50000 from 0xffff800008000000
 PHYS_OFFSET: 0x80000000
 CPU features: 0x000,0042e015,19801c82
 Memory Limit: none


0x3e6c is in arm_cmn_event_init (drivers/perf/arm-cmn.c:1528).
1523    }
1524
1525
1526    static int arm_cmn_event_init(struct perf_event *event)
1527    {
1528            struct arm_cmn *cmn = to_cmn(event->pmu);
1529            struct arm_cmn_hw_event *hw = to_cmn_hw(event);
1530            struct arm_cmn_node *dn;
1531            enum cmn_node_type type;
1532            bool bynodeid;

# "map_1" has the same content.
$ sudo cat /sys/kernel/debug/arm-cmn/map
     X    0        1        2        3        4        5        6        7
Y P D+--------+--------+--------+--------+--------+--------+--------+--------+
5    | XP #40 | XP #41 | XP #42 | XP #43 | XP #44 | XP #45 | XP #46 | XP #47 |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  CXRH  |  HN-I  |  HN-I  |  HN-I  |  HN-D  |  HN-I  |  HN-I  |  CXRH  |
    0|   #2   |   #3   |   #4   |   #5   |   #0   |   #6   |   #7   |   #3   |
    1|        |        |        |        |        |        |        |        |
  1  |  RN-D  |  RN-D  |  RN-D  |  RN-I  |  RN-I  |  RN-D  |  RN-D  |  RN-D  |
    0|   #2   |   #3   |   #4   |   #10  |   #11  |   #5   |   #6   |   #7   |
    1|        |        |        |        |        |        |        |        |
-----+--------+--------+--------+--------+--------+--------+--------+--------+
4    | XP #32 | XP #33 | XP #34 | XP #35 | XP #36 | XP #37 | XP #38 | XP #39 |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
    0|        |        |   #8   |        |        |   #9   |        |        |
    1|        |        |        |        |        |        |        |        |
  1  |        | RN-F_B |        | RN-F_B | RN-F_B |        | RN-F_B |        |
    0|   #24  |        |   #26  |        |        |   #28  |        |   #30  |
    1|   #25  |        |   #27  |        |        |   #29  |        |   #31  |
-----+--------+--------+--------+--------+--------+--------+--------+--------+
3    | XP #24 | XP #25 | XP #26 | XP #27 | XP #28 | XP #29 | XP #30 | XP #31 |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
    0|        |        |   #6   |        |        |   #7   |        |        |
    1|        |        |        |        |        |        |        |        |
  1  |        | RN-F_B |        | RN-F_B | RN-F_B |        | RN-F_B |        |
    0|   #16  |        |   #18  |        |        |   #20  |        |   #22  |
    1|   #17  |        |   #19  |        |        |   #21  |        |   #23  |
-----+--------+--------+--------+--------+--------+--------+--------+--------+
2    | XP #16 | XP #17 | XP #18 | XP #19 | XP #20 | XP #21 | XP #22 | XP #23 |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
    0|        |        |   #4   |        |        |   #5   |        |        |
    1|        |        |        |        |        |        |        |        |
  1  |        | RN-F_B |        | RN-F_B | RN-F_B |        | RN-F_B |        |
    0|   #8   |        |   #10  |        |        |   #12  |        |   #14  |
    1|   #9   |        |   #11  |        |        |   #13  |        |   #15  |
-----+--------+--------+--------+--------+--------+--------+--------+--------+
1    | XP #8  | XP #9  | XP #10 | XP #11 | XP #12 | XP #13 | XP #14 | XP #15 |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
    0|        |        |   #2   |        |        |   #3   |        |        |
    1|        |        |        |        |        |        |        |        |
  1  |        | RN-F_B |        | RN-F_B | RN-F_B |        | RN-F_B |        |
    0|   #0   |        |   #2   |        |        |   #4   |        |   #6   |
    1|   #1   |        |   #3   |        |        |   #5   |        |   #7   |
-----+--------+--------+--------+--------+--------+--------+--------+--------+
0    | XP #0  | XP #1  | XP #2  | XP #3  | XP #4  | XP #5  | XP #6  | XP #7  |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  CXRH  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  CXRH  |
    0|   #0   |        |   #0   |        |        |   #1   |        |   #1   |
    1|        |        |        |        |        |        |        |        |
  1  |  RN-D  | RN-F_B |  HN-I  | RN-F_B | RN-F_B |  HN-I  | RN-F_B |  RN-D  |
    0|   #0   |        |   #1   |        |        |   #2   |        |   #1   |
    1|        |        |        |        |        |        |        |        |
-----+--------+--------+--------+--------+--------+--------+--------+--------+

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700
  2022-05-10 17:15 ` Qian Cai
@ 2022-05-10 17:50   ` Robin Murphy
  2022-05-10 19:38     ` Qian Cai
  2022-05-10 20:09     ` Qian Cai
  0 siblings, 2 replies; 23+ messages in thread
From: Robin Murphy @ 2022-05-10 17:50 UTC (permalink / raw)
  To: Qian Cai; +Cc: will, mark.rutland, linux-arm-kernel

On 2022-05-10 18:15, Qian Cai wrote:
> On Mon, Apr 18, 2022 at 11:57:37PM +0100, Robin Murphy wrote:
>> Hi Will,
>>
>> As promised last time, here are the patches adding yet more inscrutable
>> support for the other new members of the CMN family. I'm not sure if any
>> of the folks who want this are the kind to give upstream feedback, but
>> we can always live in hope... A colleague has kindly managed to briefly
>> sanity-check the CMN-700 support under RTL emulation, but otherwise I've
>> only been able to test the refactorings in terms of not breaking my
>> little CMN-600 platform. Still, I'm pretty confident that that's caught
>> all the stupids, and the rest is mostly just yet more events, so I
>> don't think anything's particularly high-risk here.
>>
>> Cheers,
>> Robin.
>>
>>
>> Robin Murphy (4):
>>    dt-bindings: perf: arm-cmn: Add CMN-650 and CMN-700
>>    perf/arm-cmn: Add CMN-650 support
>>    perf/arm-cmn: Refactor occupancy filter selector
>>    perf/arm-cmn: Add CMN-700 support
>>
>>   .../devicetree/bindings/perf/arm,cmn.yaml     |   2 +
>>   drivers/perf/arm-cmn.c                        | 606 ++++++++++++++----
>>   2 files changed, 485 insertions(+), 123 deletions(-)
> 
> Reverting this series fixed a null-ptr-deref while running some syscall
> fuzzers by an unprivileged user on a Neoverse-N1 server with two CMN-600
> (one for each socket).
> 
>   KASAN: null-ptr-deref in range [0x0000000000000038-0x000000000000003f]
>   Mem abort info:
>     ESR = 0x0000000096000004
>     EC = 0x25: DABT (current EL), IL = 32 bits
>     SET = 0, FnV = 0
>     EA = 0, S1PTW = 0
>     FSC = 0x04: level 0 translation fault
>   Data abort info:
>     ISV = 0, ISS = 0x00000004
>     CM = 0, WnR = 0
>   [dfff800000000007] address between user and kernel address ranges
>   Internal error: Oops: 96000004 [#1] PREEMPT SMP
>   CPU: 7 PID: 115283 Comm: trinity-c57 Not tainted 5.18.0-rc6-next-20220510-dirty #93
>   pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>   pc : arm_cmn_event_init [arm_cmn]
>   lr : perf_try_init_event
>   sp : ffff800058eb7a00
>   x29: ffff800058eb7a10 x28: ffff080232bed880 x27: ffff400ccef2e120
>   x26: ffff400ccef2e280 x25: 000000000000001f x24: 0000000000000003
>   x23: 0000000000000001 x22: dfff800000000000 x21: 0000000000000219
>   x20: ffffb0f539491e88 x19: 0000000000000000 x18: 0000000000000000
>   x17: 0000000000000000 x16: 0000000000000000 x15: 0000aaaae0821540
>   x14: 0000000000000028 x13: 0000000000000000 x12: ffff70000b1d6f03
>   x11: 1ffff0000b1d6f02 x10: ffff70000b1d6f02 x9 : ffffb0f572260468
>   x8 : ffff800058eb7817 x7 : ffff400ccef2e200 x6 : 1fffe80199de5c40
>   x5 : ffffb0f53948fa00 x4 : 0000000000000000 x3 : ffff080232bed8e0
>   x2 : ffffb0f539491efc x1 : 0000000000000007 x0 : 0000000000000038
>   Call trace:
>    arm_cmn_event_init [arm_cmn]
>    perf_try_init_event
>    perf_init_event
>    perf_event_alloc
>    __do_sys_perf_event_open
>    __arm64_sys_perf_event_open
>    invoke_syscall
>    el0_svc_common.constprop.0
>    do_el0_svc
>    el0_svc
>    el0t_64_sync_handler
>    el0t_64_sync
>   Code: 35002a21 f9400293 9100e260 d343fc01 (38f66821)
>   ---[ end trace 0000000000000000 ]---
>   Kernel panic - not syncing: Oops: Fatal exception
>   SMP: stopping secondary CPUs
>   Kernel Offset: 0x30f569c50000 from 0xffff800008000000
>   PHYS_OFFSET: 0x80000000
>   CPU features: 0x000,0042e015,19801c82
>   Memory Limit: none
> 
> 
> 0x3e6c is in arm_cmn_event_init (drivers/perf/arm-cmn.c:1528).
> 1523    }
> 1524
> 1525
> 1526    static int arm_cmn_event_init(struct perf_event *event)
> 1527    {
> 1528            struct arm_cmn *cmn = to_cmn(event->pmu);
> 1529            struct arm_cmn_hw_event *hw = to_cmn_hw(event);
> 1530            struct arm_cmn_node *dn;
> 1531            enum cmn_node_type type;
> 1532            bool bynodeid;

Hmm, can you narrow it down a bit more to a particular patch and/or a 
specific reproducer? I don't see how it could really be crashing 
dereferencing event->pmu, especially since none of the code this early 
in event_init has even changed recently :/

AFAICS the most plausible thing at offset 0x38 from anywhere would be 
event->pmu->type, but again, if event->pmu is NULL here that's surely a 
fault in perf core rather than the driver?

> # "map_1" has the same content.
> $ sudo cat /sys/kernel/debug/arm-cmn/map
>       X    0        1        2        3        4        5        6        7
> Y P D+--------+--------+--------+--------+--------+--------+--------+--------+
> 5    | XP #40 | XP #41 | XP #42 | XP #43 | XP #44 | XP #45 | XP #46 | XP #47 |
>       | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
>       |........|........|........|........|........|........|........|........|
>    0  |  CXRH  |  HN-I  |  HN-I  |  HN-I  |  HN-D  |  HN-I  |  HN-I  |  CXRH  |
>      0|   #2   |   #3   |   #4   |   #5   |   #0   |   #6   |   #7   |   #3   |
>      1|        |        |        |        |        |        |        |        |
>    1  |  RN-D  |  RN-D  |  RN-D  |  RN-I  |  RN-I  |  RN-D  |  RN-D  |  RN-D  |
>      0|   #2   |   #3   |   #4   |   #10  |   #11  |   #5   |   #6   |   #7   |
>      1|        |        |        |        |        |        |        |        |
> -----+--------+--------+--------+--------+--------+--------+--------+--------+
> 4    | XP #32 | XP #33 | XP #34 | XP #35 | XP #36 | XP #37 | XP #38 | XP #39 |
>       | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
>       |........|........|........|........|........|........|........|........|
>    0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
>      0|        |        |   #8   |        |        |   #9   |        |        |
>      1|        |        |        |        |        |        |        |        |
>    1  |        | RN-F_B |        | RN-F_B | RN-F_B |        | RN-F_B |        |
>      0|   #24  |        |   #26  |        |        |   #28  |        |   #30  |
>      1|   #25  |        |   #27  |        |        |   #29  |        |   #31  |

Something's definitely screwy here though... these ID numbers should 
have a device type above them. Was this dumped with patch #1 applied, 
and if not do they show as "????" when it is?

Thanks,
Robin.

> -----+--------+--------+--------+--------+--------+--------+--------+--------+
> 3    | XP #24 | XP #25 | XP #26 | XP #27 | XP #28 | XP #29 | XP #30 | XP #31 |
>       | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
>       |........|........|........|........|........|........|........|........|
>    0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
>      0|        |        |   #6   |        |        |   #7   |        |        |
>      1|        |        |        |        |        |        |        |        |
>    1  |        | RN-F_B |        | RN-F_B | RN-F_B |        | RN-F_B |        |
>      0|   #16  |        |   #18  |        |        |   #20  |        |   #22  |
>      1|   #17  |        |   #19  |        |        |   #21  |        |   #23  |
> -----+--------+--------+--------+--------+--------+--------+--------+--------+
> 2    | XP #16 | XP #17 | XP #18 | XP #19 | XP #20 | XP #21 | XP #22 | XP #23 |
>       | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
>       |........|........|........|........|........|........|........|........|
>    0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
>      0|        |        |   #4   |        |        |   #5   |        |        |
>      1|        |        |        |        |        |        |        |        |
>    1  |        | RN-F_B |        | RN-F_B | RN-F_B |        | RN-F_B |        |
>      0|   #8   |        |   #10  |        |        |   #12  |        |   #14  |
>      1|   #9   |        |   #11  |        |        |   #13  |        |   #15  |
> -----+--------+--------+--------+--------+--------+--------+--------+--------+
> 1    | XP #8  | XP #9  | XP #10 | XP #11 | XP #12 | XP #13 | XP #14 | XP #15 |
>       | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
>       |........|........|........|........|........|........|........|........|
>    0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
>      0|        |        |   #2   |        |        |   #3   |        |        |
>      1|        |        |        |        |        |        |        |        |
>    1  |        | RN-F_B |        | RN-F_B | RN-F_B |        | RN-F_B |        |
>      0|   #0   |        |   #2   |        |        |   #4   |        |   #6   |
>      1|   #1   |        |   #3   |        |        |   #5   |        |   #7   |
> -----+--------+--------+--------+--------+--------+--------+--------+--------+
> 0    | XP #0  | XP #1  | XP #2  | XP #3  | XP #4  | XP #5  | XP #6  | XP #7  |
>       | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
>       |........|........|........|........|........|........|........|........|
>    0  |  CXRH  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  CXRH  |
>      0|   #0   |        |   #0   |        |        |   #1   |        |   #1   |
>      1|        |        |        |        |        |        |        |        |
>    1  |  RN-D  | RN-F_B |  HN-I  | RN-F_B | RN-F_B |  HN-I  | RN-F_B |  RN-D  |
>      0|   #0   |        |   #1   |        |        |   #2   |        |   #1   |
>      1|        |        |        |        |        |        |        |        |
> -----+--------+--------+--------+--------+--------+--------+--------+--------+

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700
  2022-05-10 17:50   ` Robin Murphy
@ 2022-05-10 19:38     ` Qian Cai
  2022-05-10 21:05       ` Robin Murphy
  2022-05-10 20:09     ` Qian Cai
  1 sibling, 1 reply; 23+ messages in thread
From: Qian Cai @ 2022-05-10 19:38 UTC (permalink / raw)
  To: Robin Murphy; +Cc: will, mark.rutland, linux-arm-kernel

On Tue, May 10, 2022 at 06:50:56PM +0100, Robin Murphy wrote:
> Hmm, can you narrow it down a bit more to a particular patch and/or a
> specific reproducer? I don't see how it could really be crashing
> dereferencing event->pmu, especially since none of the code this early in
> event_init has even changed recently :/

Right, there is an old bug that sometimes the debuginfo on kernel
modules is not accurate on arm64, so gdb and faddr2line gave the wrong
line. Anyway, using the printk() method, we were faulted on this line.

+       /* This is sufficiently annoying to recalculate, so cache it */
+       hw->filter_sel = arm_cmn_filter_sel(cmn->model, type, eventid);

Also, it can be reproduced within 5-min by running,

$ trinity -C 128 -cperf_event_open

> Something's definitely screwy here though... these ID numbers should have a
> device type above them. Was this dumped with patch #1 applied, and if not do
> they show as "????" when it is?

Yes, with the series applied, we have,


     X    0        1        2        3        4        5        6        7
Y P D+--------+--------+--------+--------+--------+--------+--------+--------+
5    | XP #40 | XP #41 | XP #42 | XP #43 | XP #44 | XP #45 | XP #46 | XP #47 |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  CXRH  |  HN-I  |  HN-I  |  HN-I  |  HN-D  |  HN-I  |  HN-I  |  CXRH  |
    0|   #2   |   #3   |   #4   |   #5   |   #0   |   #6   |   #7   |   #3   |
    1|        |        |        |        |        |        |        |        |
  1  |  RN-D  |  RN-D  |  RN-D  |  RN-I  |  RN-I  |  RN-D  |  RN-D  |  RN-D  |
    0|   #2   |   #3   |   #4   |   #10  |   #11  |   #5   |   #6   |   #7   |
    1|        |        |        |        |        |        |        |        |
-----+--------+--------+--------+--------+--------+--------+--------+--------+
4    | XP #32 | XP #33 | XP #34 | XP #35 | XP #36 | XP #37 | XP #38 | XP #39 |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
    0|        |        |   #8   |        |        |   #9   |        |        |
    1|        |        |        |        |        |        |        |        |
  1  |  ????  | RN-F_B |  ????  | RN-F_B | RN-F_B |  ????  | RN-F_B |  ????  |
    0|   #24  |        |   #26  |        |        |   #28  |        |   #30  |
    1|   #25  |        |   #27  |        |        |   #29  |        |   #31  |
-----+--------+--------+--------+--------+--------+--------+--------+--------+
3    | XP #24 | XP #25 | XP #26 | XP #27 | XP #28 | XP #29 | XP #30 | XP #31 |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
    0|        |        |   #6   |        |        |   #7   |        |        |
    1|        |        |        |        |        |        |        |        |
  1  |  ????  | RN-F_B |  ????  | RN-F_B | RN-F_B |  ????  | RN-F_B |  ????  |
    0|   #16  |        |   #18  |        |        |   #20  |        |   #22  |
    1|   #17  |        |   #19  |        |        |   #21  |        |   #23  |
-----+--------+--------+--------+--------+--------+--------+--------+--------+
2    | XP #16 | XP #17 | XP #18 | XP #19 | XP #20 | XP #21 | XP #22 | XP #23 |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
    0|        |        |   #4   |        |        |   #5   |        |        |
    1|        |        |        |        |        |        |        |        |
  1  |  ????  | RN-F_B |  ????  | RN-F_B | RN-F_B |  ????  | RN-F_B |  ????  |
    0|   #8   |        |   #10  |        |        |   #12  |        |   #14  |
    1|   #9   |        |   #11  |        |        |   #13  |        |   #15  |
-----+--------+--------+--------+--------+--------+--------+--------+--------+
1    | XP #8  | XP #9  | XP #10 | XP #11 | XP #12 | XP #13 | XP #14 | XP #15 |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  SN-F  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  SN-F  |
    0|        |        |   #2   |        |        |   #3   |        |        |
    1|        |        |        |        |        |        |        |        |
  1  |  ????  | RN-F_B |  ????  | RN-F_B | RN-F_B |  ????  | RN-F_B |  ????  |
    0|   #0   |        |   #2   |        |        |   #4   |        |   #6   |
    1|   #1   |        |   #3   |        |        |   #5   |        |   #7   |
-----+--------+--------+--------+--------+--------+--------+--------+--------+
0    | XP #0  | XP #1  | XP #2  | XP #3  | XP #4  | XP #5  | XP #6  | XP #7  |
     | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  | DTC 0  |
     |........|........|........|........|........|........|........|........|
  0  |  CXRH  | RN-F_B |  RN-I  | RN-F_B | RN-F_B |  RN-I  | RN-F_B |  CXRH  |
    0|   #0   |        |   #0   |        |        |   #1   |        |   #1   |
    1|        |        |        |        |        |        |        |        |
  1  |  RN-D  | RN-F_B |  HN-I  | RN-F_B | RN-F_B |  HN-I  | RN-F_B |  RN-D  |
    0|   #0   |        |   #1   |        |        |   #2   |        |   #1   |
    1|        |        |        |        |        |        |        |        |
-----+--------+--------+--------+--------+--------+--------+--------+--------+

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700
  2022-05-10 17:50   ` Robin Murphy
  2022-05-10 19:38     ` Qian Cai
@ 2022-05-10 20:09     ` Qian Cai
  1 sibling, 0 replies; 23+ messages in thread
From: Qian Cai @ 2022-05-10 20:09 UTC (permalink / raw)
  To: Robin Murphy; +Cc: will, mark.rutland, linux-arm-kernel

On Tue, May 10, 2022 at 06:50:56PM +0100, Robin Murphy wrote:
> Hmm, can you narrow it down a bit more to a particular patch and/or a
> specific reproducer? I don't see how it could really be crashing
> dereferencing event->pmu, especially since none of the code this early in
> event_init has even changed recently :/

Specifically, One of "e" == NULL in arm_cmn_filter_sel().

e = container_of(arm_cmn_event_attrs[i], typeof(*e), attr.attr);

Then, the next line will dereference it.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700
  2022-05-10 19:38     ` Qian Cai
@ 2022-05-10 21:05       ` Robin Murphy
  0 siblings, 0 replies; 23+ messages in thread
From: Robin Murphy @ 2022-05-10 21:05 UTC (permalink / raw)
  To: Qian Cai; +Cc: will, mark.rutland, linux-arm-kernel

On 2022-05-10 20:38, Qian Cai wrote:
> On Tue, May 10, 2022 at 06:50:56PM +0100, Robin Murphy wrote:
>> Hmm, can you narrow it down a bit more to a particular patch and/or a
>> specific reproducer? I don't see how it could really be crashing
>> dereferencing event->pmu, especially since none of the code this early in
>> event_init has even changed recently :/
> 
> Right, there is an old bug that sometimes the debuginfo on kernel
> modules is not accurate on arm64, so gdb and faddr2line gave the wrong
> line. Anyway, using the printk() method, we were faulted on this line.
> 
> +       /* This is sufficiently annoying to recalculate, so cache it */
> +       hw->filter_sel = arm_cmn_filter_sel(cmn->model, type, eventid);

Aha, that's a much more believable culprit - 0x38 also stood out as an 
offset in the attribute structures.

> Also, it can be reproduced within 5-min by running,
> 
> $ trinity -C 128 -cperf_event_open

I can already guess what I've done, and just reproduced the crash 
directly on the first try :)

I'll work on the fix tomorrow, thanks for the report and info!

>> Something's definitely screwy here though... these ID numbers should have a
>> device type above them. Was this dumped with patch #1 applied, and if not do
>> they show as "????" when it is?
> 
> Yes, with the series applied, we have,

Ah, turns out I can no longer get away with being lazy and not masking 
the device_type field properly when reading connect_info, as some of the 
adjacent bits are no longer reserved since the debugfs code was first 
written - I've not played with a CAL config of any of the newer stuff, 
or I might have noticed sooner.

But at least that tweak to differentiate unknown from unconnected has 
now paid for itself :D

Cheers,
Robin.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2022-05-10 21:07 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-18 22:57 [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Robin Murphy
2022-04-18 22:57 ` [PATCH 1/4] dt-bindings: perf: arm-cmn: " Robin Murphy
2022-04-18 22:57   ` Robin Murphy
2022-04-26 20:12   ` Rob Herring
2022-04-26 20:12     ` Rob Herring
2022-04-18 22:57 ` [PATCH 2/4] perf/arm-cmn: Add CMN-650 support Robin Murphy
2022-04-19 23:05   ` Ilkka Koskinen
2022-04-19 23:47     ` Ilkka Koskinen
2022-04-20  9:26       ` Will Deacon
2022-04-20 10:12     ` Robin Murphy
2022-04-21  7:09       ` Ilkka Koskinen
2022-04-21  7:25   ` Ilkka Koskinen
2022-04-21  9:46     ` Robin Murphy
2022-04-21 21:26       ` Ilkka Koskinen
2022-04-18 22:57 ` [PATCH 3/4] perf/arm-cmn: Refactor occupancy filter selector Robin Murphy
2022-04-18 22:57 ` [PATCH 4/4] perf/arm-cmn: Add CMN-700 support Robin Murphy
2022-04-21  7:54 ` [PATCH 0/4] perf/arm-cmn: Add CMN-650 and CMN-700 Ilkka Koskinen
2022-05-06 14:43 ` Will Deacon
2022-05-10 17:15 ` Qian Cai
2022-05-10 17:50   ` Robin Murphy
2022-05-10 19:38     ` Qian Cai
2022-05-10 21:05       ` Robin Murphy
2022-05-10 20:09     ` Qian Cai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.