[igt-dev] [PATCH i-g-t v14 19/33] tests/gem_softpin: Verify allocator and execbuf pair work together
Zbigniew Kempczyński
zbigniew.kempczynski at intel.com
Thu Jan 14 12:22:19 UTC 2021
Exercise objects offsets produced by the allocator for execbuf
are valid and no EINVAL/ENOSPC occurs. Check it works properly
also for multiprocess allocations/execbufs for same context.
For full-ppgtt we disable softpin to verify offsets produced
by the allocator are valid and kernel doesn't want to relocate them.
Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
---
tests/i915/gem_softpin.c | 95 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+)
diff --git a/tests/i915/gem_softpin.c b/tests/i915/gem_softpin.c
index aba060a42..e1af29830 100644
--- a/tests/i915/gem_softpin.c
+++ b/tests/i915/gem_softpin.c
@@ -28,6 +28,7 @@
#include "i915/gem.h"
#include "igt.h"
+#include "intel_allocator.h"
#define EXEC_OBJECT_PINNED (1<<4)
#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3)
@@ -697,6 +698,91 @@ static void test_noreloc(int fd, enum sleep sleep, unsigned flags)
gem_close(fd, object[i].handle);
}
+static void __exec_using_allocator(uint64_t ahnd, int fd, int num_obj,
+ bool pinned)
+{
+ const uint32_t bbe = MI_BATCH_BUFFER_END;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_exec_object2 object[num_obj];
+ uint64_t stored_offsets[num_obj];
+ int i;
+
+ memset(object, 0, sizeof(object));
+ for (i = 0; i < num_obj; i++) {
+ uint32_t sz = (rand() % 15 + 1) * 4096;
+ if (i == num_obj - 1)
+ sz = 4096;
+ object[i].handle = gem_create(fd, sz);
+ object[i].offset = intel_allocator_alloc(ahnd, object[i].handle,
+ sz, 0);
+ object[i].offset = gen8_canonical_addr(object[i].offset);
+ object[i].flags = pinned ? EXEC_OBJECT_PINNED : 0;
+ if (object[i].offset >= 1ull << 32)
+ object[i].flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+ }
+ gem_write(fd, object[--i].handle, 0, &bbe, sizeof(bbe));
+
+ if (!pinned)
+ for (i = 0; i < num_obj; i++)
+ stored_offsets[i] = object[i].offset;
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(object);
+ execbuf.buffer_count = num_obj;
+ gem_execbuf(fd, &execbuf);
+
+ for (i = 0; i < num_obj; i++) {
+ intel_allocator_free(ahnd, object[i].handle);
+ gem_close(fd, object[i].handle);
+ }
+
+ /* Check kernel will keep offsets even pinned is not set. */
+ if (!pinned)
+ for (i = 0; i < num_obj; i++)
+ igt_assert_eq_u64(stored_offsets[i], object[i].offset);
+}
+
+static void test_allocator_basic(int fd)
+{
+ const int num_obj = 257;
+ uint64_t ahnd;
+
+ ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE);
+ __exec_using_allocator(ahnd, fd, num_obj, true);
+ igt_assert(intel_allocator_close(ahnd) == true);
+}
+
+static void test_allocator_nopin(int fd)
+{
+ const int num_obj = 257;
+ uint64_t ahnd;
+
+ ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE);
+ __exec_using_allocator(ahnd, fd, num_obj, false);
+ igt_assert(intel_allocator_close(ahnd) == true);
+}
+
+static void test_allocator_fork(int fd)
+{
+ uint64_t ahnd;
+
+ intel_allocator_multiprocess_start();
+
+ igt_fork(child, 8) {
+ ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE);
+ igt_until_timeout(2)
+ __exec_using_allocator(ahnd, fd, 17, true);
+ intel_allocator_close(ahnd);
+ }
+
+ igt_waitchildren();
+
+ intel_allocator_multiprocess_stop();
+
+ ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE);
+ igt_assert(intel_allocator_close(ahnd) == true);
+}
+
igt_main
{
int fd = -1;
@@ -727,6 +813,9 @@ igt_main
igt_subtest("full")
test_full(fd);
+
+ igt_subtest("allocator-nopin")
+ test_allocator_nopin(fd);
}
igt_subtest("softpin")
@@ -754,6 +843,12 @@ igt_main
igt_subtest("evict-hang")
test_evict_hang(fd);
+ igt_subtest("allocator-basic")
+ test_allocator_basic(fd);
+
+ igt_subtest("allocator-fork")
+ test_allocator_fork(fd);
+
igt_fixture
close(fd);
}
--
2.26.0
More information about the igt-dev
mailing list