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