| From 782b7cd98e6a6b8c5fcd9e20f5c534617b1f04d3 Mon Sep 17 00:00:00 2001 |
| From: Robin Murphy <robin.murphy@arm.com> |
| Date: Fri, 3 Dec 2021 11:44:57 +0000 |
| Subject: [PATCH 10/14] perf/arm-cmn: Optimise DTC counter accesses |
| |
| In cases where we do know which DTC domain a node belongs to, we can |
| skip initialising or reading the global count in DTCs where we know |
| it won't change. The machinery to achieve that is mostly in place |
| already, so finish hooking it up by converting the vestigial domain |
| tracking to propagate suitable bitmaps all the way through to events. |
| |
| Note that this does not allow allocating such an unused counter to a |
| different event on that DTC, because that is a flippin' nightmare. |
| |
| Signed-off-by: Robin Murphy <robin.murphy@arm.com> |
| Link: https://lore.kernel.org/r/51d930fd945ef51c81f5889ccca055c302b0a1d0.1638530442.git.robin.murphy@arm.com |
| Signed-off-by: Will Deacon <will@kernel.org> |
| |
| Upstream-Status: Backport [https://lore.kernel.org/r/51d930fd945ef51c81f5889ccca055c302b0a1d0.1638530442.git.robin.murphy@arm.com] |
| Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com> |
| --- |
| drivers/perf/arm-cmn.c | 29 ++++++++++++----------------- |
| 1 file changed, 12 insertions(+), 17 deletions(-) |
| |
| diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c |
| index 5fa31ebc1fce..2204d6500814 100644 |
| --- a/drivers/perf/arm-cmn.c |
| +++ b/drivers/perf/arm-cmn.c |
| @@ -193,7 +193,7 @@ struct arm_cmn_node { |
| u8 occupid_count; |
| }; |
| /* XP */ |
| - int dtc; |
| + u8 dtc; |
| }; |
| union { |
| u8 event[4]; |
| @@ -968,14 +968,14 @@ static int arm_cmn_event_init(struct perf_event *event) |
| if (!hw->dn) |
| return -EINVAL; |
| for (dn = hw->dn; dn->type == type; dn++) { |
| - if (!bynodeid) { |
| - hw->num_dns++; |
| - } else if (dn->id != nodeid) { |
| + if (bynodeid && dn->id != nodeid) { |
| hw->dn++; |
| - } else { |
| - hw->num_dns = 1; |
| - break; |
| + continue; |
| } |
| + hw->dtcs_used |= arm_cmn_node_to_xp(cmn, dn)->dtc; |
| + hw->num_dns++; |
| + if (bynodeid) |
| + break; |
| } |
| |
| if (!hw->num_dns) { |
| @@ -985,11 +985,6 @@ static int arm_cmn_event_init(struct perf_event *event) |
| nodeid, nid.x, nid.y, nid.port, nid.dev, type); |
| return -EINVAL; |
| } |
| - /* |
| - * By assuming events count in all DTC domains, we cunningly avoid |
| - * needing to know anything about how XPs are assigned to domains. |
| - */ |
| - hw->dtcs_used = (1U << cmn->num_dtcs) - 1; |
| |
| return arm_cmn_validate_group(event); |
| } |
| @@ -1311,6 +1306,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn) |
| { |
| struct arm_cmn_node *dn, *xp; |
| int dtc_idx = 0; |
| + u8 dtcs_present = (1 << cmn->num_dtcs) - 1; |
| |
| cmn->dtc = devm_kcalloc(cmn->dev, cmn->num_dtcs, sizeof(cmn->dtc[0]), GFP_KERNEL); |
| if (!cmn->dtc) |
| @@ -1322,8 +1318,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn) |
| |
| for (dn = cmn->dns; dn->type; dn++) { |
| if (dn->type == CMN_TYPE_XP) { |
| - if (dn->dtc < 0 && cmn->num_dtcs == 1) |
| - dn->dtc = 0; |
| + dn->dtc &= dtcs_present; |
| continue; |
| } |
| |
| @@ -1333,8 +1328,8 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn) |
| if (dn->type == CMN_TYPE_DTC) { |
| int err; |
| /* We do at least know that a DTC's XP must be in that DTC's domain */ |
| - if (xp->dtc < 0) |
| - xp->dtc = dtc_idx; |
| + if (xp->dtc == 0xf) |
| + xp->dtc = 1 << dtc_idx; |
| err = arm_cmn_init_dtc(cmn, dn, dtc_idx++); |
| if (err) |
| return err; |
| @@ -1435,7 +1430,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) |
| if (xp->id == (1 << 3)) |
| cmn->mesh_x = xp->logid; |
| |
| - xp->dtc = -1; |
| + xp->dtc = 0xf; |
| xp->dtm = dtm - cmn->dtms; |
| arm_cmn_init_dtm(dtm++, xp); |
| |
| -- |
| 2.25.1 |
| |