Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame] | 1 | From 118a6499d8c5d940210c6543309addc97b48122c Mon Sep 17 00:00:00 2001 |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 2 | From: Robin Murphy <robin.murphy@arm.com> |
| 3 | Date: Fri, 3 Dec 2021 11:44:58 +0000 |
Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame] | 4 | Subject: [PATCH 23/40] perf/arm-cmn: Move group validation data off-stack |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 5 | |
| 6 | With the value of CMN_MAX_DTMS increasing significantly, our validation |
| 7 | data structure is set to get quite big. Technically we could pack it at |
| 8 | least twice as densely, since we only need around 19 bits of information |
| 9 | per DTM, but that makes the code even more mind-bogglingly impenetrable, |
| 10 | and even half of "quite big" may still be uncomfortably large for a |
| 11 | stack frame (~1KB). Just move it to an off-stack allocation instead. |
| 12 | |
| 13 | Signed-off-by: Robin Murphy <robin.murphy@arm.com> |
| 14 | Link: https://lore.kernel.org/r/0cabff2e5839ddc0979e757c55515966f65359e4.1638530442.git.robin.murphy@arm.com |
| 15 | Signed-off-by: Will Deacon <will@kernel.org> |
| 16 | |
| 17 | Upstream-Status: Backport [https://lore.kernel.org/r/0cabff2e5839ddc0979e757c55515966f65359e4.1638530442.git.robin.murphy@arm.com] |
| 18 | Signed-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 | |
| 23 | diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c |
Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame] | 24 | index acff8683af2c..d2dd02f040b8 100644 |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 25 | --- 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 Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame] | 107 | 2.34.1 |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 108 | |