Skip to content

Commit 558a078

Browse files
rmurphy-armwilldeacon
authored andcommitted
perf/arm-cmn: Move group validation data off-stack
With the value of CMN_MAX_DTMS increasing significantly, our validation data structure is set to get quite big. Technically we could pack it at least twice as densely, since we only need around 19 bits of information per DTM, but that makes the code even more mind-bogglingly impenetrable, and even half of "quite big" may still be uncomfortably large for a stack frame (~1KB). Just move it to an off-stack allocation instead. Signed-off-by: Robin Murphy <[email protected]> Link: https://lore.kernel.org/r/0cabff2e5839ddc0979e757c55515966f65359e4.1638530442.git.robin.murphy@arm.com Signed-off-by: Will Deacon <[email protected]>
1 parent 4f2c387 commit 558a078

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

drivers/perf/arm-cmn.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -876,8 +876,8 @@ static int arm_cmn_validate_group(struct perf_event *event)
876876
struct arm_cmn_node *dn;
877877
struct perf_event *sibling, *leader = event->group_leader;
878878
enum cmn_node_type type;
879-
struct arm_cmn_val val;
880-
int i;
879+
struct arm_cmn_val *val;
880+
int i, ret = -EINVAL;
881881
u8 occupid;
882882

883883
if (leader == event)
@@ -886,18 +886,22 @@ static int arm_cmn_validate_group(struct perf_event *event)
886886
if (event->pmu != leader->pmu && !is_software_event(leader))
887887
return -EINVAL;
888888

889-
memset(&val, 0, sizeof(val));
889+
val = kzalloc(sizeof(*val), GFP_KERNEL);
890+
if (!val)
891+
return -ENOMEM;
890892

891-
arm_cmn_val_add_event(&val, leader);
893+
arm_cmn_val_add_event(val, leader);
892894
for_each_sibling_event(sibling, leader)
893-
arm_cmn_val_add_event(&val, sibling);
895+
arm_cmn_val_add_event(val, sibling);
894896

895897
type = CMN_EVENT_TYPE(event);
896-
if (type == CMN_TYPE_DTC)
897-
return val.cycles ? -EINVAL : 0;
898+
if (type == CMN_TYPE_DTC) {
899+
ret = val->cycles ? -EINVAL : 0;
900+
goto done;
901+
}
898902

899-
if (val.dtc_count == CMN_DT_NUM_COUNTERS)
900-
return -EINVAL;
903+
if (val->dtc_count == CMN_DT_NUM_COUNTERS)
904+
goto done;
901905

902906
if (arm_cmn_is_occup_event(type, CMN_EVENT_EVENTID(event)))
903907
occupid = CMN_EVENT_OCCUPID(event) + 1;
@@ -907,25 +911,28 @@ static int arm_cmn_validate_group(struct perf_event *event)
907911
for_each_hw_dn(hw, dn, i) {
908912
int wp_idx, wp_cmb, dtm = dn->dtm;
909913

910-
if (val.dtm_count[dtm] == CMN_DTM_NUM_COUNTERS)
911-
return -EINVAL;
914+
if (val->dtm_count[dtm] == CMN_DTM_NUM_COUNTERS)
915+
goto done;
912916

913-
if (occupid && val.occupid[dtm] && occupid != val.occupid[dtm])
914-
return -EINVAL;
917+
if (occupid && val->occupid[dtm] && occupid != val->occupid[dtm])
918+
goto done;
915919

916920
if (type != CMN_TYPE_WP)
917921
continue;
918922

919923
wp_idx = arm_cmn_wp_idx(event);
920-
if (val.wp[dtm][wp_idx])
921-
return -EINVAL;
924+
if (val->wp[dtm][wp_idx])
925+
goto done;
922926

923-
wp_cmb = val.wp[dtm][wp_idx ^ 1];
927+
wp_cmb = val->wp[dtm][wp_idx ^ 1];
924928
if (wp_cmb && wp_cmb != CMN_EVENT_WP_COMBINE(event) + 1)
925-
return -EINVAL;
929+
goto done;
926930
}
927931

928-
return 0;
932+
ret = 0;
933+
done:
934+
kfree(val);
935+
return ret;
929936
}
930937

931938
static int arm_cmn_event_init(struct perf_event *event)

0 commit comments

Comments
 (0)