UPSTREAM: 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. Bug: 247832918 Change-Id: I6c17e17bf3279ead000abf11947cfa71a1e820bf 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> (cherry picked from commit 4f2c3872dde55090bf39e1f12a8517a32b6cd048) Signed-off-by: Robin Peng <robinpeng@google.com>
This commit is contained in:
committed by
Treehugger Robot
parent
fb9091356e
commit
9a74f34abd
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user