blob: 93a801bc653981ad76f66cd1c9a8b82b26cca114 [file] [log] [blame]
Patrick Williams2194f502022-10-16 14:26:09 -05001From 1cf0522e9b4cdad7609c6ce31e848c3d8f2932d5 Mon Sep 17 00:00:00 2001
Brad Bishopbec4ebc2022-08-03 09:55:16 -04002From: Robin Murphy <robin.murphy@arm.com>
3Date: Fri, 3 Dec 2021 11:44:57 +0000
Patrick Williams2194f502022-10-16 14:26:09 -05004Subject: [PATCH 22/40] perf/arm-cmn: Optimise DTC counter accesses
Brad Bishopbec4ebc2022-08-03 09:55:16 -04005
6In cases where we do know which DTC domain a node belongs to, we can
7skip initialising or reading the global count in DTCs where we know
8it won't change. The machinery to achieve that is mostly in place
9already, so finish hooking it up by converting the vestigial domain
10tracking to propagate suitable bitmaps all the way through to events.
11
12Note that this does not allow allocating such an unused counter to a
13different event on that DTC, because that is a flippin' nightmare.
14
15Signed-off-by: Robin Murphy <robin.murphy@arm.com>
16Link: https://lore.kernel.org/r/51d930fd945ef51c81f5889ccca055c302b0a1d0.1638530442.git.robin.murphy@arm.com
17Signed-off-by: Will Deacon <will@kernel.org>
18
19Upstream-Status: Backport [https://lore.kernel.org/r/51d930fd945ef51c81f5889ccca055c302b0a1d0.1638530442.git.robin.murphy@arm.com]
20Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com>
21---
22 drivers/perf/arm-cmn.c | 29 ++++++++++++-----------------
23 1 file changed, 12 insertions(+), 17 deletions(-)
24
25diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
Patrick Williams2194f502022-10-16 14:26:09 -050026index 005a0d83bcac..acff8683af2c 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -040027--- a/drivers/perf/arm-cmn.c
28+++ b/drivers/perf/arm-cmn.c
29@@ -193,7 +193,7 @@ struct arm_cmn_node {
30 u8 occupid_count;
31 };
32 /* XP */
33- int dtc;
34+ u8 dtc;
35 };
36 union {
37 u8 event[4];
38@@ -968,14 +968,14 @@ static int arm_cmn_event_init(struct perf_event *event)
39 if (!hw->dn)
40 return -EINVAL;
41 for (dn = hw->dn; dn->type == type; dn++) {
42- if (!bynodeid) {
43- hw->num_dns++;
44- } else if (dn->id != nodeid) {
45+ if (bynodeid && dn->id != nodeid) {
46 hw->dn++;
47- } else {
48- hw->num_dns = 1;
49- break;
50+ continue;
51 }
52+ hw->dtcs_used |= arm_cmn_node_to_xp(cmn, dn)->dtc;
53+ hw->num_dns++;
54+ if (bynodeid)
55+ break;
56 }
57
58 if (!hw->num_dns) {
59@@ -985,11 +985,6 @@ static int arm_cmn_event_init(struct perf_event *event)
60 nodeid, nid.x, nid.y, nid.port, nid.dev, type);
61 return -EINVAL;
62 }
63- /*
64- * By assuming events count in all DTC domains, we cunningly avoid
65- * needing to know anything about how XPs are assigned to domains.
66- */
67- hw->dtcs_used = (1U << cmn->num_dtcs) - 1;
68
69 return arm_cmn_validate_group(event);
70 }
71@@ -1311,6 +1306,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
72 {
73 struct arm_cmn_node *dn, *xp;
74 int dtc_idx = 0;
75+ u8 dtcs_present = (1 << cmn->num_dtcs) - 1;
76
77 cmn->dtc = devm_kcalloc(cmn->dev, cmn->num_dtcs, sizeof(cmn->dtc[0]), GFP_KERNEL);
78 if (!cmn->dtc)
79@@ -1322,8 +1318,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
80
81 for (dn = cmn->dns; dn->type; dn++) {
82 if (dn->type == CMN_TYPE_XP) {
83- if (dn->dtc < 0 && cmn->num_dtcs == 1)
84- dn->dtc = 0;
85+ dn->dtc &= dtcs_present;
86 continue;
87 }
88
89@@ -1333,8 +1328,8 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
90 if (dn->type == CMN_TYPE_DTC) {
91 int err;
92 /* We do at least know that a DTC's XP must be in that DTC's domain */
93- if (xp->dtc < 0)
94- xp->dtc = dtc_idx;
95+ if (xp->dtc == 0xf)
96+ xp->dtc = 1 << dtc_idx;
97 err = arm_cmn_init_dtc(cmn, dn, dtc_idx++);
98 if (err)
99 return err;
100@@ -1435,7 +1430,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
101 if (xp->id == (1 << 3))
102 cmn->mesh_x = xp->logid;
103
104- xp->dtc = -1;
105+ xp->dtc = 0xf;
106 xp->dtm = dtm - cmn->dtms;
107 arm_cmn_init_dtm(dtm++, xp);
108
109--
Patrick Williams2194f502022-10-16 14:26:09 -05001102.34.1
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400111