diff options
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0019-perf-arm-cmn-Streamline-node-iteration.patch')
-rw-r--r-- | meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0019-perf-arm-cmn-Streamline-node-iteration.patch | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0019-perf-arm-cmn-Streamline-node-iteration.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0019-perf-arm-cmn-Streamline-node-iteration.patch new file mode 100644 index 0000000000..2fd7ba4c93 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0019-perf-arm-cmn-Streamline-node-iteration.patch @@ -0,0 +1,118 @@ +From ca15b67dc746c13a8231d11a3e2925f128982a7d Mon Sep 17 00:00:00 2001 +From: Robin Murphy <robin.murphy@arm.com> +Date: Fri, 3 Dec 2021 11:44:54 +0000 +Subject: [PATCH 19/40] perf/arm-cmn: Streamline node iteration + +Refactor the places where we scan through the set of nodes to switch +from explicit array indexing to pointer-based iteration. This leads to +slightly simpler object code, but also makes the source less dense and +more pleasant for further development. It also unearths an almost-bug +in arm_cmn_event_init() where we've been depending on the "array index" +of NULL relative to cmn->dns being a sufficiently large number, yuck. + +Signed-off-by: Robin Murphy <robin.murphy@arm.com> +Link: https://lore.kernel.org/r/ee0c9eda9a643f46001ac43aadf3f0b1fd5660dd.1638530442.git.robin.murphy@arm.com +Signed-off-by: Will Deacon <will@kernel.org> + +Upstream-Status: Backport [https://lore.kernel.org/r/ee0c9eda9a643f46001ac43aadf3f0b1fd5660dd.1638530442.git.robin.murphy@arm.com] +Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com> +--- + drivers/perf/arm-cmn.c | 33 ++++++++++++++++++++------------- + 1 file changed, 20 insertions(+), 13 deletions(-) + +diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c +index adf50d613734..da7bf779fec2 100644 +--- a/drivers/perf/arm-cmn.c ++++ b/drivers/perf/arm-cmn.c +@@ -299,11 +299,11 @@ static struct arm_cmn_node *arm_cmn_node_to_xp(struct arm_cmn_node *dn) + static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn, + enum cmn_node_type type) + { +- int i; ++ struct arm_cmn_node *dn; + +- for (i = 0; i < cmn->num_dns; i++) +- if (cmn->dns[i].type == type) +- return &cmn->dns[i]; ++ for (dn = cmn->dns; dn->type; dn++) ++ if (dn->type == type) ++ return dn; + return NULL; + } + +@@ -941,8 +941,8 @@ static int arm_cmn_event_init(struct perf_event *event) + { + struct arm_cmn *cmn = to_cmn(event->pmu); + struct arm_cmn_hw_event *hw = to_cmn_hw(event); ++ struct arm_cmn_node *dn; + enum cmn_node_type type; +- unsigned int i; + bool bynodeid; + u16 nodeid, eventid; + +@@ -974,10 +974,12 @@ static int arm_cmn_event_init(struct perf_event *event) + nodeid = CMN_EVENT_NODEID(event); + + hw->dn = arm_cmn_node(cmn, type); +- for (i = hw->dn - cmn->dns; i < cmn->num_dns && cmn->dns[i].type == type; i++) { ++ if (!hw->dn) ++ return -EINVAL; ++ for (dn = hw->dn; dn->type == type; dn++) { + if (!bynodeid) { + hw->num_dns++; +- } else if (cmn->dns[i].id != nodeid) { ++ } else if (dn->id != nodeid) { + hw->dn++; + } else { + hw->num_dns = 1; +@@ -1332,7 +1334,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn) + + cmn->xps = arm_cmn_node(cmn, CMN_TYPE_XP); + +- for (dn = cmn->dns; dn < cmn->dns + cmn->num_dns; dn++) { ++ for (dn = cmn->dns; dn->type; dn++) { + if (dn->type != CMN_TYPE_XP) + arm_cmn_init_node_to_xp(cmn, dn); + else if (cmn->num_dtcs == 1) +@@ -1382,6 +1384,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) + u32 xp_offset[CMN_MAX_XPS]; + u64 reg; + int i, j; ++ size_t sz; + + cfg_region = cmn->base + rgn_offset; + reg = readl_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_2); +@@ -1408,14 +1411,13 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) + cmn->num_dns += FIELD_GET(CMN_CI_CHILD_COUNT, reg); + } + +- /* Cheeky +1 to help terminate pointer-based iteration */ +- cmn->dns = devm_kcalloc(cmn->dev, cmn->num_dns + 1, +- sizeof(*cmn->dns), GFP_KERNEL); +- if (!cmn->dns) ++ /* Cheeky +1 to help terminate pointer-based iteration later */ ++ dn = devm_kcalloc(cmn->dev, cmn->num_dns + 1, sizeof(*dn), GFP_KERNEL); ++ if (!dn) + return -ENOMEM; + + /* Pass 2: now we can actually populate the nodes */ +- dn = cmn->dns; ++ cmn->dns = dn; + for (i = 0; i < cmn->num_xps; i++) { + void __iomem *xp_region = cmn->base + xp_offset[i]; + struct arm_cmn_node *xp = dn++; +@@ -1484,6 +1486,11 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) + /* Correct for any nodes we skipped */ + cmn->num_dns = dn - cmn->dns; + ++ sz = (void *)(dn + 1) - (void *)cmn->dns; ++ dn = devm_krealloc(cmn->dev, cmn->dns, sz, GFP_KERNEL); ++ if (dn) ++ cmn->dns = dn; ++ + /* + * If mesh_x wasn't set during discovery then we never saw + * an XP at (0,1), thus we must have an Nx1 configuration. +-- +2.34.1 + |