[igt-dev] [PATCH i-g-t 7/7] benchmarks/gem_exec_fault: Add softpin mode to support gens with ppgtt

Zbigniew Kempczyński zbigniew.kempczynski at intel.com
Fri Oct 8 06:54:32 UTC 2021


Alignment trick doesn't work properly for ppgtt gens - kernel is able
to keep previous offset and doesn't call unbind/bind. With softpin
on ppgtt we're able to enforce rebind and benchmark should behave
correctly on such gens.

To avoid inaccurate results kernel CONFIG_PROVE_LOCKING should be set
to N, otherwise kernel can call unbind/bind for same offset more than
one (backoff is not visible from userspace).

Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
Cc: Petri Latvala <petri.latvala at intel.com>
Cc: Ashutosh Dixit <ashutosh.dixit at intel.com>
---
 benchmarks/gem_exec_fault.c | 47 +++++++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/benchmarks/gem_exec_fault.c b/benchmarks/gem_exec_fault.c
index fe940b44c..40f11f4f1 100644
--- a/benchmarks/gem_exec_fault.c
+++ b/benchmarks/gem_exec_fault.c
@@ -43,7 +43,9 @@
 #include "drm.h"
 #include "drmtest.h"
 #include "i915/gem_create.h"
+#include "i915/gem_submission.h"
 #include "igt_stats.h"
+#include "intel_allocator.h"
 #include "intel_io.h"
 #include "intel_reg.h"
 #include "ioctl_wrappers.h"
@@ -74,11 +76,28 @@ static int loop(uint64_t size, unsigned ring, int reps, int ncpus,
 	unsigned nengine;
 	double *shared;
 	int fd;
+	bool has_ppgtt;
 
 	shared = mmap(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
 
 	fd = drm_open_driver(DRIVER_INTEL);
 
+	/*
+	 * For older gens .alignment = 1ull << 63 lead do bind/unbind,
+	 * what doesn't work for newer gens with ppgtt.
+	 * For ppgtt case we use reloc allocator which would just assigns
+	 * new offset for each batch. This way we enforce bind/unbind vma
+	 * for each execbuf.
+	 */
+	has_ppgtt = gem_uses_full_ppgtt(fd);
+	if (has_ppgtt) {
+		igt_info("Using softpin mode\n");
+		intel_allocator_multiprocess_start();
+	} else {
+		igt_assert(gem_allows_passing_alignment(fd));
+		igt_info("Using alignment mode\n");
+	}
+
 	memset(&obj, 0, sizeof(obj));
 	obj.handle = batch(fd, 4096);
 
@@ -92,6 +111,7 @@ static int loop(uint64_t size, unsigned ring, int reps, int ncpus,
 		if (__gem_execbuf(fd, &execbuf))
 			return 77;
 	}
+
 	/* let the small object leak; ideally blocking the low address */
 
 	nengine = 0;
@@ -106,7 +126,7 @@ static int loop(uint64_t size, unsigned ring, int reps, int ncpus,
 		engines[nengine++] = ring;
 
 	if (size > 1ul << 31)
-		obj.flags |= 1 << 3;
+		obj.flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
 
 	while (reps--) {
 		memset(shared, 0, 4096);
@@ -114,10 +134,14 @@ static int loop(uint64_t size, unsigned ring, int reps, int ncpus,
 		igt_fork(child, ncpus) {
 			struct timespec start, end;
 			unsigned count = 0;
+			uint64_t ahnd = 0;
 
 			obj.handle = batch(fd, size);
 			obj.offset = -1;
 
+			if (has_ppgtt)
+				ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC);
+
 			clock_gettime(CLOCK_MONOTONIC, &start);
 			do {
 				for (int inner = 0; inner < 1024; inner++) {
@@ -127,9 +151,14 @@ static int loop(uint64_t size, unsigned ring, int reps, int ncpus,
 					obj.alignment = 0;
 					gem_execbuf(fd, &execbuf);
 
-					/* fault out */
-					obj.alignment = 1ull << 63;
-					__gem_execbuf(fd, &execbuf);
+					if (ahnd) {
+						obj.offset = get_offset(ahnd, obj.handle, size, 0);
+						obj.flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+					} else {
+						/* fault out */
+						obj.alignment = 1ull << 63;
+						__gem_execbuf(fd, &execbuf);
+					}
 
 					clock_gettime(CLOCK_MONOTONIC, &end);
 					if (elapsed(&start, &end) >= timeout) {
@@ -144,6 +173,8 @@ static int loop(uint64_t size, unsigned ring, int reps, int ncpus,
 			shared[child] = 1e6*elapsed(&start, &end) / count / 2;
 
 			gem_close(fd, obj.handle);
+			if (ahnd)
+				intel_allocator_close(ahnd);
 		}
 		igt_waitchildren();
 
@@ -151,9 +182,17 @@ static int loop(uint64_t size, unsigned ring, int reps, int ncpus,
 			shared[ncpus] += shared[child];
 		printf("%7.3f\n", shared[ncpus] / ncpus);
 	}
+
+	if (has_ppgtt)
+		intel_allocator_multiprocess_stop();
+
 	return 0;
 }
 
+/*
+ * NOTE: Ensure prove locking in the kernel is off, otherwise results
+ * would be inaccurate.
+ */
 int main(int argc, char **argv)
 {
 	unsigned ring = I915_EXEC_RENDER;
-- 
2.26.0



More information about the igt-dev mailing list