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@xxxxxxxxx> --- intel/intel_bufmgr_gem.c | 96 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 27 deletions(-) diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c index 5a67f53..91320ca 100644 --- a/intel/intel_bufmgr_gem.c +++ b/intel/intel_bufmgr_gem.c @@ -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; -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx