summaryrefslogtreecommitdiff
path: root/tests/gem_exec_reloc.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-05-10 23:41:16 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2017-05-11 00:10:11 +0100
commit1c2c593363012b60e7b64ac2f39b0afb63cd1b83 (patch)
tree3536b90e6c6f42cfa4f896ab5505e4a8a0a42a03 /tests/gem_exec_reloc.c
parent1e740411ea92549eba56057f47c4572da41a8b23 (diff)
igt/gem_exec_reloc: Exercise relocations across the full GTT range
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'tests/gem_exec_reloc.c')
-rw-r--r--tests/gem_exec_reloc.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/tests/gem_exec_reloc.c b/tests/gem_exec_reloc.c
index bb4bbb34..b98c89b6 100644
--- a/tests/gem_exec_reloc.c
+++ b/tests/gem_exec_reloc.c
@@ -499,6 +499,112 @@ static void basic_reloc(int fd, unsigned before, unsigned after, unsigned flags)
gem_close(fd, obj.handle);
}
+static inline uint64_t sign_extend(uint64_t x, int index)
+{
+ int shift = 63 - index;
+ return (int64_t)(x << shift) >> shift;
+}
+
+static uint64_t gen8_canonical_address(uint64_t address)
+{
+ return sign_extend(address, 47);
+}
+
+static void basic_range(int fd, unsigned flags)
+{
+ struct drm_i915_gem_relocation_entry reloc[128];
+ struct drm_i915_gem_exec_object2 obj[128];
+ struct drm_i915_gem_execbuffer2 execbuf;
+ uint64_t address_mask = has_64b_reloc(fd) ? ~(uint64_t)0 : ~(uint32_t)0;
+ uint64_t gtt_size = gem_aperture_size(fd);
+ const uint32_t bbe = MI_BATCH_BUFFER_END;
+ igt_spin_t *spin = NULL;
+ int count, n;
+
+ igt_require(gem_has_softpin(fd));
+
+ for (count = 12; gtt_size >> (count + 1); count++)
+ ;
+
+ count -= 12;
+
+ memset(obj, 0, sizeof(obj));
+ memset(reloc, 0, sizeof(reloc));
+
+ n = 0;
+ for (int i = 0; i <= count; i++) {
+ obj[n].handle = gem_create(fd, 4096);
+ obj[n].offset = (1ull << (i + 12)) - 4096;
+ obj[n].offset = gen8_canonical_address(obj[i].offset);
+ obj[n].flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+
+ igt_debug("obj[%d] handle=%d, address=%llx\n",
+ n, obj[n].handle, (long long)obj[n].offset);
+
+ reloc[n].offset = 8 * (n + 1);
+ reloc[n].target_handle = obj[n].handle;
+ reloc[n].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+ reloc[n].presumed_offset = -1;
+ n++;
+ }
+ for (int i = 1; i < count; i++) {
+ obj[n].handle = gem_create(fd, 4096);
+ obj[n].offset = 1ull << (i + 12);
+ obj[n].offset = gen8_canonical_address(obj[n].offset);
+ obj[n].flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+
+ igt_debug("obj[%d] handle=%d, address=%llx\n",
+ n, obj[n].handle, (long long)obj[n].offset);
+
+ reloc[n].offset = 8 * (n + 1);
+ reloc[n].target_handle = obj[n].handle;
+ reloc[n].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+ reloc[n].presumed_offset = -1;
+ n++;
+ }
+ obj[n].handle = gem_create(fd, 4096);
+ obj[n].relocs_ptr = to_user_pointer(reloc);
+ obj[n].relocation_count = n;
+ gem_write(fd, obj[n].handle, 0, &bbe, sizeof(bbe));
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(obj);
+ execbuf.buffer_count = n + 1;
+
+ if (flags & ACTIVE) {
+ spin = igt_spin_batch_new(fd, 0, obj[n].handle);
+ if (!(flags & HANG))
+ igt_spin_batch_set_timeout(spin, NSEC_PER_SEC/100);
+ igt_assert(gem_bo_busy(fd, obj[n].handle));
+ }
+
+ gem_execbuf(fd, &execbuf);
+ igt_spin_batch_free(fd, spin);
+
+ for (int i = 0; i < n; i++) {
+ uint64_t offset;
+
+ offset = ~reloc[i].presumed_offset & address_mask;
+ gem_read(fd, obj[n].handle, reloc[i].offset,
+ &offset, has_64b_reloc(fd) ? 8 : 4);
+
+ igt_debug("obj[%d] handle=%d, offset=%llx, found=%llx, presumed=%llx\n",
+ i, obj[i].handle,
+ (long long)obj[i].offset,
+ (long long)offset,
+ (long long)reloc[i].presumed_offset);
+
+ igt_assert_eq_u64(obj[i].offset, offset);
+ if (reloc[i].presumed_offset == -1)
+ igt_warn("reloc.presumed_offset == -1\n");
+ else
+ igt_assert_eq_u64(reloc[i].presumed_offset, offset);
+ }
+
+ for (int i = 0; i <= n; i++)
+ gem_close(fd, obj[i].handle);
+}
+
static void basic_softpin(int fd)
{
struct drm_i915_gem_exec_object2 obj[2];
@@ -596,6 +702,12 @@ igt_main
}
}
+ if (!(f->flags & NORELOC)) {
+ igt_subtest_f("%srange%s",
+ f->basic ? "basic-" : "", f->name)
+ basic_range(fd, f->flags);
+ }
+
igt_fixture {
if (f->flags & HANG)
igt_disallow_hang(fd, hang);