[PATCH i-g-t 2/4] tests/gem_exec_reloc: Add GEM minimum page size helper

Janusz Krzysztofik janusz.krzysztofik at linux.intel.com
Thu Oct 24 17:44:26 UTC 2019


A number of tests assume 4kB minimum page size while using softpin.
That assumption may be wrong on future GEM backends with possibly
larger minimum page sizes.  As a result, those tests may either fail on
softpin at offsets which are incorrectly aligned, may silently skip
such incorrectly aligned addresses assuming them occupied by other
users, or may always succeed when examining invalid use patterns.

Provide a helper function that detects minimum page size and returns
the size order.  Tests may use it to calculate softpin offsets suitable
for actual hardware default backing store.

Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik at linux.intel.com>
---
 lib/ioctl_wrappers.c | 66 ++++++++++++++++++++++++++++++++++++++++++++
 lib/ioctl_wrappers.h |  1 +
 2 files changed, 67 insertions(+)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 628f8b83..9620ee56 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -54,6 +54,7 @@
 #include "intel_io.h"
 #include "igt_debugfs.h"
 #include "igt_sysfs.h"
+#include "igt_x86.h"
 #include "config.h"
 
 #ifdef HAVE_VALGRIND
@@ -1158,6 +1159,71 @@ bool gem_has_softpin(int fd)
 	return has_softpin;
 }
 
+/**
+ * gem_min_page_size_order:
+ * @fd: open i915 drm file descriptor
+ *
+ * This function detects the minimum size of a gem object allocated from
+ * a default backing store.  It is useful for calculating correctly aligned
+ * softpin offsets.
+ * Since size order to size conversion (size = 1 << order) is less trivial
+ * than the opposite, the function returns the size order as more handy.
+ *
+ * Returns:
+ * Size order of the minimum page size
+ */
+int gem_min_page_size_order(int fd)
+{
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	uint64_t gtt_size = gem_aperture_size(fd);
+	const uint32_t bbe = MI_BATCH_BUFFER_END;
+	int page_order = 12;
+	uint64_t page_size = 1ull << page_order; /* 4096 */
+	uint64_t offset = gtt_size;
+
+	/* no softpin => 4kB page size */
+	if (!gem_has_softpin(fd))
+		return page_order;
+
+	memset(&obj, 0, sizeof(obj));
+	memset(&execbuf, 0, sizeof(execbuf));
+
+	obj.handle = gem_create(fd, 4096);
+	obj.flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+
+	while (offset > page_size) {
+		while (page_size < offset) {
+			gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+			obj.offset = gen8_canonical_addr(offset - page_size);
+			if (!__gem_execbuf(fd, &execbuf)) {
+				igt_debug("page size=%llx, page order=%d\n",
+					  (long long)page_size, page_order);
+				break;
+			}
+
+			page_size <<= 1;
+			page_order++;
+		}
+		if (page_size < offset)
+			break;
+
+		/* address possibly occupied by other users, skip and retry */
+		offset >>= 1;
+		page_order = 12;
+		page_size = 1ull << page_order;
+	}
+
+	gem_close(fd, obj.handle);
+
+	igt_require(page_size < gtt_size); /* something must have gone wrong */
+
+	return page_order;
+}
+
 /**
  * gem_has_exec_fence:
  * @fd: open i915 drm file descriptor
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 03211c97..91690847 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -138,6 +138,7 @@ uint64_t gem_aperture_size(int fd);
 uint64_t gem_global_aperture_size(int fd);
 uint64_t gem_mappable_aperture_size(void);
 bool gem_has_softpin(int fd);
+int gem_min_page_size_order(int fd);
 bool gem_has_exec_fence(int fd);
 
 /* check functions which auto-skip tests by calling igt_skip() */
-- 
2.21.0



More information about the Intel-gfx-trybot mailing list