[Intel-gfx] [PATCH igt] igt/gem_exec_reloc: Check we write the full 64bit relocation

Chris Wilson chris at chris-wilson.co.uk
Fri Nov 4 15:03:59 UTC 2016


Recently a patch ran successfully through BAT that broke 64bit
relocations on a couple of machines. Oops. So lets add a very fast set
of tests to check basic relocation handling.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 tests/gem_exec_reloc.c                | 199 ++++++++++++++++++++++++++++++++++
 tests/intel-ci/fast-feedback.testlist |   3 +
 2 files changed, 202 insertions(+)

diff --git a/tests/gem_exec_reloc.c b/tests/gem_exec_reloc.c
index 5f898da..b541b38 100644
--- a/tests/gem_exec_reloc.c
+++ b/tests/gem_exec_reloc.c
@@ -28,6 +28,9 @@ IGT_TEST_DESCRIPTION("Basic sanity check of execbuf-ioctl relocations.");
 #define LOCAL_I915_EXEC_BSD_SHIFT      (13)
 #define LOCAL_I915_EXEC_BSD_MASK       (3 << LOCAL_I915_EXEC_BSD_SHIFT)
 
+#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
+#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
+
 #define ENGINE_MASK  (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
 
 static uint32_t find_last_set(uint64_t x)
@@ -320,6 +323,193 @@ static void active(int fd, unsigned engine)
 	gem_close(fd, obj[0].handle);
 }
 
+static bool has_64bit_reloc(int fd)
+{
+	return intel_gen(intel_get_drm_devid(fd)) >= 8;
+}
+
+static void basic_cpu(int fd)
+{
+	struct drm_i915_gem_relocation_entry reloc;
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	uint32_t bbe = MI_BATCH_BUFFER_END;
+	uint32_t trash;
+	uint64_t offset;
+	char *wc;
+
+	memset(&obj, 0, sizeof(obj));
+
+	obj.handle = gem_create(fd, 4096);
+	obj.relocs_ptr = (uintptr_t)&reloc;
+	obj.relocation_count = 1;
+	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+	memset(&reloc, 0, sizeof(reloc));
+	reloc.offset = 4000;
+	reloc.target_handle = obj.handle;
+	reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = (uintptr_t)&obj;
+	execbuf.buffer_count = 1;
+
+	wc = gem_mmap__wc(fd, obj.handle, 0, 4096, PROT_WRITE);
+	offset = -1;
+	memcpy(wc + 4000, &offset, sizeof(offset));
+
+	gem_set_domain(fd, obj.handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	gem_execbuf(fd, &execbuf);
+
+	offset = 0;
+	memcpy(&offset, wc + 4000, has_64bit_reloc(fd) ? 8 : 4);
+	munmap(wc, 4096);
+
+	igt_assert_eq_u64(reloc.presumed_offset, offset);
+	igt_assert_eq_u64(obj.offset, offset);
+
+	/* Simulate relocation */
+	trash = obj.handle;
+	obj.handle = gem_create(fd, 4096);
+	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+	reloc.target_handle = obj.handle;
+
+	wc = gem_mmap__wc(fd, obj.handle, 0, 4096, PROT_WRITE);
+	offset = -1;
+	memcpy(wc + 4000, &offset, sizeof(offset));
+
+	gem_set_domain(fd, obj.handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	gem_execbuf(fd, &execbuf);
+
+	offset = 0;
+	memcpy(&offset, wc + 4000, has_64bit_reloc(fd) ? 8 : 4);
+	munmap(wc, 4096);
+
+	igt_assert_eq_u64(reloc.presumed_offset, offset);
+	igt_assert_eq_u64(obj.offset, offset);
+
+	gem_close(fd, obj.handle);
+	gem_close(fd, trash);
+}
+
+static void basic_gtt(int fd)
+{
+	struct drm_i915_gem_relocation_entry reloc;
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	uint32_t bbe = MI_BATCH_BUFFER_END;
+	uint64_t offset;
+	char *wc;
+
+	memset(&obj, 0, sizeof(obj));
+
+	obj.handle = gem_create(fd, 4096);
+	obj.relocs_ptr = (uintptr_t)&reloc;
+	obj.relocation_count = 1;
+	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+	memset(&reloc, 0, sizeof(reloc));
+	reloc.offset = 4000;
+	reloc.target_handle = obj.handle;
+	reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = (uintptr_t)&obj;
+	execbuf.buffer_count = 1;
+
+	wc = gem_mmap__wc(fd, obj.handle, 0, 4096, PROT_WRITE);
+	offset = -1;
+	memcpy(wc + 4000, &offset, sizeof(offset));
+
+	gem_set_domain(fd, obj.handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	gem_execbuf(fd, &execbuf);
+
+	offset = 0;
+	memcpy(&offset, wc + 4000, has_64bit_reloc(fd) ? 8 : 4);
+
+	igt_assert_eq_u64(reloc.presumed_offset, offset);
+	igt_assert_eq_u64(obj.offset, offset);
+
+	offset = -1;
+	memcpy(wc + 4000, &offset, sizeof(offset));
+
+	/* Simulate relocation */
+	obj.offset += 4096;
+	reloc.presumed_offset += 4096;
+	memcpy(wc + 4000, &obj.offset, has_64bit_reloc(fd) ? 8 : 4);
+
+	gem_execbuf(fd, &execbuf);
+
+	offset = 0;
+	memcpy(&offset, wc + 4000, has_64bit_reloc(fd) ? 8 : 4);
+	munmap(wc, 4096);
+
+	igt_assert_eq_u64(reloc.presumed_offset, offset);
+	igt_assert_eq_u64(obj.offset, offset);
+
+	gem_close(fd, obj.handle);
+}
+
+static void basic_noreloc(int fd)
+{
+	struct drm_i915_gem_relocation_entry reloc;
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	uint32_t bbe = MI_BATCH_BUFFER_END;
+	uint64_t offset;
+	char *wc;
+
+	memset(&obj, 0, sizeof(obj));
+
+	obj.handle = gem_create(fd, 4096);
+	obj.relocs_ptr = (uintptr_t)&reloc;
+	obj.relocation_count = 1;
+	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+	memset(&reloc, 0, sizeof(reloc));
+	reloc.offset = 4000;
+	reloc.target_handle = obj.handle;
+	reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = (uintptr_t)&obj;
+	execbuf.buffer_count = 1;
+	execbuf.flags = LOCAL_I915_EXEC_NO_RELOC;
+
+	wc = gem_mmap__wc(fd, obj.handle, 0, 4096, PROT_WRITE);
+	offset = -1;
+	memcpy(wc + 4000, &offset, sizeof(offset));
+
+	gem_set_domain(fd, obj.handle,
+		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	gem_execbuf(fd, &execbuf);
+
+	offset = 0;
+	memcpy(&offset, wc + 4000, has_64bit_reloc(fd) ? 8 : 4);
+
+	igt_assert_eq_u64(reloc.presumed_offset, offset);
+	igt_assert_eq_u64(obj.offset, offset);
+
+	/* Simulate relocation */
+	obj.offset += 4096;
+	reloc.presumed_offset += 4096;
+	memcpy(wc + 4000, &obj.offset, sizeof(obj.offset));
+
+	gem_execbuf(fd, &execbuf);
+
+	offset = 0;
+	memcpy(&offset, wc + 4000, has_64bit_reloc(fd) ? 8 : 4);
+	munmap(wc, 4096);
+
+	igt_assert_eq_u64(reloc.presumed_offset, offset);
+	igt_assert_eq_u64(obj.offset, offset);
+
+	gem_close(fd, obj.handle);
+}
+
 igt_main
 {
 	uint64_t size;
@@ -328,6 +518,15 @@ igt_main
 	igt_fixture
 		fd = drm_open_driver_master(DRIVER_INTEL);
 
+	igt_subtest("basic-cpu")
+		basic_cpu(fd);
+
+	igt_subtest("basic-gtt")
+		basic_gtt(fd);
+
+	igt_subtest("basic-noreloc")
+		basic_noreloc(fd);
+
 	for (size = 4096; size <= 4ull*1024*1024*1024; size <<= 1) {
 		igt_subtest_f("mmap-%u", find_last_set(size) - 1)
 			from_mmap(fd, size, MEM);
diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
index b8fce59..6efaaa4 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -64,6 +64,9 @@ igt at gem_exec_nop@basic-series
 igt at gem_exec_parallel@basic
 igt at gem_exec_parse@basic-allowed
 igt at gem_exec_parse@basic-rejected
+igt at gem_exec_reloc@basic-cpu
+igt at gem_exec_reloc@basic-gtt
+igt at gem_exec_reloc@basic-noreloc
 igt at gem_exec_store@basic-all
 igt at gem_exec_store@basic-blt
 igt at gem_exec_store@basic-bsd
-- 
2.10.2



More information about the Intel-gfx mailing list