From ef57fb235016a168b0f2260783c44c7f4ebea32d Mon Sep 17 00:00:00 2001 From: Eric Engestrom Date: Thu, 18 Oct 2018 17:19:56 +0100 Subject: [PATCH] intel: replace large stack buffer with heap allocation For now, this keeps the "100 bytes" allocation; we can try to figure out the correct size as a follow up. Suggested-by: Lionel Landwerlin Signed-off-by: Eric Engestrom Reviewed-by: Lionel Landwerlin --- src/intel/dev/gen_device_info.c | 57 ++++++++++--------- src/intel/dev/gen_device_info.h | 2 +- .../drivers/dri/i965/brw_performance_query.c | 9 +-- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/intel/dev/gen_device_info.c b/src/intel/dev/gen_device_info.c index 951e81d3e60..6f3b6ff35b6 100644 --- a/src/intel/dev/gen_device_info.c +++ b/src/intel/dev/gen_device_info.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -1057,62 +1058,66 @@ fill_masks(struct gen_device_info *devinfo) } } -void +bool gen_device_info_update_from_masks(struct gen_device_info *devinfo, uint32_t slice_mask, uint32_t subslice_mask, uint32_t n_eus) { - struct { - struct drm_i915_query_topology_info base; - uint8_t data[100]; - } topology; + struct drm_i915_query_topology_info *topology; assert((slice_mask & 0xff) == slice_mask); - memset(&topology, 0, sizeof(topology)); + size_t data_length = 100; - topology.base.max_slices = util_last_bit(slice_mask); - topology.base.max_subslices = util_last_bit(subslice_mask); + topology = calloc(1, sizeof(*topology) + data_length); + if (!topology) + return false; - topology.base.subslice_offset = DIV_ROUND_UP(topology.base.max_slices, 8); - topology.base.subslice_stride = DIV_ROUND_UP(topology.base.max_subslices, 8); + topology->max_slices = util_last_bit(slice_mask); + topology->max_subslices = util_last_bit(subslice_mask); + + topology->subslice_offset = DIV_ROUND_UP(topology->max_slices, 8); + topology->subslice_stride = DIV_ROUND_UP(topology->max_subslices, 8); uint32_t n_subslices = __builtin_popcount(slice_mask) * __builtin_popcount(subslice_mask); uint32_t num_eu_per_subslice = DIV_ROUND_UP(n_eus, n_subslices); uint32_t eu_mask = (1U << num_eu_per_subslice) - 1; - topology.base.eu_offset = topology.base.subslice_offset + - DIV_ROUND_UP(topology.base.max_subslices, 8); - topology.base.eu_stride = DIV_ROUND_UP(num_eu_per_subslice, 8); + topology->eu_offset = topology->subslice_offset + + DIV_ROUND_UP(topology->max_subslices, 8); + topology->eu_stride = DIV_ROUND_UP(num_eu_per_subslice, 8); /* Set slice mask in topology */ - for (int b = 0; b < topology.base.subslice_offset; b++) - topology.base.data[b] = (slice_mask >> (b * 8)) & 0xff; + for (int b = 0; b < topology->subslice_offset; b++) + topology->data[b] = (slice_mask >> (b * 8)) & 0xff; - for (int s = 0; s < topology.base.max_slices; s++) { + for (int s = 0; s < topology->max_slices; s++) { /* Set subslice mask in topology */ - for (int b = 0; b < topology.base.subslice_stride; b++) { - int subslice_offset = topology.base.subslice_offset + - s * topology.base.subslice_stride + b; + for (int b = 0; b < topology->subslice_stride; b++) { + int subslice_offset = topology->subslice_offset + + s * topology->subslice_stride + b; - topology.base.data[subslice_offset] = (subslice_mask >> (b * 8)) & 0xff; + topology->data[subslice_offset] = (subslice_mask >> (b * 8)) & 0xff; } /* Set eu mask in topology */ - for (int ss = 0; ss < topology.base.max_subslices; ss++) { - for (int b = 0; b < topology.base.eu_stride; b++) { - int eu_offset = topology.base.eu_offset + - (s * topology.base.max_subslices + ss) * topology.base.eu_stride + b; + for (int ss = 0; ss < topology->max_subslices; ss++) { + for (int b = 0; b < topology->eu_stride; b++) { + int eu_offset = topology->eu_offset + + (s * topology->max_subslices + ss) * topology->eu_stride + b; - topology.base.data[eu_offset] = (eu_mask >> (b * 8)) & 0xff; + topology->data[eu_offset] = (eu_mask >> (b * 8)) & 0xff; } } } - gen_device_info_update_from_topology(devinfo, &topology.base); + gen_device_info_update_from_topology(devinfo, topology); + free(topology); + + return true; } static void diff --git a/src/intel/dev/gen_device_info.h b/src/intel/dev/gen_device_info.h index 4fe937355a7..6199290f995 100644 --- a/src/intel/dev/gen_device_info.h +++ b/src/intel/dev/gen_device_info.h @@ -268,7 +268,7 @@ bool gen_get_device_info(int devid, struct gen_device_info *devinfo); const char *gen_get_device_name(int devid); /* Used with SLICE_MASK/SUBSLICE_MASK values from DRM_I915_GETPARAM. */ -void gen_device_info_update_from_masks(struct gen_device_info *devinfo, +bool gen_device_info_update_from_masks(struct gen_device_info *devinfo, uint32_t slice_mask, uint32_t subslice_mask, uint32_t n_eus); diff --git a/src/mesa/drivers/dri/i965/brw_performance_query.c b/src/mesa/drivers/dri/i965/brw_performance_query.c index cd7961905bd..6c168d0adf3 100644 --- a/src/mesa/drivers/dri/i965/brw_performance_query.c +++ b/src/mesa/drivers/dri/i965/brw_performance_query.c @@ -1734,10 +1734,11 @@ getparam_topology(struct brw_context *brw) if (ret) return false; - gen_device_info_update_from_masks(&brw->screen->devinfo, - slice_mask, - subslice_mask, - brw->screen->eu_total); + if (!gen_device_info_update_from_masks(&brw->screen->devinfo, + slice_mask, + subslice_mask, + brw->screen->eu_total)) + return false; return true; }