[PATCH i-g-t v8 18/33] intel_batchbuffer: fixing crash
Zbigniew Kempczyński
zbigniew.kempczynski at intel.com
Mon Oct 19 15:59:18 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 c231e7a4..2eeb362f 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 b4cbe673..029b7e23 100644
--- a/lib/intel_batchbuffer.h
+++ b/lib/intel_batchbuffer.h
@@ -632,6 +632,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