Arm CMN-600 PMU driver
Subsystems (4)
Robin Murphy
maintainerv2 cover Arm CMN-600 PMU driver
Hi all,
Here's an update with some very minor cleanup tweaks, plus a proposal for some more in-depth debug information. Given that nobody seems to have any significant complaints about the interface, I assume we're all happy to merge the basic driver as-is and fix anything later if needed.
Robin.
Robin Murphy (3):
perf: Add Arm CMN-600 DT binding
perf: Add Arm CMN-600 PMU driver
perf/arm-cmn: Add debugfs topology info
Documentation/admin-guide/perf/arm-cmn.rst | 65 + Documentation/admin-guide/perf/index.rst | 1 + .../devicetree/bindings/perf/arm,cmn.yaml | 57 + drivers/perf/Kconfig | 7 + drivers/perf/Makefile | 1 + drivers/perf/arm-cmn.c | 1790 +++++++++++++++++ 6 files changed, 1921 insertions(+) create mode 100644 Documentation/admin-guide/perf/arm-cmn.rst create mode 100644 Documentation/devicetree/bindings/perf/arm,cmn.yaml create mode 100644 drivers/perf/arm-cmn.c
Signature · 1 line
2.28.0.dirty
Robin Murphy
maintainerPATCH v2 1/3 perf: Add Arm CMN-600 DT binding
Document the requirements for the CMN-600 DT binding. The internal topology is almost entirely discoverable by walking a tree of ID registers, but sadly both the starting point for that walk and the exact format of those registers are configuration-dependent and not discoverable from some sane fixed location. Oh well.
---
v2: fix filename, license and whitespace per Rob's comments
.../devicetree/bindings/perf/arm,cmn.yaml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/perf/arm,cmn.yaml
Documentation/devicetree/bindings/perf/arm,cmn.yaml new file +57 -0
@@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2020 Arm Ltd. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/perf/arm-cmn.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arm CMN (Coherent Mesh Network) Performance Monitors + +maintainers: + - Robin Murphy <[email protected]> + +properties: + compatible: + const: arm,cmn-600 + + reg: + items: + - description: Physical address of the base (PERIPHBASE) and + size (up to 64MB) of the configuration address space. + + interrupts: + minItems: 1 + maxItems: 4 + items: + - description: Overflow interrupt for DTC0 + - description: Overflow interrupt for DTC1 + - description: Overflow interrupt for DTC2 + - description: Overflow interrupt for DTC3 + description: One interrupt for each DTC domain implemented must + be specified, in order. DTC0 is always present. + + arm,root-node: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Offset from PERIPHBASE of the configuration + discovery node (see TRM definition of ROOTNODEBASE). + +required: + - compatible + - reg + - interrupts + - arm,root-node + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + pmu@50000000 { + compatible = "arm,cmn-600"; + reg = <0x50000000 0x4000000>; + /* 4x2 mesh with one DTC, and CFG node at 0,1,1,0 */ + interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; + arm,root-node = <0x104000>; + }; +...
Signature · 1 line
2.28.0.dirty
Rob Herring
maintainerRe: [PATCH v2 1/3] perf: Add Arm CMN-600 DT binding
Quoted 6 lines · Robin Murphy
Document the requirements for the CMN-600 DT binding. The internal topology is almost entirely discoverable by walking a tree of ID registers, but sadly both the starting point for that walk and the exact format of those registers are configuration-dependent and not discoverable from some sane fixed location. Oh well.
Quoted 9 lines
Signed-off-by Robin Murphy <[email protected]>---
v2: fix filename, license and whitespace per Rob's comments
.../devicetree/bindings/perf/arm,cmn.yaml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/perf/arm,cmn.yaml
My bot found errors running 'make dt_binding_check' on your patch:
./Documentation/devicetree/bindings/perf/arm,cmn.yaml: $id: relative path/filename doesn't match actual path or filename
expected: http://devicetree.org/schemas/perf/arm,cmn.yaml#
See https://patchwork.ozlabs.org/patch/1366940
If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure dt-schema is up to date:
pip3 install git+https://github.com/devicetree-org/dt-schema.git@master --upgrade
Please check and re-submit.
Robin Murphy
maintainerPATCH v2 1/3 perf: Add Arm CMN-600 DT binding
In reply to Robin MurphyDocument the requirements for the CMN-600 DT binding. The internal topology is almost entirely discoverable by walking a tree of ID registers, but sadly both the starting point for that walk and the exact format of those registers are configuration-dependent and not discoverable from some sane fixed location. Oh well.
---
fix up $id as well, oops...
.../devicetree/bindings/perf/arm,cmn.yaml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/perf/arm,cmn.yaml
Documentation/devicetree/bindings/perf/arm,cmn.yaml new file +57 -0
@@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2020 Arm Ltd. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/perf/arm,cmn.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arm CMN (Coherent Mesh Network) Performance Monitors + +maintainers: + - Robin Murphy <[email protected]> + +properties: + compatible: + const: arm,cmn-600 + + reg: + items: + - description: Physical address of the base (PERIPHBASE) and + size (up to 64MB) of the configuration address space. + + interrupts: + minItems: 1 + maxItems: 4 + items: + - description: Overflow interrupt for DTC0 + - description: Overflow interrupt for DTC1 + - description: Overflow interrupt for DTC2 + - description: Overflow interrupt for DTC3 + description: One interrupt for each DTC domain implemented must + be specified, in order. DTC0 is always present. + + arm,root-node: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Offset from PERIPHBASE of the configuration + discovery node (see TRM definition of ROOTNODEBASE). + +required: + - compatible + - reg + - interrupts + - arm,root-node + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + pmu@50000000 { + compatible = "arm,cmn-600"; + reg = <0x50000000 0x4000000>; + /* 4x2 mesh with one DTC, and CFG node at 0,1,1,0 */ + interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; + arm,root-node = <0x104000>; + }; +...
--
2.28.0.dirty
Rob Herring
maintainerRe: [PATCH v2.1 1/3] perf: Add Arm CMN-600 DT binding
Quoted 7 lines · Robin Murphy
Document the requirements for the CMN-600 DT binding. The internal topology is almost entirely discoverable by walking a tree of ID registers, but sadly both the starting point for that walk and the exact format of those registers are configuration-dependent and not discoverable from some sane fixed location. Oh well.
Quoted 8 lines
Signed-off-by Robin Murphy <[email protected]>---
fix up $id as well, oops...
.../devicetree/bindings/perf/arm,cmn.yaml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/perf/arm,cmn.yaml
Do you expect this to cover more than cmn-600? If not, use the compatible string for the file name.
Quoted 28 lines
Documentation/devicetree/bindings/perf/arm,cmn.yaml new file +21
-0@@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2020 Arm Ltd. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/perf/arm,cmn.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arm CMN (Coherent Mesh Network) Performance Monitors + +maintainers: + - Robin Murphy <[email protected]> + +properties: + compatible: + const: arm,cmn-600 + + reg: + items: + - description: Physical address of the base (PERIPHBASE) and + size (up to 64MB) of the configuration address space. +
Documentation/devicetree/bindings/perf/arm,cmn.yaml line 31
Quoted 10 lines
Documentation/devicetree/bindings/perf/arm,cmn.yaml new file +10
-0+ interrupts: + minItems: 1 + maxItems: 4 + items: + - description: Overflow interrupt for DTC0 + - description: Overflow interrupt for DTC1 + - description: Overflow interrupt for DTC2 + - description: Overflow interrupt for DTC3 + description: One interrupt for each DTC domain implemented must + be specified, in order. DTC0 is always present.
What's DTC?
Documentation/devicetree/bindings/perf/arm,cmn.yaml line 36
Quoted 5 lines
Documentation/devicetree/bindings/perf/arm,cmn.yaml new file +5
-0+ + arm,root-node: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Offset from PERIPHBASE of the configuration + discovery node (see TRM definition of ROOTNODEBASE).
You can enforce some alignment:
multipleOf: 0x4000
Quoted 23 lines
Documentation/devicetree/bindings/perf/arm,cmn.yaml new file +21
-1+ +required: + - compatible + - reg + - interrupts + - arm,root-node + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + pmu@50000000 { + compatible = "arm,cmn-600"; + reg = <0x50000000 0x4000000>; + /* 4x2 mesh with one DTC, and CFG node at 0,1,1,0 */ + interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; + arm,root-node = <0x104000>; + }; +... --2.28.0.dirty
Robin Murphy
maintainerRe: [PATCH v2.1 1/3] perf: Add Arm CMN-600 DT binding
Quoted 11 lines · Rob Herring
Quoted 10 lines · Robin Murphy
Document the requirements for the CMN-600 DT binding. The internal topology is almost entirely discoverable by walking a tree of ID registers, but sadly both the starting point for that walk and the exact format of those registers are configuration-dependent and not discoverable from some sane fixed location. Oh well.
Signed-off-by Robin Murphy <[email protected]>---
Quoted 8 lines
Quoted 5 lines
fix up $id as well, oops...
.../devicetree/bindings/perf/arm,cmn.yaml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+)create mode 100644
Documentation/devicetree/bindings/perf/arm,cmn.yamlDo you expect this to cover more than cmn-600? If not, use the compatible string for the file name.
As far as I'm aware, future CMN products will maintain the same general PMU design, but with enough subtle differences to deserve their own compatible strings.
Quoted 31 lines
Quoted 31 lines
Documentation/devicetree/bindings/perf/arm,cmn.yaml new file +25
-0@@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2020 Arm Ltd. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/perf/arm,cmn.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arm CMN (Coherent Mesh Network) Performance Monitors + +maintainers: + - Robin Murphy <[email protected]> + +properties: + compatible: + const: arm,cmn-600 + + reg: + items: + - description: Physical address of the base (PERIPHBASE) and + size (up to 64MB) of the configuration address space. + + interrupts: + minItems: 1 + maxItems: 4 + items:
Quoted 8 lines
Documentation/devicetree/bindings/perf/arm,cmn.yaml line 31
Quoted 6 lines
Documentation/devicetree/bindings/perf/arm,cmn.yaml new file +6
-0+ - description: Overflow interrupt for DTC0 + - description: Overflow interrupt for DTC1 + - description: Overflow interrupt for DTC2 + - description: Overflow interrupt for DTC3 + description: One interrupt for each DTC domain implemented must + be specified, in order. DTC0 is always present.What's DTC?
Debug and Trace Controller. I figure it's one of those situations where if someone knows enough about a CMN configuration to be able to write something to this binding, they're probably going to be familiar with the abbreviation.
In CMN terminology, "DT" is all over the place meaning "Debug and Trace". Only now do I suddenly realise that discussing this in the context of Device Tree is pretty much the worst-case scenario for confusion :)
Quoted 9 lines
Documentation/devicetree/bindings/perf/arm,cmn.yaml line 36
Quoted 5 lines
Documentation/devicetree/bindings/perf/arm,cmn.yaml new file +5
-0+ + arm,root-node: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Offset from PERIPHBASE of the configuration + discovery node (see TRM definition of ROOTNODEBASE).You can enforce some alignment:
multipleOf:
0x4000
That's one of the things that may vary in future, so I'm doubtful if it would really be worth the bother. There's only one correct value for a given configuration, and still hundreds of appropriately-aligned wrong ones, so ultimately either it's right and it works, or it's not and it won't (any sensible driver should do a bit of sanity-checking during discovery anyway).
Robin.
Quoted 23 lines
Quoted 23 lines
Documentation/devicetree/bindings/perf/arm,cmn.yaml new file +21
-1+ +required: + - compatible + - reg + - interrupts + - arm,root-node + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + pmu@50000000 { + compatible = "arm,cmn-600"; + reg = <0x50000000 0x4000000>; + /* 4x2 mesh with one DTC, and CFG node at 0,1,1,0 */ + interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; + arm,root-node = <0x104000>; + }; +... --2.28.0.dirty
Robin Murphy
maintainerPATCH v2 2/3 perf: Add Arm CMN-600 PMU driver
In reply to Robin MurphyInitial driver for PMU event counting on the Arm CMN-600 interconnect. CMN sports an obnoxiously complex distributed PMU system as part of its debug and trace features, which can do all manner of things like sampling, cross-triggering and generating CoreSight trace. This driver covers the PMU functionality, plus the relevant aspects of watchpoints for simply counting matching flits.
---
v2:
- fix non-atomic use of atomic ID counter
- slightly refactor DTM initialisation to be more sensible
- remove left-over root node probing hack
Documentation/admin-guide/perf/arm-cmn.rst | 65 + Documentation/admin-guide/perf/index.rst | 1 + drivers/perf/Kconfig | 7 + drivers/perf/Makefile | 1 + drivers/perf/arm-cmn.c | 1641 ++++++++++++++++++++ 5 files changed, 1715 insertions(+) create mode 100644 Documentation/admin-guide/perf/arm-cmn.rst create mode 100644 drivers/perf/arm-cmn.c
Documentation/admin-guide/perf/arm-cmn.rst new file +65 -0
@@ -0,0 +1,65 @@ +============================= +Arm Coherent Mesh Network PMU +============================= + +CMN-600 is a configurable mesh interconnect consisting of a rectangular +grid of crosspoints (XPs), with each crosspoint supporting up to two +device ports to which various AMBA CHI agents are attached. + +CMN implements a distributed PMU design as part of its debug and trace +functionality. This consists of a local monitor (DTM) at every XP, which +counts up to 4 event signals from the connected device nodes and/or the +XP itself. Overflow from these local counters is accumulated in up to 8 +global counters implemented by the main controller (DTC), which provides +overall PMU control and interrupts for global counter overflow. + +PMU events +---------- + +The PMU driver registers a single PMU device for the whole interconnect, +see /sys/bus/event_source/devices/arm_cmn. Multi-chip systems may link +more than one CMN together via external CCIX links - in this situation, +each mesh counts its own events entirely independently, and additional +PMU devices will be named arm_cmn_{1..n}. + +Most events are specified in a format based directly on the TRM +definitions - "type" selects the respective node type, and "eventid" the +event number. Some events require an additional occupancy ID, which is +specified by "occupid". + +* Since RN-D nodes do not have any distinct events from RN-I nodes, they + are treated as the same type (0xa), and the common event templates are + named "rnid_*". + +* The cycle counter is treated as a synthetic event belonging to the DTC + node ("type" == 0x3, "eventid" is ignored). + +* XP events also encode the port and channel in the "eventid" field, to + match the underlying pmu_event0_id encoding for the pmu_event_sel + register. The event templates are named with prefixes to cover all + permutations. + +By default each event provides an aggregate count over all nodes of the +given type. To target a specific node, "bynodeid" must be set to 1 and +"nodeid" to the appropriate value derived from the CMN configuration +(as defined in the "Node ID Mapping" section of the TRM). + +Watchpoints +----------- + +The PMU can also count watchpoint events to monitor specific flit +traffic. Watchpoints are treated as a synthetic event type, and like PMU +events can be global or targeted with a particular XP's "nodeid" value. +Since the watchpoint direction is otherwise implicit in the underlying +register selection, separate events are provided for flit uploads and +downloads. + +The flit match value and mask are passed in config1 and config2 ("val" +and "mask" respectively). "wp_dev_sel", "wp_chn_sel", "wp_grp" and +"wp_exclusive" are specified per the TRM definitions for dtm_wp_config0. +Where a watchpoint needs to match fields from both match groups on the +REQ or SNP channel, it can be specified as two events - one for each +group - with the same nonzero "combine" value. The count for such a +pair of combined events will be attributed to the primary match. +Watchpoint events with a "combine" value of 0 are considered independent +and will count individually.
Documentation/admin-guide/perf/index.rst +1 -0
@@ -12,6 +12,7 @@ Performance monitor support qcom_l2_pmu qcom_l3_pmu arm-ccn + arm-cmn xgene-pmu arm_dsu_pmu thunderx2-pmu
drivers/perf/Kconfig +7 -0
@@ -41,6 +41,13 @@ config ARM_CCN PMU (perf) driver supporting the ARM CCN (Cache Coherent Network) interconnect. +config ARM_CMN + tristate "Arm CMN-600 PMU support" + depends on ARM64 || (COMPILE_TEST && 64BIT) + help + Support for PMU events monitoring on the Arm CMN-600 Coherent Mesh + Network interconnect. + config ARM_PMU depends on ARM || ARM64 bool "ARM PMU framework"
drivers/perf/Makefile +1 -0
@@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_ARM_CCI_PMU) += arm-cci.o obj-$(CONFIG_ARM_CCN) += arm-ccn.o +obj-$(CONFIG_ARM_CMN) += arm-cmn.o obj-$(CONFIG_ARM_DSU_PMU) += arm_dsu_pmu.o obj-$(CONFIG_ARM_PMU) += arm_pmu.o arm_pmu_platform.o obj-$(CONFIG_ARM_PMU_ACPI) += arm_pmu_acpi.o
drivers/perf/arm-cmn.c new file +1641 -0
1,641 lines not on this page · raw message
Signature · 1 line
2.28.0.dirty
Robin Murphy
maintainerRFC v2 3/3 perf/arm-cmn: Add debugfs topology info
In reply to Robin MurphyIn general, detailed performance analysis will require knoweldge of the the SoC beyond the CMN itself - e.g. which actual CPUs/peripherals/etc. are connected to each node. However for certain development and bringup tasks it can be useful to have a quick overview of the CMN internal topology to hand too. Add a debugfs file to map this out.
--- drivers/perf/arm-cmn.c | 161 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 155 insertions(+), 6 deletions(-)
drivers/perf/arm-cmn.c +155 -6
@@ -5,6 +5,7 @@#include <linux/acpi.h> #include <linux/bitfield.h> #include <linux/bitops.h> +#include <linux/debugfs.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/kernel.h>
@@ -47,6 +48,10 @@#define CMN_CFGM_PERIPH_ID_2 0x0010#define CMN_CFGM_PID2_REVISION GENMASK(7, 4) +/* XPs have some extra topology info which isn't directly relevant to the PMU */ +#define CMN_MXP__CONNECT_INFO_P0 0x0008 +#define CMN_MXP__CONNECT_INFO_P1 0x0010 +/* PMU registers occupy the 3rd 4KB page of each node's 16KB space */ #define CMN_PMU_OFFSET 0x2000
@@ -248,11 +253,151 @@ struct arm_cmn {unsigned int state;struct pmu pmu; +struct dentry *debug; };#define to_cmn (p) container_of(p, struct arm_cmn, pmu) +static int arm_cmn_xyidbits (const struct arm_cmn *cmn) +{ +return cmn->mesh_x >4 || cmn->mesh_y >4 ?3 :2 ; +} +static int arm_cmn_hp_state; +struct dentry *arm_cmn_debugfs; + +#ifdef CONFIG_DEBUG_FS +static const char *arm_cmn_device_type (u8 type) +{ +switch (type) { +case 0x01 :return " RN-I |" ; +case 0x02 :return " RN-D |" ; +case 0x04 :return " RN-F_B |" ; +case 0x05 :return "RN-F_B_E|" ; +case 0x06 :return " RN-F_A |" ; +case 0x07 :return "RN-F_A_E|" ; +case 0x08 :return " HN-T |" ; +case 0x09 :return " HN-I |" ; +case 0x0a :return " HN-D |" ; +case 0x0c :return " SN-F |" ; +case 0x0d :return " SBSX |" ; +case 0x0e :return " HN-F |" ; +case 0x11 :return " CXHA |" ; +case 0x12 :return " CXRA |" ; +case 0x13 :return " CXRH |" ; +default :return " |" ; + } +} + +static void arm_cmn_show_logid (struct seq_file *s,int x,int y,int p,int d) +{ +struct arm_cmn *cmn = s->private; +int i, bits =arm_cmn_xyidbits (cmn); + +for (i =0 ; i < cmn->num_dns; i++) { +enum cmn_node_type type = cmn->dns[i].type; +u16 id = cmn->dns[i].id; + +if (type ==CMN_TYPE_XP ) +continue ; +/* Ignore the extra components that will overlap on some ports */ +if (type <CMN_TYPE_HNI ) +continue ; + +if (CMN_NODEID_X (id, bits) != x ||CMN_NODEID_Y (id, bits) != y || +CMN_NODEID_PID (id) != p ||CMN_NODEID_DEVID (id) != d) +continue ; + +seq_printf (s," #%-2d |" , cmn->dns[i].logid); +return ; + } +seq_puts (s," |" ); +} + +static int arm_cmn_map_show (struct seq_file *s,void *data) +{ +struct arm_cmn *cmn = s->private; +int x, y; + +seq_puts (s," X" ); +for (x =0 ; x < cmn->mesh_x; x++) +seq_printf (s," %d " , x); +seq_puts (s,"\nY P D+" ); + y = cmn->mesh_y; +while (y--) { +int xp_base = cmn->mesh_x * y; +u8 port[2 ][8 ] = {}; + +for (x =0 ; x < cmn->mesh_x; x++) +seq_puts (s,"--------+" ); + +seq_printf (s,"\n%d |" , y); +for (x =0 ; x < cmn->mesh_x; x++) { +struct arm_cmn_node *xp = cmn->xps + xp_base + x; +void __iomem *base = xp->pmu_base -CMN_PMU_OFFSET ; + + port[0 ][x] =readl_relaxed (base +CMN_MXP__CONNECT_INFO_P0 ); + port[1 ][x] =readl_relaxed (base +CMN_MXP__CONNECT_INFO_P1 ); +seq_printf (s," XP #%-2d |" , xp_base + x); + } + +seq_puts (s,"\n |" ); +for (x =0 ; x < cmn->mesh_x; x++) { +int dtc = cmn->xps[xp_base + x].dtc; + +if (dtc <0 ) +seq_puts (s," DTC ?? |" ); +else +seq_printf (s," DTC %d |" , dtc); + } +seq_puts (s,"\n |" ); +for (x =0 ; x < cmn->mesh_x; x++) +seq_puts (s,"........|" ); + +seq_puts (s,"\n 0 |" ); +for (x =0 ; x < cmn->mesh_x; x++) +seq_puts (s,arm_cmn_device_type (port[0 ][x])); +seq_puts (s,"\n 0|" ); +for (x =0 ; x < cmn->mesh_x; x++) +arm_cmn_show_logid (s, x, y,0 ,0 ); +seq_puts (s,"\n 1|" ); +for (x =0 ; x < cmn->mesh_x; x++) +arm_cmn_show_logid (s, x, y,0 ,1 ); + +seq_puts (s,"\n 1 |" ); +for (x =0 ; x < cmn->mesh_x; x++) +seq_puts (s,arm_cmn_device_type (port[1 ][x])); +seq_puts (s,"\n 0|" ); +for (x =0 ; x < cmn->mesh_x; x++) +arm_cmn_show_logid (s, x, y,1 ,0 ); +seq_puts (s,"\n 1|" ); +for (x =0 ; x < cmn->mesh_x; x++) +arm_cmn_show_logid (s, x, y,1 ,1 ); + +seq_puts (s,"\n-----+" ); + } +for (x =0 ; x < cmn->mesh_x; x++) +seq_puts (s,"--------+" ); +seq_puts (s,"\n" ); +return 0 ; +} +DEFINE_SHOW_ATTRIBUTE (arm_cmn_map); + +static void arm_cmn_debugfs_init (struct arm_cmn *cmn,int id) +{ +const char *name ="map" ; + +if (id >0 ) + name =devm_kasprintf (cmn->dev,GFP_KERNEL ,"map_%d" , id); +if (!name) +return ; + + cmn->debug =debugfs_create_file (name,0444 , arm_cmn_debugfs, cmn, &arm_cmn_map_fops); +} +#else +static void arm_cmn_debugfs_init (struct arm_cmn *cmn,int id) {} +#endif +struct arm_cmn_hw_event {struct arm_cmn_node *dn;
@@ -294,11 +439,6 @@ struct arm_cmn_format_attr {int config; }; -static int arm_cmn_xyidbits (const struct arm_cmn *cmn) -{ -return cmn->mesh_x >4 || cmn->mesh_y >4 ?3 :2 ; -} -static void arm_cmn_init_node_to_xp (const struct arm_cmn *cmn,struct arm_cmn_node *dn) {
@@ -1565,6 +1705,9 @@ static int arm_cmn_probe(struct platform_device *pdev) err =perf_pmu_register (&cmn->pmu, name,-1 );if (err)cpuhp_state_remove_instance (arm_cmn_hp_state, &cmn->cpuhp_node); +else +arm_cmn_debugfs_init (cmn, this_id); +return err; }
@@ -1581,6 +1724,7 @@ static int arm_cmn_remove(struct platform_device *pdev)for (i =0 ; i < cmn->num_dtcs; i++)irq_set_affinity_hint (cmn->dtc[i].irq,NULL ); +debugfs_remove (cmn->debug);return 0 ; }
@@ -1621,9 +1765,13 @@ static int __init arm_cmn_init(void)return ret; arm_cmn_hp_state = ret; + arm_cmn_debugfs =debugfs_create_dir ("arm-cmn" ,NULL ); + ret =platform_driver_register (&arm_cmn_driver); -if (ret) +if (ret) {cpuhp_remove_multi_state (arm_cmn_hp_state); +debugfs_remove (arm_cmn_debugfs); + }return ret; }
@@ -1631,6 +1779,7 @@ static void __exit arm_cmn_exit(void) {platform_driver_unregister (&arm_cmn_driver);cpuhp_remove_multi_state (arm_cmn_hp_state); +debugfs_remove (arm_cmn_debugfs); }module_init (arm_cmn_init);
Signature · 1 line
2.28.0.dirty
Quoted 6 lines · Robin Murphy
Here's an update with some very minor cleanup tweaks, plus a proposal for some more in-depth debug information. Given that nobody seems to have any significant complaints about the interface, I assume we're all happy to merge the basic driver as-is and fix anything later if needed.
Robin.
Agree with merging the driver as-is.
Tested both the updated driver and the debugfs on Graviton2 (ACPI). Both map and initial numbers seem right.
May I offer a small addition to the documentation? Something along these lines:
Documentation/admin-guide/perf/arm-cmn.rst +8 -2
@@ -41,8 +41,14 @@ specified by "occupid". By default each event provides an aggregate count over all nodes of the given type. To target a specific node, "bynodeid" must be set to 1 and -"nodeid" to the appropriate value derived from the CMN configuration -(as defined in the "Node ID Mapping" section of the TRM). +"nodeid" to the appropriate value derived from the CMN configuration. + +The CMN map is available in /sys/kernel/debug/arm-cmn/map. +A nodeid could be calculated with this formulae: + node-id = d | (p << 2) | (y << 3) | (x << (3 + xybits)) +where: + x,y,p,d are node location as can be seen in the map + xybits is 2 for meshes <= 2*2, and 3 otherwise. Watchpoints -----------
Will Deacon
maintainerQuoted 25 lines · Tsahi
Quoted 6 lines · Robin Murphy
Here's an update with some very minor cleanup tweaks, plus a proposal for some more in-depth debug information. Given that nobody seems to have any significant complaints about the interface, I assume we're all happy to merge the basic driver as-is and fix anything later if needed.
Robin.
Agree with merging the driver as-is.
Tested both the updated driver and the debugfs on Graviton2 (ACPI). Both map and initial numbers seem right.Tested-by Tsahi Zidenberg <[email protected]>May I offer a small addition to the documentation? Something along these lines:
Documentation/admin-guide/perf/arm-cmn.rst +0
-0@@ -41,8 +41,14 @@ specified by "occupid". By default each event provides an aggregate count over all nodes of the given type. To target a specific node, "bynodeid" must be set to 1 and
Documentation/admin-guide/perf/arm-cmn.rst specified by "occupid". · line 51
Quoted 10 lines
Documentation/admin-guide/perf/arm-cmn.rst +8
-2-"nodeid" to the appropriate value derived from the CMN configuration -(as defined in the "Node ID Mapping" section of the TRM). +"nodeid" to the appropriate value derived from the CMN configuration. + +The CMN map is available in /sys/kernel/debug/arm-cmn/map. +A nodeid could be calculated with this formulae: + node-id = d | (p << 2) | (y << 3) | (x << (3 + xybits)) +where: + x,y,p,d are node location as can be seen in the map + xybits is 2 for meshes <= 2*2, and 3 otherwise.
I already queued the driver, but if you send this as a stand-alone patch (on top of the arm64 for-next/perf branch) then I'm happy to take it.
Thanks,
Will
Quoted 3 lines
Documentation/admin-guide/perf/arm-cmn.rst +0
-0Watchpoints -----------
Robin Murphy
maintainerQuoted 24 lines · Will Deacon
Quoted 23 lines · Tsahi
On 18/09/2020, 16:29, "Robin Murphy" <[email protected]> wrote:
> Here's an update with some very minor cleanup tweaks, plus a proposal > for some more in-depth debug information. Given that nobody seems to > have any significant complaints about the interface, I assume we're all > happy to merge the basic driver as-is and fix anything later if needed. >
> Robin.Agree with merging the driver as-is.
Tested both the updated driver and the debugfs on Graviton2 (ACPI). Both map and initial numbers seem right.Tested-by Tsahi Zidenberg <[email protected]>May I offer a small addition to the documentation? Something along these lines:
Documentation/admin-guide/perf/arm-cmn.rst +0
-0@@ -41,8 +41,14 @@ specified by "occupid".
Quoted 12 lines
Documentation/admin-guide/perf/arm-cmn.rst specified by "occupid". · line 51
Quoted 12 lines
Documentation/admin-guide/perf/arm-cmn.rst +8
-2By default each event provides an aggregate count over all nodes of the given type. To target a specific node, "bynodeid" must be set to 1 and -"nodeid" to the appropriate value derived from the CMN configuration -(as defined in the "Node ID Mapping" section of the TRM). +"nodeid" to the appropriate value derived from the CMN configuration. + +The CMN map is available in /sys/kernel/debug/arm-cmn/map. +A nodeid could be calculated with this formulae: + node-id = d | (p << 2) | (y << 3) | (x << (3 + xybits)) +where: + x,y,p,d are node location as can be seen in the map + xybits is 2 for meshes <= 2*2, and 3 otherwise.
Note that I disagree strongly with removing the reference to the documentation that canonically defines the node ID format, especially when the proposal is to replace it with a harder-to-read definition that is also wrong ;)
If there's actually interest in using the coordinate format rather than just whole ID values, then we should generate format attributes that overlay the appropriate sections of the nodeid field. I haven't tried to implement that so far since it's not entirely trivial and I wasn't sure if anyone would care.
Quoted 2 lines
I already queued the driver, but if you send this as a stand-alone patch (on top of the arm64 for-next/perf branch) then I'm happy to take it.
Ha, so much for taking my holiday after -rc6 and expecting to come back to chasing this up at -rc1... cheers Will, that was a very nice surprise to return to!
Robin.
Quoted 10 lines · Robin Murphy
Quoted 9 lines · Tsahi
By default each event provides an aggregate count over all nodes of the given type. To target a specific node, "bynodeid" must be set to 1 and
-"nodeid" to the appropriate value derived from the CMN configurationDocumentation/admin-guide/perf/arm-cmn.rst +5
-1-(as defined in the "Node ID Mapping" section of the TRM). +"nodeid" to the appropriate value derived from the CMN configuration. + +The CMN map is available in /sys/kernel/debug/arm-cmn/map. +A nodeid could be calculated with this formulae: + node-id = d | (p << 2) | (y << 3) | (x << (3 + xybits))
Quoted 8 lines
Documentation/admin-guide/perf/arm-cmn.rst specified by "occupid". · line 51
Quoted 3 lines
Documentation/admin-guide/perf/arm-cmn.rst +3
-0+where: + x,y,p,d are node location as can be seen in the map + xybits is 2 for meshes <= 2*2, and 3 otherwise.Note that I disagree strongly with removing the reference to the documentation that canonically defines the node ID format, especially when the proposal is to replace it with a harder-to-read definition that is also wrong ;)
Would be happy to be corrected :)
Quoted 5 lines
If there's actually interest in using the coordinate format rather than just whole ID values, then we should generate format attributes that overlay the appropriate sections of the nodeid field. I haven't tried to implement that so far since it's not entirely trivial and I wasn't sure if anyone would care.
I agree that over 90% of the work with the counters should be with aggregate values that the driver already handles well by default.
At the next level, there might be a lot to gain from just understanding if the counter in question is going up across the board, or just for a specific node. Are there a lot of HNF cache misses in the system, or from one specific HNF? To answer that question, the developer doesn't need to hold the SOC SPEC, just to have the list of relevant node-ids per type/counter.
I really like the arm-cmn/map you created. There is still a small missing link between that map to relevant node-ids for the above. In my opinion, looking at specific node-ids would be a rare enough task, requiring enough expertise, that I am comfortable putting a formulae in documentation without actually modifying API, at least at this stage.
Thank you!
Tsahi.