All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robin Murphy <robin.murphy@arm.com>
To: will@kernel.org
Cc: mark.rutland@arm.com, linux-arm-kernel@lists.infradead.org
Subject: [PATCH 05/14] perf/arm-cmn: Streamline node iteration
Date: Fri,  3 Dec 2021 11:44:54 +0000	[thread overview]
Message-ID: <ee0c9eda9a643f46001ac43aadf3f0b1fd5660dd.1638530442.git.robin.murphy@arm.com> (raw)
In-Reply-To: <cover.1638530442.git.robin.murphy@arm.com>

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>
---
 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.28.0.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2021-12-03 11:49 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-03 11:44 [PATCH 00/14] perf: Arm CMN updates Robin Murphy
2021-12-03 11:44 ` [PATCH 01/14] perf/arm-cmn: Fix CPU hotplug unregistration Robin Murphy
2021-12-03 11:44 ` [PATCH 02/14] perf/arm-cmn: Account for NUMA affinity Robin Murphy
2021-12-03 11:44 ` [PATCH 03/14] perf/arm-cmn: Drop compile-test restriction Robin Murphy
2021-12-03 11:44 ` [PATCH 04/14] perf/arm-cmn: Refactor node ID handling Robin Murphy
2021-12-03 11:44 ` Robin Murphy [this message]
2021-12-03 11:44 ` [PATCH 06/14] perf/arm-cmn: Refactor DTM handling Robin Murphy
2021-12-03 11:44 ` [PATCH 07/14] perf/arm-cmn: Optimise DTM counter reads Robin Murphy
2021-12-03 11:44 ` [PATCH 08/14] perf/arm-cmn: Optimise DTC counter accesses Robin Murphy
2021-12-03 11:44 ` [PATCH 09/14] perf/arm-cmn: Move group validation data off-stack Robin Murphy
2021-12-03 11:44 ` [PATCH 10/14] perf/arm-cmn: Demarcate CMN-600 specifics Robin Murphy
2021-12-03 11:45 ` [PATCH 11/14] perf/arm-cmn: Support new IP features Robin Murphy
2021-12-03 11:45 ` [PATCH 12/14] dt-bindings: perf: arm-cmn: Add CI-700 Robin Murphy
2021-12-03 11:45   ` Robin Murphy
2021-12-03 23:34   ` Rob Herring
2021-12-03 23:34     ` Rob Herring
2021-12-03 11:45 ` [PATCH 13/14] perf/arm-cmn: Add CI-700 Support Robin Murphy
2021-12-03 11:45 ` [PATCH 14/14] perf/arm-cmn: Add debugfs topology info Robin Murphy
2021-12-14 14:04 ` [PATCH 00/14] perf: Arm CMN updates Will Deacon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ee0c9eda9a643f46001ac43aadf3f0b1fd5660dd.1638530442.git.robin.murphy@arm.com \
    --to=robin.murphy@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.