blob: b251779c2767a1be4d9150ca69e2edceae5e9dc5 [file] [log] [blame]
Patrick Williams2194f502022-10-16 14:26:09 -05001From 118a6499d8c5d940210c6543309addc97b48122c 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:58 +0000
Patrick Williams2194f502022-10-16 14:26:09 -05004Subject: [PATCH 23/40] perf/arm-cmn: Move group validation data off-stack
Brad Bishopbec4ebc2022-08-03 09:55:16 -04005
6With the value of CMN_MAX_DTMS increasing significantly, our validation
7data structure is set to get quite big. Technically we could pack it at
8least twice as densely, since we only need around 19 bits of information
9per DTM, but that makes the code even more mind-bogglingly impenetrable,
10and even half of "quite big" may still be uncomfortably large for a
11stack frame (~1KB). Just move it to an off-stack allocation instead.
12
13Signed-off-by: Robin Murphy <robin.murphy@arm.com>
14Link: https://lore.kernel.org/r/0cabff2e5839ddc0979e757c55515966f65359e4.1638530442.git.robin.murphy@arm.com
15Signed-off-by: Will Deacon <will@kernel.org>
16
17Upstream-Status: Backport [https://lore.kernel.org/r/0cabff2e5839ddc0979e757c55515966f65359e4.1638530442.git.robin.murphy@arm.com]
18Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com>
19---
20 drivers/perf/arm-cmn.c | 43 ++++++++++++++++++++++++------------------
21 1 file changed, 25 insertions(+), 18 deletions(-)
22
23diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
Patrick Williams2194f502022-10-16 14:26:09 -050024index acff8683af2c..d2dd02f040b8 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -040025--- a/drivers/perf/arm-cmn.c
26+++ b/drivers/perf/arm-cmn.c
27@@ -876,8 +876,8 @@ static int arm_cmn_validate_group(struct perf_event *event)
28 struct arm_cmn_node *dn;
29 struct perf_event *sibling, *leader = event->group_leader;
30 enum cmn_node_type type;
31- struct arm_cmn_val val;
32- int i;
33+ struct arm_cmn_val *val;
34+ int i, ret = -EINVAL;
35 u8 occupid;
36
37 if (leader == event)
38@@ -886,18 +886,22 @@ static int arm_cmn_validate_group(struct perf_event *event)
39 if (event->pmu != leader->pmu && !is_software_event(leader))
40 return -EINVAL;
41
42- memset(&val, 0, sizeof(val));
43+ val = kzalloc(sizeof(*val), GFP_KERNEL);
44+ if (!val)
45+ return -ENOMEM;
46
47- arm_cmn_val_add_event(&val, leader);
48+ arm_cmn_val_add_event(val, leader);
49 for_each_sibling_event(sibling, leader)
50- arm_cmn_val_add_event(&val, sibling);
51+ arm_cmn_val_add_event(val, sibling);
52
53 type = CMN_EVENT_TYPE(event);
54- if (type == CMN_TYPE_DTC)
55- return val.cycles ? -EINVAL : 0;
56+ if (type == CMN_TYPE_DTC) {
57+ ret = val->cycles ? -EINVAL : 0;
58+ goto done;
59+ }
60
61- if (val.dtc_count == CMN_DT_NUM_COUNTERS)
62- return -EINVAL;
63+ if (val->dtc_count == CMN_DT_NUM_COUNTERS)
64+ goto done;
65
66 if (arm_cmn_is_occup_event(type, CMN_EVENT_EVENTID(event)))
67 occupid = CMN_EVENT_OCCUPID(event) + 1;
68@@ -907,25 +911,28 @@ static int arm_cmn_validate_group(struct perf_event *event)
69 for_each_hw_dn(hw, dn, i) {
70 int wp_idx, wp_cmb, dtm = dn->dtm;
71
72- if (val.dtm_count[dtm] == CMN_DTM_NUM_COUNTERS)
73- return -EINVAL;
74+ if (val->dtm_count[dtm] == CMN_DTM_NUM_COUNTERS)
75+ goto done;
76
77- if (occupid && val.occupid[dtm] && occupid != val.occupid[dtm])
78- return -EINVAL;
79+ if (occupid && val->occupid[dtm] && occupid != val->occupid[dtm])
80+ goto done;
81
82 if (type != CMN_TYPE_WP)
83 continue;
84
85 wp_idx = arm_cmn_wp_idx(event);
86- if (val.wp[dtm][wp_idx])
87- return -EINVAL;
88+ if (val->wp[dtm][wp_idx])
89+ goto done;
90
91- wp_cmb = val.wp[dtm][wp_idx ^ 1];
92+ wp_cmb = val->wp[dtm][wp_idx ^ 1];
93 if (wp_cmb && wp_cmb != CMN_EVENT_WP_COMBINE(event) + 1)
94- return -EINVAL;
95+ goto done;
96 }
97
98- return 0;
99+ ret = 0;
100+done:
101+ kfree(val);
102+ return ret;
103 }
104
105 static int arm_cmn_event_init(struct perf_event *event)
106--
Patrick Williams2194f502022-10-16 14:26:09 -05001072.34.1
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400108