[Intel-gfx] [PATCH i-g-t 2/4] tests/gem_pread: test reads from a bo not backed by struct page

Daniele Ceraolo Spurio daniele.ceraolospurio at intel.com
Thu Oct 12 22:30:42 UTC 2017


Using an imported vgem bo we can test reads from an object not backed
by struct page. These reads use different paths in the kernel.

While at it, extract some common code in an helper function and fix the
src vs dst naming (they are the other way around).

Suggested-by: Chris Wilson <chris at chris-wilson.co.uk>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
---
 tests/gem_pread.c | 160 +++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 111 insertions(+), 49 deletions(-)

diff --git a/tests/gem_pread.c b/tests/gem_pread.c
index 39a46ed..89a9a5d 100644
--- a/tests/gem_pread.c
+++ b/tests/gem_pread.c
@@ -26,6 +26,7 @@
  */
 
 #include "igt.h"
+#include "igt_vgem.h"
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -73,25 +74,91 @@ static const char *bytes_per_sec(char *buf, double v)
 	return buf;
 }
 
+static void do_read_loop(int fd, const char *name, uint32_t handle,
+			 uint32_t *dst, int size)
+{
+	int count;
+	double usecs;
+	char buf[100];
+	const char* bps;
+	unsigned i;
+
+	for (count = 1; count <= 1<<17; count <<= 1) {
+		struct timeval start, end;
+
+		memset(dst, 0, size);
+		gettimeofday(&start, NULL);
+		do_gem_read(fd, handle, dst, size, count);
+		gettimeofday(&end, NULL);
+		usecs = elapsed(&start, &end, count);
+		bps = bytes_per_sec(buf, size/usecs*1e6);
+		igt_info("Time to %s pread %d bytes x %6d:	%7.3fµs, %s\n",
+			 name, size, count, usecs, bps);
+		fflush(stdout);
+
+		for (i = 0; i < size / 4096; i++)
+			igt_assert_eq(dst[i * 1024], i);
+	}
+}
+
+static uint32_t create_i915_bo(int fd, uint64_t size)
+{
+	uint32_t handle = gem_create(fd, size);
+	uint32_t *ptr;
+	unsigned i;
+
+	ptr = gem_mmap__cpu(fd, handle, 0, size, PROT_WRITE);
+	gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	for (i = 0; i < size / 4096; i++)
+		ptr[i * 1024] = i;
+	munmap(ptr, size);
+	return handle;
+}
+
+/*
+ * imported BOs are not backed by struct page and therefore the preads go
+ * through different driver paths compared to a normal bo
+ */
+static uint32_t create_foreign_bo(int fd, uint64_t size)
+{
+	struct vgem_bo scratch;
+	int vgem;
+	uint32_t handle;
+	uint32_t *ptr;
+	unsigned i;
+
+	vgem = drm_open_driver(DRIVER_VGEM);
 
-uint32_t *src, dst;
-int fd, count;
+	scratch.width = 1024;
+	scratch.height = size / 4096;
+	scratch.bpp = 32;
+	handle = vgem_create_and_import(vgem, &scratch, fd, NULL);
+	igt_assert_eq(size, scratch.size);
+
+	ptr = vgem_mmap(vgem, &scratch, PROT_WRITE);
+	for (i = 0; i < size / 4096; i++)
+		ptr[i * 1024] = i;
+	munmap(ptr, scratch.size);
+
+	close(vgem);
+
+	return handle;
+}
 
 int main(int argc, char **argv)
 {
+	int fd;
+	uint32_t *dst;
+	uint32_t handle;
 	int object_size = 0;
-	double usecs;
-	char buf[100];
-	const char* bps;
 	const struct {
-		int level;
-		const char *name;
-	} cache[] = {
-		{ 0, "uncached" },
-		{ 1, "snoop" },
-		{ 2, "display" },
-		{ -1 },
-	}, *c;
+		const char *prefix;
+		uint32_t (*bo_create)(int fd, uint64_t size);
+	} modes[] = {
+		{ "", create_i915_bo },
+		{ "foreign-bo-", create_foreign_bo },
+		{ NULL, NULL }
+	}, *m;
 
 	igt_subtest_init(argc, argv);
 	igt_skip_on_simulation();
@@ -104,49 +171,44 @@ int main(int argc, char **argv)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
-
-		dst = gem_create(fd, object_size);
-		src = malloc(object_size);
-	}
-
-	igt_subtest("basic") {
-		for (count = 1; count <= 1<<17; count <<= 1) {
-			struct timeval start, end;
-
-			gettimeofday(&start, NULL);
-			do_gem_read(fd, dst, src, object_size, count);
-			gettimeofday(&end, NULL);
-			usecs = elapsed(&start, &end, count);
-			bps = bytes_per_sec(buf, object_size/usecs*1e6);
-			igt_info("Time to pread %d bytes x %6d:	%7.3fµs, %s\n",
-				 object_size, count, usecs, bps);
-			fflush(stdout);
-		}
+		dst = malloc(object_size);
+		igt_assert(dst);
 	}
 
-	for (c = cache; c->level != -1; c++) {
-		igt_subtest(c->name) {
-			gem_set_caching(fd, dst, c->level);
-
-			for (count = 1; count <= 1<<17; count <<= 1) {
-				struct timeval start, end;
-
-				gettimeofday(&start, NULL);
-				do_gem_read(fd, dst, src, object_size, count);
-				gettimeofday(&end, NULL);
-				usecs = elapsed(&start, &end, count);
-				bps = bytes_per_sec(buf, object_size/usecs*1e6);
-				igt_info("Time to %s pread %d bytes x %6d:	%7.3fµs, %s\n",
-					 c->name, object_size, count, usecs, bps);
-				fflush(stdout);
+	for (m = modes; m->bo_create != NULL; m++) {
+		igt_subtest_group {
+			const struct {
+				int level;
+				const char *name;
+			} cache[] = {
+				{ 0, "uncached" },
+				{ 1, "snoop" },
+				{ 2, "display" },
+				{ -1 },
+			}, *c;
+
+			igt_fixture
+				handle = m->bo_create(fd, object_size);
+
+			igt_subtest_f("%sbasic", m->prefix)
+				do_read_loop(fd, "basic", handle, dst,
+					     object_size);
+
+			for (c = cache; c->level != -1; c++) {
+				igt_subtest_f("%s%s", m->prefix, c->name) {
+					gem_set_caching(fd, handle, c->level);
+					do_read_loop(fd, c->name, handle, dst,
+						     object_size);
+				}
 			}
+
+			igt_fixture
+				gem_close(fd, handle);
 		}
 	}
 
 	igt_fixture {
-		free(src);
-		gem_close(fd, dst);
-
+		free(dst);
 		close(fd);
 	}
 
-- 
1.9.1



More information about the Intel-gfx mailing list