@@ -427,15 +427,17 @@ drm_intel_gem_bo_reference(drm_intel_bo *bo)
* with the intersection of the memory type flags and the union of the
* access flags.
*/
-static void
+static int
drm_intel_add_validate_buffer(drm_intel_bo *bo)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
int index;
+ struct drm_i915_gem_exec_object *exec_objects;
+ drm_intel_bo **exec_bos;
if (bo_gem->validate_index != -1)
- return;
+ return 0;
/* Extend the array of validation entries as necessary. */
if (bufmgr_gem->exec_count == bufmgr_gem->exec_size) {
@@ -444,12 +446,22 @@ drm_intel_add_validate_buffer(drm_intel_bo *bo)
if (new_size == 0)
new_size = 5;
- bufmgr_gem->exec_objects =
- realloc(bufmgr_gem->exec_objects,
- sizeof(*bufmgr_gem->exec_objects) * new_size);
- bufmgr_gem->exec_bos =
- realloc(bufmgr_gem->exec_bos,
+ exec_objects = realloc(bufmgr_gem->exec_objects,
+ sizeof(*bufmgr_gem->exec_objects) * new_size);
+ if (!exec_objects) {
+ return -ENOMEM;
+ }
+
+ bufmgr_gem->exec_objects = exec_objects;
+
+ exec_bos = realloc(bufmgr_gem->exec_bos,
sizeof(*bufmgr_gem->exec_bos) * new_size);
+ if (!exec_bos) {
+ return -ENOMEM;
+ }
+
+ bufmgr_gem->exec_bos = exec_bos;
+
bufmgr_gem->exec_size = new_size;
}
@@ -463,20 +475,23 @@ drm_intel_add_validate_buffer(drm_intel_bo *bo)
bufmgr_gem->exec_objects[index].offset = 0;
bufmgr_gem->exec_bos[index] = bo;
bufmgr_gem->exec_count++;
+ return 0;
}
-static void
+static int
drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
{
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
int index;
+ struct drm_i915_gem_exec_object2 *exec2_objects;
+ drm_intel_bo **exec_bos;
if (bo_gem->validate_index != -1) {
if (need_fence)
bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |=
EXEC_OBJECT_NEEDS_FENCE;
- return;
+ return 0;
}
/* Extend the array of validation entries as necessary. */
@@ -486,12 +501,19 @@ drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
if (new_size == 0)
new_size = 5;
- bufmgr_gem->exec2_objects =
- realloc(bufmgr_gem->exec2_objects,
+ exec2_objects = realloc(bufmgr_gem->exec2_objects,
sizeof(*bufmgr_gem->exec2_objects) * new_size);
- bufmgr_gem->exec_bos =
- realloc(bufmgr_gem->exec_bos,
+ if (!exec2_objects)
+ return -ENOMEM;
+
+ bufmgr_gem->exec2_objects = exec2_objects;
+
+ exec_bos = realloc(bufmgr_gem->exec_bos,
sizeof(*bufmgr_gem->exec_bos) * new_size);
+ if (!exec_bos)
+ return -ENOMEM;
+
+ bufmgr_gem->exec_bos = exec_bos;
bufmgr_gem->exec_size = new_size;
}
@@ -512,6 +534,7 @@ drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
EXEC_OBJECT_NEEDS_FENCE;
}
bufmgr_gem->exec_count++;
+ return 0;
}
#define RELOC_BUF_SIZE(x) ((I915_RELOC_HEADER + x * I915_RELOC0_STRIDE) * \
@@ -1931,14 +1954,14 @@ drm_intel_gem_bo_clear_relocs(drm_intel_bo *bo, int start)
* validations to be performed and update the relocation buffers with
* index values into the validation list.
*/
-static void
+static int
drm_intel_gem_bo_process_reloc(drm_intel_bo *bo)
{
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
- int i;
+ int i, ret = 0;
if (bo_gem->relocs == NULL)
- return;
+ return 0;
for (i = 0; i < bo_gem->reloc_count; i++) {
drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo;
@@ -1949,21 +1972,26 @@ drm_intel_gem_bo_process_reloc(drm_intel_bo *bo)
drm_intel_gem_bo_mark_mmaps_incoherent(bo);
/* Continue walking the tree depth-first. */
- drm_intel_gem_bo_process_reloc(target_bo);
+ ret = drm_intel_gem_bo_process_reloc(target_bo);
+ if (ret)
+ break;
/* Add the target to the validate list */
- drm_intel_add_validate_buffer(target_bo);
+ ret = drm_intel_add_validate_buffer(target_bo);
+ if (ret)
+ break;
}
+ return ret;
}
-static void
+static int
drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo)
{
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
- int i;
+ int i, ret = 0;
if (bo_gem->relocs == NULL)
- return;
+ return 0;
for (i = 0; i < bo_gem->reloc_count; i++) {
drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo;
@@ -1975,14 +2003,19 @@ drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo)
drm_intel_gem_bo_mark_mmaps_incoherent(bo);
/* Continue walking the tree depth-first. */
- drm_intel_gem_bo_process_reloc2(target_bo);
+ ret = drm_intel_gem_bo_process_reloc2(target_bo);
+ if (ret)
+ break;
need_fence = (bo_gem->reloc_target_info[i].flags &
DRM_INTEL_RELOC_FENCE);
/* Add the target to the validate list */
- drm_intel_add_validate_buffer2(target_bo, need_fence);
+ ret = drm_intel_add_validate_buffer2(target_bo, need_fence);
+ if (ret)
+ break;
}
+ return ret;
}
@@ -2334,12 +2367,16 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, int used,
pthread_mutex_lock(&bufmgr_gem->lock);
/* Update indices and set up the validate list. */
- drm_intel_gem_bo_process_reloc(bo);
+ ret = drm_intel_gem_bo_process_reloc(bo);
+ if (ret)
+ goto skip_execution;
/* Add the batch buffer to the validation list. There are no
* relocations pointing to it.
*/
- drm_intel_add_validate_buffer(bo);
+ ret = drm_intel_add_validate_buffer(bo);
+ if (ret)
+ goto skip_execution;
memclear(execbuf);
execbuf.buffers_ptr = (uintptr_t) bufmgr_gem->exec_objects;
@@ -2370,6 +2407,7 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, int used,
}
drm_intel_update_buffer_offsets(bufmgr_gem);
+skip_execution:
if (bufmgr_gem->bufmgr.debug)
drm_intel_gem_dump_validation_list(bufmgr_gem);
@@ -2421,12 +2459,16 @@ do_exec2(drm_intel_bo *bo, int used, drm_intel_context *ctx,
pthread_mutex_lock(&bufmgr_gem->lock);
/* Update indices and set up the validate list. */
- drm_intel_gem_bo_process_reloc2(bo);
+ ret = drm_intel_gem_bo_process_reloc2(bo);
+ if (ret)
+ goto skip_execution;
/* Add the batch buffer to the validation list. There are no relocations
* pointing to it.
*/
- drm_intel_add_validate_buffer2(bo, 0);
+ ret = drm_intel_add_validate_buffer2(bo, 0);
+ if (ret)
+ goto skip_execution;
memclear(execbuf);
execbuf.buffers_ptr = (uintptr_t)bufmgr_gem->exec2_objects;
realloc will return NULL if failed to allocate the extra memory requested. Return -ENOMEM from the function if it fails. v2: Modifications to propagate relloc failure to caller functions and skip the execbuffer ioctl. (Chris) Signed-off-by: Praveen Paneri <praveen.paneri@intel.com> --- intel/intel_bufmgr_gem.c | 96 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 27 deletions(-)