[PATCH i-g-t v3 18/22] intel_batchbuffer: fixing crash

Zbigniew Kempczyński zbigniew.kempczynski at intel.com
Wed Oct 14 11:05:38 UTC 2020


---
 lib/intel_batchbuffer.c | 112 +++++++++++++++++++++++-----------------
 lib/intel_batchbuffer.h |   2 +
 2 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/lib/intel_batchbuffer.c b/lib/intel_batchbuffer.c
index 4d45c3dd..0a57532f 100644
--- a/lib/intel_batchbuffer.c
+++ b/lib/intel_batchbuffer.c
@@ -1268,6 +1268,7 @@ static struct intel_bb *
 __intel_bb_create(int i915, uint32_t ctx, uint32_t size, bool do_relocs,
 		  uint8_t allocator_type)
 {
+	struct drm_i915_gem_exec_object2 *object;
 	struct intel_bb *ibb = calloc(1, sizeof(*ibb));
 	uint64_t gtt_size;
 
@@ -1301,9 +1302,10 @@ __intel_bb_create(int i915, uint32_t ctx, uint32_t size, bool do_relocs,
 	ibb->gtt_size = gtt_size;
 	ibb->uses_full_ppgtt = gem_uses_full_ppgtt(i915);
 
-	ibb->batch_offset = INTEL_BUF_INVALID_ADDRESS;
-	intel_bb_add_object(ibb, ibb->handle, ibb->size,
-			    ibb->batch_offset, ibb->alignment, false);
+	object = intel_bb_add_object(ibb, ibb->handle, ibb->size,
+				     INTEL_BUF_INVALID_ADDRESS, ibb->alignment,
+				     false);
+	ibb->batch_offset = object->offset;
 
 	ibb->refcount = 1;
 
@@ -1472,6 +1474,7 @@ void intel_bb_destroy(struct intel_bb *ibb)
  *
  * Recreate batch bo when there's no additional reference.
 */
+
 void intel_bb_reset(struct intel_bb *ibb, bool purge_objects_cache)
 {
 	uint32_t i;
@@ -1501,10 +1504,12 @@ void intel_bb_reset(struct intel_bb *ibb, bool purge_objects_cache)
 	/*
 	 * When we use allocators we're in no-reloc mode so we have to free
 	 * and reacquire offset (ibb->handle can change in multiprocess
-	 * environment).
+	 * environment). We also have to remove and add it again to
+	 * objects and cache tree.
 	 */
-	if (ibb->allocator_type != INTEL_ALLOCATOR_NONE)
-		intel_allocator_free(ibb->allocator_handle, ibb->handle);
+	if (ibb->allocator_type != INTEL_ALLOCATOR_NONE && !purge_objects_cache)
+		intel_bb_remove_object(ibb, ibb->handle, ibb->batch_offset,
+				       ibb->size);
 
 	gem_close(ibb->i915, ibb->handle);
 	ibb->handle = gem_create(ibb->i915, ibb->size);
@@ -1646,8 +1651,10 @@ static bool __remove_from_cache(struct intel_bb *ibb, uint32_t handle)
 	struct drm_i915_gem_exec_object2 **found, *object;
 
 	object = intel_bb_find_object(ibb, handle);
-	if (!object)
+	if (!object) {
+		igt_warn("Object: handle: %u not found\n", handle);
 		return false;
+	}
 
 	found = tdelete((void *) object, &ibb->root, __compare_objects);
 	if (!found)
@@ -1694,11 +1701,15 @@ static void __remove_from_objects(struct intel_bb *ibb,
 		}
 	}
 
-	if (!found) {
-		igt_warn("Trying to remove unknown object, handle: %u\n",
-			 object->handle);
+	/*
+	 * When we reset bb (without purging) we have:
+	 * 1. cache which contains all cached objects
+	 * 2. objects array which contains only bb object (cleared in reset
+	 *    path with bb object added at the end)
+	 * So !found is normal situation and no warning is added here.
+	 */
+	if (!found)
 		return;
-	}
 
 	ibb->num_objects--;
 	if (i < ibb->num_objects)
@@ -1744,8 +1755,6 @@ intel_bb_add_object(struct intel_bb *ibb, uint32_t handle, uint64_t size,
 	object->alignment = alignment ?: 4096;
 	__add_to_objects(ibb, object);
 
-	igt_debug("Passed offset: %lx, handle: %u, alignment: %lx\n",
-		  (long) offset, handle, (long) alignment);
 	/*
 	 * If object->offset == INVALID_ADDRESS we added freshly object to the
 	 * cache. In that case we have two choices:
@@ -1776,12 +1785,10 @@ intel_bb_add_object(struct intel_bb *ibb, uint32_t handle, uint64_t size,
 		}
 	} else {
 		igt_assert_f(object->offset == gen8_canonical_addr(offset),
-			     "offset not match: %" PRIx64 " <> %" PRIx64 "\n",
-			     (uint64_t) object->offset, gen8_canonical_addr(offset));
+			     "(pid: %ld) handle: %u, offset not match: %" PRIx64 " <> %" PRIx64 "\n",
+			     (long) getpid(), handle, (uint64_t) object->offset, gen8_canonical_addr(offset));
 	}
 
-	igt_debug("Assigned offset: %lx, handle: %u, alignment: %lx\n",
-		  (long) offset, handle, (long) alignment);
 	object->offset = offset;
 
 	/* Limit current offset to gtt size */
@@ -1897,6 +1904,8 @@ intel_bb_find_object(struct intel_bb *ibb, uint32_t handle)
 	struct drm_i915_gem_exec_object2 **found;
 
 	found = tfind((void *) &object, &ibb->root, __compare_objects);
+	if (!found)
+		return NULL;
 
 	return *found;
 }
@@ -1907,6 +1916,8 @@ intel_bb_object_set_flag(struct intel_bb *ibb, uint32_t handle, uint64_t flag)
 	struct drm_i915_gem_exec_object2 object = { .handle = handle };
 	struct drm_i915_gem_exec_object2 **found;
 
+	igt_assert_f(ibb->root, "Trying to search in null tree\n");
+
 	found = tfind((void *) &object, &ibb->root, __compare_objects);
 	if (!found) {
 		igt_warn("Trying to set fence on not found handle: %u\n",
@@ -2158,45 +2169,46 @@ static void intel_bb_dump_execbuf(struct intel_bb *ibb,
 	int i, j;
 	uint64_t address;
 
-	igt_info("execbuf batch len: %u, start offset: 0x%x, "
-		 "DR1: 0x%x, DR4: 0x%x, "
-		 "num clip: %u, clipptr: 0x%llx, "
-		 "flags: 0x%llx, rsvd1: 0x%llx, rsvd2: 0x%llx\n",
-		 execbuf->batch_len, execbuf->batch_start_offset,
-		 execbuf->DR1, execbuf->DR4,
-		 execbuf->num_cliprects, execbuf->cliprects_ptr,
-		 execbuf->flags, execbuf->rsvd1, execbuf->rsvd2);
-
-	igt_info("execbuf buffer_count: %d\n", execbuf->buffer_count);
+	igt_debug("[pid: %ld] execbuf batch len: %u, start offset: 0x%x, "
+		  "DR1: 0x%x, DR4: 0x%x, "
+		  "num clip: %u, clipptr: 0x%llx, "
+		  "flags: 0x%llx, rsvd1: 0x%llx, rsvd2: 0x%llx\n",
+		  (long) getpid(),
+		  execbuf->batch_len, execbuf->batch_start_offset,
+		  execbuf->DR1, execbuf->DR4,
+		  execbuf->num_cliprects, execbuf->cliprects_ptr,
+		  execbuf->flags, execbuf->rsvd1, execbuf->rsvd2);
+
+	igt_debug("execbuf buffer_count: %d\n", execbuf->buffer_count);
 	for (i = 0; i < execbuf->buffer_count; i++) {
 		objects = &((struct drm_i915_gem_exec_object2 *)
 			    from_user_pointer(execbuf->buffers_ptr))[i];
 		relocs = from_user_pointer(objects->relocs_ptr);
 		address = objects->offset;
-		igt_info(" [%d] handle: %u, reloc_count: %d, reloc_ptr: %p, "
-			 "align: 0x%llx, offset: 0x%" PRIx64 ", flags: 0x%llx, "
-			 "rsvd1: 0x%llx, rsvd2: 0x%llx\n",
-			 i, objects->handle, objects->relocation_count,
-			 relocs,
-			 objects->alignment,
-			 address,
-			 objects->flags,
-			 objects->rsvd1, objects->rsvd2);
+		igt_debug(" [%d] handle: %u, reloc_count: %d, reloc_ptr: %p, "
+			  "align: 0x%llx, offset: 0x%" PRIx64 ", flags: 0x%llx, "
+			  "rsvd1: 0x%llx, rsvd2: 0x%llx\n",
+			  i, objects->handle, objects->relocation_count,
+			  relocs,
+			  objects->alignment,
+			  address,
+			  objects->flags,
+			  objects->rsvd1, objects->rsvd2);
 		if (objects->relocation_count) {
-			igt_info("\texecbuf relocs:\n");
+			igt_debug("\texecbuf relocs:\n");
 			for (j = 0; j < objects->relocation_count; j++) {
 				reloc = &relocs[j];
 				address = reloc->presumed_offset;
-				igt_info("\t [%d] target handle: %u, "
-					 "offset: 0x%llx, delta: 0x%x, "
-					 "presumed_offset: 0x%" PRIx64 ", "
-					 "read_domains: 0x%x, "
-					 "write_domain: 0x%x\n",
-					 j, reloc->target_handle,
-					 reloc->offset, reloc->delta,
-					 address,
-					 reloc->read_domains,
-					 reloc->write_domain);
+				igt_debug("\t [%d] target handle: %u, "
+					  "offset: 0x%llx, delta: 0x%x, "
+					  "presumed_offset: 0x%" PRIx64 ", "
+					  "read_domains: 0x%x, "
+					  "write_domain: 0x%x\n",
+					  j, reloc->target_handle,
+					  reloc->offset, reloc->delta,
+					  address,
+					  reloc->read_domains,
+					  reloc->write_domain);
 			}
 		}
 	}
@@ -2239,6 +2251,12 @@ static void print_node(const void *node, VISIT which, int depth)
 	}
 }
 
+void intel_bb_dump_cache(struct intel_bb *ibb)
+{
+	igt_info("[pid: %ld] dump cache\n", (long) getpid());
+	twalk(ibb->root, print_node);
+}
+
 static struct drm_i915_gem_exec_object2 *
 create_objects_array(struct intel_bb *ibb)
 {
diff --git a/lib/intel_batchbuffer.h b/lib/intel_batchbuffer.h
index 92ecbe6a..8ad4382d 100644
--- a/lib/intel_batchbuffer.h
+++ b/lib/intel_batchbuffer.h
@@ -630,6 +630,8 @@ uint64_t intel_bb_offset_reloc_to_object(struct intel_bb *ibb,
 					 uint32_t offset,
 					 uint64_t presumed_offset);
 
+void intel_bb_dump_cache(struct intel_bb *ibb);
+
 void intel_bb_exec(struct intel_bb *ibb, uint32_t end_offset,
 		   uint64_t flags, bool sync);
 
-- 
2.26.0



More information about the Intel-gfx-trybot mailing list