Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame^] | 1 | From ca15b67dc746c13a8231d11a3e2925f128982a7d 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:54 +0000 |
Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame^] | 4 | Subject: [PATCH 19/40] perf/arm-cmn: Streamline node iteration |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 5 | |
| 6 | Refactor the places where we scan through the set of nodes to switch |
| 7 | from explicit array indexing to pointer-based iteration. This leads to |
| 8 | slightly simpler object code, but also makes the source less dense and |
| 9 | more pleasant for further development. It also unearths an almost-bug |
| 10 | in arm_cmn_event_init() where we've been depending on the "array index" |
| 11 | of NULL relative to cmn->dns being a sufficiently large number, yuck. |
| 12 | |
| 13 | Signed-off-by: Robin Murphy <robin.murphy@arm.com> |
| 14 | Link: https://lore.kernel.org/r/ee0c9eda9a643f46001ac43aadf3f0b1fd5660dd.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/ee0c9eda9a643f46001ac43aadf3f0b1fd5660dd.1638530442.git.robin.murphy@arm.com] |
| 18 | Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com> |
| 19 | --- |
| 20 | drivers/perf/arm-cmn.c | 33 ++++++++++++++++++++------------- |
| 21 | 1 file changed, 20 insertions(+), 13 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 adf50d613734..da7bf779fec2 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 | @@ -299,11 +299,11 @@ static struct arm_cmn_node *arm_cmn_node_to_xp(struct arm_cmn_node *dn) |
| 28 | static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn, |
| 29 | enum cmn_node_type type) |
| 30 | { |
| 31 | - int i; |
| 32 | + struct arm_cmn_node *dn; |
| 33 | |
| 34 | - for (i = 0; i < cmn->num_dns; i++) |
| 35 | - if (cmn->dns[i].type == type) |
| 36 | - return &cmn->dns[i]; |
| 37 | + for (dn = cmn->dns; dn->type; dn++) |
| 38 | + if (dn->type == type) |
| 39 | + return dn; |
| 40 | return NULL; |
| 41 | } |
| 42 | |
| 43 | @@ -941,8 +941,8 @@ static int arm_cmn_event_init(struct perf_event *event) |
| 44 | { |
| 45 | struct arm_cmn *cmn = to_cmn(event->pmu); |
| 46 | struct arm_cmn_hw_event *hw = to_cmn_hw(event); |
| 47 | + struct arm_cmn_node *dn; |
| 48 | enum cmn_node_type type; |
| 49 | - unsigned int i; |
| 50 | bool bynodeid; |
| 51 | u16 nodeid, eventid; |
| 52 | |
| 53 | @@ -974,10 +974,12 @@ static int arm_cmn_event_init(struct perf_event *event) |
| 54 | nodeid = CMN_EVENT_NODEID(event); |
| 55 | |
| 56 | hw->dn = arm_cmn_node(cmn, type); |
| 57 | - for (i = hw->dn - cmn->dns; i < cmn->num_dns && cmn->dns[i].type == type; i++) { |
| 58 | + if (!hw->dn) |
| 59 | + return -EINVAL; |
| 60 | + for (dn = hw->dn; dn->type == type; dn++) { |
| 61 | if (!bynodeid) { |
| 62 | hw->num_dns++; |
| 63 | - } else if (cmn->dns[i].id != nodeid) { |
| 64 | + } else if (dn->id != nodeid) { |
| 65 | hw->dn++; |
| 66 | } else { |
| 67 | hw->num_dns = 1; |
| 68 | @@ -1332,7 +1334,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn) |
| 69 | |
| 70 | cmn->xps = arm_cmn_node(cmn, CMN_TYPE_XP); |
| 71 | |
| 72 | - for (dn = cmn->dns; dn < cmn->dns + cmn->num_dns; dn++) { |
| 73 | + for (dn = cmn->dns; dn->type; dn++) { |
| 74 | if (dn->type != CMN_TYPE_XP) |
| 75 | arm_cmn_init_node_to_xp(cmn, dn); |
| 76 | else if (cmn->num_dtcs == 1) |
| 77 | @@ -1382,6 +1384,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) |
| 78 | u32 xp_offset[CMN_MAX_XPS]; |
| 79 | u64 reg; |
| 80 | int i, j; |
| 81 | + size_t sz; |
| 82 | |
| 83 | cfg_region = cmn->base + rgn_offset; |
| 84 | reg = readl_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_2); |
| 85 | @@ -1408,14 +1411,13 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) |
| 86 | cmn->num_dns += FIELD_GET(CMN_CI_CHILD_COUNT, reg); |
| 87 | } |
| 88 | |
| 89 | - /* Cheeky +1 to help terminate pointer-based iteration */ |
| 90 | - cmn->dns = devm_kcalloc(cmn->dev, cmn->num_dns + 1, |
| 91 | - sizeof(*cmn->dns), GFP_KERNEL); |
| 92 | - if (!cmn->dns) |
| 93 | + /* Cheeky +1 to help terminate pointer-based iteration later */ |
| 94 | + dn = devm_kcalloc(cmn->dev, cmn->num_dns + 1, sizeof(*dn), GFP_KERNEL); |
| 95 | + if (!dn) |
| 96 | return -ENOMEM; |
| 97 | |
| 98 | /* Pass 2: now we can actually populate the nodes */ |
| 99 | - dn = cmn->dns; |
| 100 | + cmn->dns = dn; |
| 101 | for (i = 0; i < cmn->num_xps; i++) { |
| 102 | void __iomem *xp_region = cmn->base + xp_offset[i]; |
| 103 | struct arm_cmn_node *xp = dn++; |
| 104 | @@ -1484,6 +1486,11 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) |
| 105 | /* Correct for any nodes we skipped */ |
| 106 | cmn->num_dns = dn - cmn->dns; |
| 107 | |
| 108 | + sz = (void *)(dn + 1) - (void *)cmn->dns; |
| 109 | + dn = devm_krealloc(cmn->dev, cmn->dns, sz, GFP_KERNEL); |
| 110 | + if (dn) |
| 111 | + cmn->dns = dn; |
| 112 | + |
| 113 | /* |
| 114 | * If mesh_x wasn't set during discovery then we never saw |
| 115 | * an XP at (0,1), thus we must have an Nx1 configuration. |
| 116 | -- |
Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame^] | 117 | 2.34.1 |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 118 | |