diff mbox

[02/11] intel: Validate output of realloc()

Message ID 1428655383-26087-3-git-send-email-praveen.paneri@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Praveen Paneri April 10, 2015, 8:42 a.m. UTC
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(-)
diff mbox

Patch

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;