iris: avoid stack overflow in iris_bo_wait_syncobj()

Keep most cases using the stack as it's cheaper, but fall back to the
heap when the size gets too big.

This should fix a stack overflow reported by @rhezashan for a case
where we had lots of iris_screens.

Credits to Matt Turner and José Roberto de Souza for their work on
this issue, which led us to find its root cause.

Cc: mesa-stable
Reported-by: rheza shandikri (@rhezashan in gitlab)
Credits-to: José Roberto de Souza <jose.souza@intel.com>
Credits-to: Matt Turner <mattst88@gmail.com>
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25236>
(cherry picked from commit 3cec15dd14)
This commit is contained in:
Paulo Zanoni 2023-09-08 14:29:51 -07:00 committed by Eric Engestrom
parent 1b47be15f4
commit 8c775576e0
2 changed files with 8 additions and 2 deletions

View file

@ -76,7 +76,7 @@
"description": "iris: avoid stack overflow in iris_bo_wait_syncobj()",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null
},

View file

@ -50,6 +50,7 @@
#include "errno.h"
#include "common/intel_aux_map.h"
#include "common/intel_clflush.h"
#include "c99_alloca.h"
#include "dev/intel_debug.h"
#include "common/intel_gem.h"
#include "dev/intel_device_info.h"
@ -455,7 +456,10 @@ iris_bo_wait_syncobj(struct iris_bo *bo, int64_t timeout_ns)
simple_mtx_lock(&bufmgr->bo_deps_lock);
uint32_t handles[bo->deps_size * IRIS_BATCH_COUNT * 2];
const int handles_len = bo->deps_size * IRIS_BATCH_COUNT * 2;
uint32_t *handles = handles_len <= 32 ?
(uint32_t *)alloca(handles_len * sizeof(*handles)) :
(uint32_t *)malloc(handles_len * sizeof(*handles));
int handle_count = 0;
for (int d = 0; d < bo->deps_size; d++) {
@ -499,6 +503,8 @@ iris_bo_wait_syncobj(struct iris_bo *bo, int64_t timeout_ns)
}
out:
if (handles_len > 32)
free(handles);
simple_mtx_unlock(&bufmgr->bo_deps_lock);
return ret;
}