[PATCH] lib/xe/xe_util: Creating the helper functions

Bommu Krishnaiah krishnaiah.bommu at intel.com
Sun Mar 31 18:59:49 UTC 2024


Creating the helper functions which can be reused by many tests,
as part of this patch xe_exec_compute_mode and xe_exec_fault_mode
are used this helper functions.

Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu at intel.com>
Cc: Janga Rahul Kumar <janga.rahul.kumar at intel.com>
Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray at intel.com>
Cc: Oak Zeng <oak.zeng at intel.com>
---
 lib/xe/xe_util.c                   | 194 +++++++++++++++++++++++++++++
 lib/xe/xe_util.h                   |  48 +++++++
 tests/intel/xe_exec_compute_mode.c | 190 ++++------------------------
 tests/intel/xe_exec_fault_mode.c   | 179 +++-----------------------
 4 files changed, 282 insertions(+), 329 deletions(-)

diff --git a/lib/xe/xe_util.c b/lib/xe/xe_util.c
index 050162b5e..17cd45e45 100644
--- a/lib/xe/xe_util.c
+++ b/lib/xe/xe_util.c
@@ -255,3 +255,197 @@ bool xe_is_gt_in_c6(int fd, int gt)
 
 	return strcmp(gt_c_state, "gt-c6") == 0;
 }
+
+struct cpu_va *create_xe_bo(int fd, uint32_t vm, uint32_t *bo,
+		uint32_t bo_size, uint64_t placement, unsigned int flags)
+{
+	struct cpu_va *data;
+
+	if (flags & USERPTR) {
+		if (flags & INVALIDATE) {
+			data = mmap((void *)MAP_ADDRESS, bo_size, PROT_READ | PROT_WRITE,
+					MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
+			igt_assert(data != MAP_FAILED);
+		} else {
+			data = aligned_alloc(xe_get_default_alignment(fd), bo_size);
+			igt_assert(data);
+		}
+	} else {
+		*bo = xe_bo_create(fd, flags & VM_FOR_BO ? vm : 0, bo_size, placement,
+				DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
+		data = xe_bo_map(fd, *bo, bo_size);
+	}
+
+	memset(data, 0, bo_size);
+
+	return data;
+}
+
+void create_exec_queue(int fd, uint32_t vm, uint32_t *exec_queues,
+		uint32_t *bind_exec_queues, int n_exec_queues,
+		struct drm_xe_engine_class_instance *eci, unsigned int flags)
+{
+	int i;
+
+	for (i = 0; i < n_exec_queues; i++) {
+		exec_queues[i] = xe_exec_queue_create(fd, vm, eci, 0);
+		if (flags & BIND_EXEC_QUEUE)
+			bind_exec_queues[i] = xe_bind_exec_queue_create(fd, vm, 0);
+		else
+			bind_exec_queues[i] = 0;
+	};
+}
+
+void xe_bo_bind(int fd, uint32_t vm, uint32_t bind_exec_queues, uint32_t bo,
+		uint32_t bo_size, uint64_t addr, struct drm_xe_sync *sync,
+		struct cpu_va *data, unsigned int flags)
+{
+	int64_t fence_timeout = igt_run_in_simulation() ? HUNDRED_SEC : ONE_SEC;
+
+	sync[0].addr = to_user_pointer(&data[0].vm_sync);
+	if (bo)
+		xe_vm_bind_async(fd, vm, bind_exec_queues, bo, 0, addr, bo_size, sync, 1);
+	else
+		xe_vm_bind_userptr_async(fd, vm, bind_exec_queues,
+				to_user_pointer(data), addr,
+				bo_size, sync, 1);
+
+	xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
+			bind_exec_queues, fence_timeout);
+	data[0].vm_sync = 0;
+
+	if (flags & PREFETCH) {
+		/* Should move to system memory */
+		xe_vm_prefetch_async(fd, vm, bind_exec_queues, 0, addr,
+				bo_size, sync, 1, 0);
+		xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
+				bind_exec_queues, fence_timeout);
+		data[0].vm_sync = 0;
+	}
+}
+
+void insert_store(uint64_t dst, struct cpu_va *data, uint32_t val, int i)
+{
+	int b = 0;
+	data[i].batch[b++] = MI_STORE_DWORD_IMM_GEN4;
+	data[i].batch[b++] = dst;
+	data[i].batch[b++] = dst >> 32;
+	data[i].batch[b++] = val;
+	data[i].batch[b++] = MI_BATCH_BUFFER_END;
+	igt_assert(b <= ARRAY_SIZE(data[i].batch));
+}
+
+void xe_execbuf(int fd, uint32_t vm, struct drm_xe_exec *exec, int n_execs,
+		uint32_t *exec_queues, uint32_t *bind_exec_queues,
+		int n_exec_queues, uint32_t bo, uint32_t bo_size,
+		struct drm_xe_sync *sync, uint64_t addr, struct cpu_va *data,
+		int *map_fd, unsigned int flags)
+{
+	int i;
+	int64_t fence_timeout = igt_run_in_simulation() ? HUNDRED_SEC : ONE_SEC;
+
+	for (i = 0; i < n_execs; i++) {
+		uint64_t batch_offset = (char *)&data[i].batch - (char *)data;
+		uint64_t batch_addr = addr + batch_offset;
+		uint64_t sdi_offset = (char *)&data[i].data - (char *)data;
+		uint64_t sdi_addr = addr + sdi_offset;
+		int e = i % n_exec_queues;
+
+		if (flags & INVALID_VA)
+			sdi_addr = 0x1fffffffffff000;
+
+		insert_store(sdi_addr, data, 0xc0ffee, i);
+
+		sync[0].addr = addr + (char *)&data[i].exec_sync - (char *)data;
+
+		exec->exec_queue_id = exec_queues[e];
+		exec->address = batch_addr;
+		xe_exec(fd, exec);
+
+		if (flags & REBIND && i + 1 != n_execs) {
+			xe_wait_ufence(fd, &data[i].exec_sync, USER_FENCE_VALUE,
+					exec_queues[e], fence_timeout);
+			xe_vm_unbind_async(fd, vm, bind_exec_queues[e], 0,
+					addr, bo_size, NULL, 0);
+
+			sync[0].addr = to_user_pointer(&data[0].vm_sync);
+			addr += bo_size;
+
+			if (bo)
+				xe_vm_bind_async(fd, vm, bind_exec_queues[e], bo,
+						0, addr, bo_size, sync, 1);
+			else
+				xe_vm_bind_userptr_async(fd, vm,
+						bind_exec_queues[e],
+						to_user_pointer(data),
+						addr, bo_size, sync, 1);
+
+			xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
+					bind_exec_queues[e], fence_timeout);
+			data[0].vm_sync = 0;
+		}
+
+		if (flags & INVALIDATE && i + 1 != n_execs) {
+			if (!(flags & RACE)) {
+				/*
+				 * Wait for exec completion and check data as
+				 * userptr will likely change to different
+				 * physical memory on next mmap call triggering
+				 * an invalidate.
+				 */
+				xe_wait_ufence(fd, &data[i].exec_sync,
+						USER_FENCE_VALUE, exec_queues[e],
+						fence_timeout);
+				igt_assert_eq(data[i].data, 0xc0ffee);
+			} else if (i * 2 != n_execs) {
+				/*
+				 * We issue 1 mmap which races against running
+				 * jobs. No real check here aside from this test
+				 * not faulting on the GPU.
+				 */
+				continue;
+			}
+
+			if (flags & RACE) {
+				*map_fd = open("/tmp", O_TMPFILE | O_RDWR,
+						0x666);
+				write(*map_fd, data, bo_size);
+				data = mmap((void *)MAP_ADDRESS, bo_size,
+						PROT_READ | PROT_WRITE, MAP_SHARED |
+						MAP_FIXED, *map_fd, 0);
+			} else {
+				data = mmap((void *)MAP_ADDRESS, bo_size,
+						PROT_READ | PROT_WRITE, MAP_SHARED |
+						MAP_FIXED | MAP_ANONYMOUS, -1, 0);
+			}
+
+			igt_assert(data != MAP_FAILED);
+		}
+	}
+}
+
+void xe_vm_unbind(int fd, uint32_t vm, uint32_t bind_exec_queues,
+		struct drm_xe_sync *sync, struct cpu_va *data, uint64_t addr,
+		uint32_t bo_size)
+{
+	int64_t fence_timeout = igt_run_in_simulation() ? HUNDRED_SEC : ONE_SEC;
+
+	sync[0].addr = to_user_pointer(&data[0].vm_sync);
+	xe_vm_unbind_async(fd, vm, bind_exec_queues, 0, addr, bo_size,
+			sync, 1);
+	xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
+			bind_exec_queues, fence_timeout);
+}
+
+void destory_exec_queue(int fd, uint32_t *exec_queues,
+		uint32_t *bind_exec_queues, int n_exec_queues)
+{
+	int i;
+
+	for (i = 0; i < n_exec_queues; i++) {
+		xe_exec_queue_destroy(fd, exec_queues[i]);
+		if (bind_exec_queues[i])
+			xe_exec_queue_destroy(fd, bind_exec_queues[i]);
+	}
+}
+
diff --git a/lib/xe/xe_util.h b/lib/xe/xe_util.h
index 6480ea01a..aa1b0dcc1 100644
--- a/lib/xe/xe_util.h
+++ b/lib/xe/xe_util.h
@@ -47,4 +47,52 @@ void xe_bind_unbind_async(int fd, uint32_t vm, uint32_t bind_engine,
 
 bool xe_is_gt_in_c6(int fd, int gt);
 
+
+#define USERPTR			(0x1 << 0)
+#define REBIND			(0x1 << 1)
+#define INVALIDATE		(0x1 << 2)
+#define RACE			(0x1 << 3)
+#define BIND_EXEC_QUEUE		(0x1 << 4)
+#define PREFETCH		(0x1 << 5)
+#define INVALID_FAULT		(0x1 << 6)
+#define INVALID_VA		(0x1 << 7)
+#define ENABLE_SCRATCH		(0x1 << 8)
+#define VM_FOR_BO		(0x1 << 9)
+#define EXEC_QUEUE_EARLY	(0x1 << 10)
+
+#define MAX_N_EXEC_QUEUES	16
+#define USER_FENCE_VALUE	0xdeadbeefdeadbeefull
+#define MAP_ADDRESS		0x00007fadeadbe000
+
+#define ONE_SEC		MS_TO_NS(1000)
+#define HUNDRED_SEC	MS_TO_NS(100000)
+
+struct cpu_va {
+	uint32_t batch[16];
+	uint64_t pad;
+	uint64_t vm_sync;
+	uint64_t exec_sync;
+	uint32_t data;
+};
+
+struct cpu_va *create_xe_bo(int fd, uint32_t vm, uint32_t *bo,
+		uint32_t bo_size, uint64_t placement,  unsigned int flags);
+void create_exec_queue(int fd, uint32_t vm, uint32_t *exec_queues,
+		uint32_t *bind_exec_queues, int n_exec_queues,
+		struct drm_xe_engine_class_instance *eci, unsigned int flags);
+void xe_bo_bind(int fd, uint32_t vm, uint32_t bind_exec_queues, uint32_t bo,
+		uint32_t bo_size, uint64_t addr, struct drm_xe_sync *sync,
+		struct cpu_va *data, unsigned int flags);
+void xe_execbuf(int fd, uint32_t vm, struct drm_xe_exec *exec, int n_execs,
+		uint32_t *exec_queues, uint32_t *bind_exec_queues,
+		int n_exec_queues, uint32_t bo, uint32_t bo_size,
+		struct drm_xe_sync *sync, uint64_t addr, struct cpu_va *data,
+		int *map_fd, unsigned int flags);
+void insert_store(uint64_t dst, struct cpu_va *data, uint32_t val, int i);
+void xe_vm_unbind(int fd, uint32_t vm, uint32_t bind_exec_queues,
+		struct drm_xe_sync *sync, struct cpu_va *data,
+		uint64_t addr, uint32_t bo_size);
+void destory_exec_queue(int fd, uint32_t *exec_queues,
+		uint32_t *bind_exec_queues, int n_exec_queues);
+
 #endif /* XE_UTIL_H */
diff --git a/tests/intel/xe_exec_compute_mode.c b/tests/intel/xe_exec_compute_mode.c
index 3ec848164..e8d82cc69 100644
--- a/tests/intel/xe_exec_compute_mode.c
+++ b/tests/intel/xe_exec_compute_mode.c
@@ -15,6 +15,7 @@
 #include "igt.h"
 #include "lib/igt_syncobj.h"
 #include "lib/intel_reg.h"
+#include "lib/xe/xe_util.h"
 #include <sys/ioctl.h>
 #include "xe_drm.h"
 
@@ -23,15 +24,6 @@
 #include "xe/xe_spin.h"
 #include <string.h>
 
-#define MAX_N_EXECQUEUES 	16
-#define USERPTR				(0x1 << 0)
-#define REBIND				(0x1 << 1)
-#define INVALIDATE			(0x1 << 2)
-#define RACE				(0x1 << 3)
-#define BIND_EXECQUEUE		(0x1 << 4)
-#define VM_FOR_BO			(0x1 << 5)
-#define EXEC_QUEUE_EARLY	(0x1 << 6)
-
 /**
  * SUBTEST: twice-%s
  * Description: Run %arg[1] compute machine test twice
@@ -88,7 +80,6 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 {
 	uint32_t vm;
 	uint64_t addr = 0x1a0000;
-#define USER_FENCE_VALUE	0xdeadbeefdeadbeefull
 	struct drm_xe_sync sync[1] = {
 		{ .type = DRM_XE_SYNC_TYPE_USER_FENCE,
 		  .flags = DRM_XE_SYNC_FLAG_SIGNAL,
@@ -99,161 +90,38 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 		.num_syncs = 1,
 		.syncs = to_user_pointer(sync),
 	};
-	uint32_t exec_queues[MAX_N_EXECQUEUES];
-	uint32_t bind_exec_queues[MAX_N_EXECQUEUES];
+	uint32_t exec_queues[MAX_N_EXEC_QUEUES];
+	uint32_t bind_exec_queues[MAX_N_EXEC_QUEUES];
 	size_t bo_size;
 	uint32_t bo = 0;
-	struct {
-		uint32_t batch[16];
-		uint64_t pad;
-		uint64_t vm_sync;
-		uint64_t exec_sync;
-		uint32_t data;
-	} *data;
-	int i, j, b;
+	struct cpu_va *data;
+	int i, j;
 	int map_fd = -1;
 	int64_t fence_timeout;
+	uint64_t placement;
 
-	igt_assert(n_exec_queues <= MAX_N_EXECQUEUES);
+	igt_assert(n_exec_queues <= MAX_N_EXEC_QUEUES);
 
 	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_FLAG_LR_MODE, 0);
 	bo_size = sizeof(*data) * n_execs;
 	bo_size = xe_bb_size(fd, bo_size);
 
-	for (i = 0; (flags & EXEC_QUEUE_EARLY) && i < n_exec_queues; i++) {
-		exec_queues[i] = xe_exec_queue_create(fd, vm, eci, 0);
-		if (flags & BIND_EXECQUEUE)
-			bind_exec_queues[i] =
-				xe_bind_exec_queue_create(fd, vm, 0);
-		else
-			bind_exec_queues[i] = 0;
-	};
+	if (flags & EXEC_QUEUE_EARLY)
+		create_exec_queue(fd, vm, exec_queues, bind_exec_queues, n_exec_queues, eci, flags);
 
-	if (flags & USERPTR) {
-#define	MAP_ADDRESS	0x00007fadeadbe000
-		if (flags & INVALIDATE) {
-			data = mmap((void *)MAP_ADDRESS, bo_size, PROT_READ |
-				    PROT_WRITE, MAP_SHARED | MAP_FIXED |
-				    MAP_ANONYMOUS, -1, 0);
-			igt_assert(data != MAP_FAILED);
-		} else {
-			data = aligned_alloc(xe_get_default_alignment(fd),
-					     bo_size);
-			igt_assert(data);
-		}
-	} else {
-		bo = xe_bo_create(fd, flags & VM_FOR_BO ? vm : 0,
-				  bo_size, vram_if_possible(fd, eci->gt_id),
-				  DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
-		data = xe_bo_map(fd, bo, bo_size);
-	}
-	memset(data, 0, bo_size);
+	placement = vram_if_possible(fd, eci->gt_id);
 
-	for (i = 0; !(flags & EXEC_QUEUE_EARLY) && i < n_exec_queues; i++) {
-		exec_queues[i] = xe_exec_queue_create(fd, vm, eci, 0);
-		if (flags & BIND_EXECQUEUE)
-			bind_exec_queues[i] =
-				xe_bind_exec_queue_create(fd, vm, 0);
-		else
-			bind_exec_queues[i] = 0;
-	};
+	data = create_xe_bo(fd, vm, &bo, bo_size, placement, flags);
 
-	sync[0].addr = to_user_pointer(&data[0].vm_sync);
-	if (bo)
-		xe_vm_bind_async(fd, vm, bind_exec_queues[0], bo, 0, addr,
-				 bo_size, sync, 1);
-	else
-		xe_vm_bind_userptr_async(fd, vm, bind_exec_queues[0],
-					 to_user_pointer(data), addr,
-					 bo_size, sync, 1);
-#define ONE_SEC	MS_TO_NS(1000)
-#define HUNDRED_SEC	MS_TO_NS(100000)
+	if(!(flags & EXEC_QUEUE_EARLY))
+		create_exec_queue(fd, vm, exec_queues, bind_exec_queues, n_exec_queues, eci, flags);
+
+	xe_bo_bind(fd, vm, bind_exec_queues[0], bo, bo_size, addr, sync, data, flags);
 
 	fence_timeout = igt_run_in_simulation() ? HUNDRED_SEC : ONE_SEC;
 
-	xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
-		       bind_exec_queues[0], fence_timeout);
-	data[0].vm_sync = 0;
-
-	for (i = 0; i < n_execs; i++) {
-		uint64_t batch_offset = (char *)&data[i].batch - (char *)data;
-		uint64_t batch_addr = addr + batch_offset;
-		uint64_t sdi_offset = (char *)&data[i].data - (char *)data;
-		uint64_t sdi_addr = addr + sdi_offset;
-		int e = i % n_exec_queues;
-
-		b = 0;
-		data[i].batch[b++] = MI_STORE_DWORD_IMM_GEN4;
-		data[i].batch[b++] = sdi_addr;
-		data[i].batch[b++] = sdi_addr >> 32;
-		data[i].batch[b++] = 0xc0ffee;
-		data[i].batch[b++] = MI_BATCH_BUFFER_END;
-		igt_assert(b <= ARRAY_SIZE(data[i].batch));
-
-		sync[0].addr = addr + (char *)&data[i].exec_sync - (char *)data;
-
-		exec.exec_queue_id = exec_queues[e];
-		exec.address = batch_addr;
-		xe_exec(fd, &exec);
-
-		if (flags & REBIND && i + 1 != n_execs) {
-			xe_wait_ufence(fd, &data[i].exec_sync, USER_FENCE_VALUE,
-				       exec_queues[e], fence_timeout);
-			xe_vm_unbind_async(fd, vm, bind_exec_queues[e], 0,
-					   addr, bo_size, NULL, 0);
-
-			sync[0].addr = to_user_pointer(&data[0].vm_sync);
-			addr += bo_size;
-			if (bo)
-				xe_vm_bind_async(fd, vm, bind_exec_queues[e], bo,
-						 0, addr, bo_size, sync, 1);
-			else
-				xe_vm_bind_userptr_async(fd, vm,
-							 bind_exec_queues[e],
-							 to_user_pointer(data),
-							 addr, bo_size, sync,
-							 1);
-			xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
-				       bind_exec_queues[e], fence_timeout);
-			data[0].vm_sync = 0;
-		}
-
-		if (flags & INVALIDATE && i + 1 != n_execs) {
-			if (!(flags & RACE)) {
-				/*
-				 * Wait for exec completion and check data as
-				 * userptr will likely change to different
-				 * physical memory on next mmap call triggering
-				 * an invalidate.
-				 */
-				xe_wait_ufence(fd, &data[i].exec_sync,
-					       USER_FENCE_VALUE, exec_queues[e],
-					       fence_timeout);
-				igt_assert_eq(data[i].data, 0xc0ffee);
-			} else if (i * 2 != n_execs) {
-				/*
-				 * We issue 1 mmap which races against running
-				 * jobs. No real check here aside from this test
-				 * not faulting on the GPU.
-				 */
-				continue;
-			}
-
-			if (flags & RACE) {
-				map_fd = open("/tmp", O_TMPFILE | O_RDWR,
-					      0x666);
-				write(map_fd, data, bo_size);
-				data = mmap((void *)MAP_ADDRESS, bo_size,
-					    PROT_READ | PROT_WRITE, MAP_SHARED |
-					    MAP_FIXED, map_fd, 0);
-			} else {
-				data = mmap((void *)MAP_ADDRESS, bo_size,
-					    PROT_READ | PROT_WRITE, MAP_SHARED |
-					    MAP_FIXED | MAP_ANONYMOUS, -1, 0);
-			}
-			igt_assert(data != MAP_FAILED);
-		}
-	}
+	xe_execbuf(fd, vm, &exec, n_execs, exec_queues, bind_exec_queues,
+			n_exec_queues, bo, bo_size, sync, addr, data, &map_fd, flags);
 
 	j = flags & INVALIDATE ? n_execs - 1 : 0;
 	for (i = j; i < n_execs; i++)
@@ -264,20 +132,12 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 	if (flags & INVALIDATE)
 		usleep(250000);
 
-	sync[0].addr = to_user_pointer(&data[0].vm_sync);
-	xe_vm_unbind_async(fd, vm, bind_exec_queues[0], 0, addr, bo_size,
-			   sync, 1);
-	xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
-		       bind_exec_queues[0], fence_timeout);
+	xe_vm_unbind(fd, vm, bind_exec_queues[0], sync, data, addr, bo_size);
 
 	for (i = j; i < n_execs; i++)
 		igt_assert_eq(data[i].data, 0xc0ffee);
 
-	for (i = 0; i < n_exec_queues; i++) {
-		xe_exec_queue_destroy(fd, exec_queues[i]);
-		if (bind_exec_queues[i])
-			xe_exec_queue_destroy(fd, bind_exec_queues[i]);
-	}
+	destory_exec_queue(fd, exec_queues, bind_exec_queues, n_exec_queues);
 
 	if (bo) {
 		munmap(data, bo_size);
@@ -492,14 +352,14 @@ igt_main
 		{ "userptr-rebind", USERPTR | REBIND },
 		{ "userptr-invalidate", USERPTR | INVALIDATE },
 		{ "userptr-invalidate-race", USERPTR | INVALIDATE | RACE },
-		{ "bindexecqueue", BIND_EXECQUEUE },
-		{ "bindexecqueue-userptr", BIND_EXECQUEUE | USERPTR },
-		{ "bindexecqueue-rebind",  BIND_EXECQUEUE | REBIND },
-		{ "bindexecqueue-userptr-rebind",  BIND_EXECQUEUE | USERPTR |
+		{ "bindexecqueue", BIND_EXEC_QUEUE },
+		{ "bindexecqueue-userptr", BIND_EXEC_QUEUE | USERPTR },
+		{ "bindexecqueue-rebind",  BIND_EXEC_QUEUE | REBIND },
+		{ "bindexecqueue-userptr-rebind",  BIND_EXEC_QUEUE | USERPTR |
 			REBIND },
-		{ "bindexecqueue-userptr-invalidate",  BIND_EXECQUEUE | USERPTR |
+		{ "bindexecqueue-userptr-invalidate",  BIND_EXEC_QUEUE | USERPTR |
 			INVALIDATE },
-		{ "bindexecqueue-userptr-invalidate-race", BIND_EXECQUEUE | USERPTR |
+		{ "bindexecqueue-userptr-invalidate-race", BIND_EXEC_QUEUE | USERPTR |
 			INVALIDATE | RACE },
 		{ NULL },
 	};
diff --git a/tests/intel/xe_exec_fault_mode.c b/tests/intel/xe_exec_fault_mode.c
index 40fe1743e..7b2fef224 100644
--- a/tests/intel/xe_exec_fault_mode.c
+++ b/tests/intel/xe_exec_fault_mode.c
@@ -16,24 +16,13 @@
 #include "igt.h"
 #include "lib/igt_syncobj.h"
 #include "lib/intel_reg.h"
+#include "lib/xe/xe_util.h"
 #include "xe_drm.h"
 
 #include "xe/xe_ioctl.h"
 #include "xe/xe_query.h"
 #include <string.h>
 
-#define MAX_N_EXEC_QUEUES	16
-
-#define USERPTR		(0x1 << 0)
-#define REBIND		(0x1 << 1)
-#define INVALIDATE	(0x1 << 2)
-#define RACE		(0x1 << 3)
-#define BIND_EXEC_QUEUE	(0x1 << 4)
-#define PREFETCH	(0x1 << 5)
-#define INVALID_FAULT	(0x1 << 6)
-#define INVALID_VA	(0x1 << 7)
-#define ENABLE_SCRATCH  (0x1 << 8)
-
 /**
  * SUBTEST: invalid-va
  * Description: Access invalid va and check for EIO through user fence.
@@ -99,7 +88,6 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 {
 	uint32_t vm;
 	uint64_t addr = 0x1a0000;
-#define USER_FENCE_VALUE	0xdeadbeefdeadbeefull
 	struct drm_xe_sync sync[1] = {
 		{ .type = DRM_XE_SYNC_TYPE_USER_FENCE, .flags = DRM_XE_SYNC_FLAG_SIGNAL,
 	          .timeline_value = USER_FENCE_VALUE },
@@ -113,14 +101,9 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 	uint32_t bind_exec_queues[MAX_N_EXEC_QUEUES];
 	size_t bo_size;
 	uint32_t bo = 0;
-	struct {
-		uint32_t batch[16];
-		uint64_t pad;
-		uint64_t vm_sync;
-		uint64_t exec_sync;
-		uint32_t data;
-	} *data;
-	int i, j, b;
+	struct cpu_va *data;
+	uint64_t placement;
+	int i, j;
 	int map_fd = -1;
 
 	igt_assert(n_exec_queues <= MAX_N_EXEC_QUEUES);
@@ -134,144 +117,19 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 	bo_size = sizeof(*data) * n_execs;
 	bo_size = xe_bb_size(fd, bo_size);
 
-	if (flags & USERPTR) {
-#define	MAP_ADDRESS	0x00007fadeadbe000
-		if (flags & INVALIDATE) {
-			data = mmap((void *)MAP_ADDRESS, bo_size, PROT_READ |
-				    PROT_WRITE, MAP_SHARED | MAP_FIXED |
-				    MAP_ANONYMOUS, -1, 0);
-			igt_assert(data != MAP_FAILED);
-		} else {
-			data = aligned_alloc(xe_get_default_alignment(fd),
-					     bo_size);
-			igt_assert(data);
-		}
-	} else {
-		if (flags & PREFETCH)
-			bo = xe_bo_create(fd, 0, bo_size,
-					  all_memory_regions(fd) |
-					  vram_if_possible(fd, 0),
-					  DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
-		else
-			bo = xe_bo_create(fd, 0, bo_size,
-					  vram_if_possible(fd, eci->gt_id),
-					  DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
-		data = xe_bo_map(fd, bo, bo_size);
-	}
-	memset(data, 0, bo_size);
-
-	for (i = 0; i < n_exec_queues; i++) {
-		exec_queues[i] = xe_exec_queue_create(fd, vm, eci, 0);
-		if (flags & BIND_EXEC_QUEUE)
-			bind_exec_queues[i] =
-				xe_bind_exec_queue_create(fd, vm, 0);
-		else
-			bind_exec_queues[i] = 0;
-	};
-
-	sync[0].addr = to_user_pointer(&data[0].vm_sync);
-	if (bo)
-		xe_vm_bind_async(fd, vm, bind_exec_queues[0], bo, 0, addr, bo_size, sync, 1);
-	else
-		xe_vm_bind_userptr_async(fd, vm, bind_exec_queues[0],
-					 to_user_pointer(data), addr,
-					 bo_size, sync, 1);
-#define ONE_SEC	MS_TO_NS(1000)
-	xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
-		       bind_exec_queues[0], ONE_SEC);
-	data[0].vm_sync = 0;
-
-	if (flags & PREFETCH) {
-		/* Should move to system memory */
-		xe_vm_prefetch_async(fd, vm, bind_exec_queues[0], 0, addr,
-				     bo_size, sync, 1, 0);
-		xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
-			       bind_exec_queues[0], ONE_SEC);
-		data[0].vm_sync = 0;
-	}
-
-	for (i = 0; i < n_execs; i++) {
-		uint64_t batch_offset = (char *)&data[i].batch - (char *)data;
-		uint64_t batch_addr = addr + batch_offset;
-		uint64_t sdi_offset = (char *)&data[i].data - (char *)data;
-		uint64_t sdi_addr = addr + sdi_offset;
-		int e = i % n_exec_queues;
+	placement = (flags & PREFETCH) ? all_memory_regions(fd) |
+		vram_if_possible(fd, 0) : vram_if_possible(fd, eci->gt_id);
 
-		b = 0;
-		if (flags & INVALID_VA)
-			sdi_addr = 0x1fffffffffff000;
+	data = create_xe_bo(fd, vm, &bo, bo_size, placement, flags);
 
-		data[i].batch[b++] = MI_STORE_DWORD_IMM_GEN4;
-		data[i].batch[b++] = sdi_addr;
-		data[i].batch[b++] = sdi_addr >> 32;
-		data[i].batch[b++] = 0xc0ffee;
-		data[i].batch[b++] = MI_BATCH_BUFFER_END;
-		igt_assert(b <= ARRAY_SIZE(data[i].batch));
+	create_exec_queue(fd, vm, exec_queues, bind_exec_queues,
+			n_exec_queues, eci, flags);
 
-		sync[0].addr = addr + (char *)&data[i].exec_sync - (char *)data;
+	xe_bo_bind(fd, vm, bind_exec_queues[0], bo, bo_size, addr, sync, data, flags);
 
-		exec.exec_queue_id = exec_queues[e];
-		exec.address = batch_addr;
-		xe_exec(fd, &exec);
+	xe_execbuf(fd, vm, &exec, n_execs, exec_queues, bind_exec_queues,
+			n_exec_queues, bo, bo_size, sync, addr, data, &map_fd, flags);
 
-		if (flags & REBIND && i + 1 != n_execs) {
-			xe_wait_ufence(fd, &data[i].exec_sync, USER_FENCE_VALUE,
-				       exec_queues[e], ONE_SEC);
-			xe_vm_unbind_async(fd, vm, bind_exec_queues[e], 0,
-					   addr, bo_size, NULL, 0);
-
-			sync[0].addr = to_user_pointer(&data[0].vm_sync);
-			addr += bo_size;
-			if (bo)
-				xe_vm_bind_async(fd, vm, bind_exec_queues[e], bo,
-						 0, addr, bo_size, sync, 1);
-			else
-				xe_vm_bind_userptr_async(fd, vm,
-							 bind_exec_queues[e],
-							 to_user_pointer(data),
-							 addr, bo_size, sync,
-							 1);
-			xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
-				       bind_exec_queues[e], ONE_SEC);
-			data[0].vm_sync = 0;
-		}
-
-		if (flags & INVALIDATE && i + 1 != n_execs) {
-			if (!(flags & RACE)) {
-				/*
-				 * Wait for exec completion and check data as
-				 * userptr will likely change to different
-				 * physical memory on next mmap call triggering
-				 * an invalidate.
-				 */
-				xe_wait_ufence(fd, &data[i].exec_sync,
-					       USER_FENCE_VALUE, exec_queues[e],
-					       ONE_SEC);
-				igt_assert_eq(data[i].data, 0xc0ffee);
-			} else if (i * 2 != n_execs) {
-				/*
-				 * We issue 1 mmap which races against running
-				 * jobs. No real check here aside from this test
-				 * not faulting on the GPU.
-				 */
-				continue;
-			}
-
-			if (flags & RACE) {
-				map_fd = open("/tmp", O_TMPFILE | O_RDWR,
-					      0x666);
-				write(map_fd, data, bo_size);
-				data = mmap((void *)MAP_ADDRESS, bo_size,
-					    PROT_READ | PROT_WRITE, MAP_SHARED |
-					    MAP_FIXED, map_fd, 0);
-			} else {
-				data = mmap((void *)MAP_ADDRESS, bo_size,
-					    PROT_READ | PROT_WRITE, MAP_SHARED |
-					    MAP_FIXED | MAP_ANONYMOUS, -1, 0);
-			}
-			igt_assert(data != MAP_FAILED);
-		}
-	}
 	if (!(flags & INVALID_FAULT)) {
 		int64_t timeout = ONE_SEC;
 
@@ -286,22 +144,15 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 							       exec_queues[i % n_exec_queues], &timeout), 0);
 		}
 	}
-	sync[0].addr = to_user_pointer(&data[0].vm_sync);
-	xe_vm_unbind_async(fd, vm, bind_exec_queues[0], 0, addr, bo_size,
-			   sync, 1);
-	xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE,
-		       bind_exec_queues[0], ONE_SEC);
+
+	xe_vm_unbind(fd, vm, bind_exec_queues[0], sync, data, addr, bo_size);
 
 	if (!(flags & INVALID_FAULT) && !(flags & INVALID_VA)) {
 		for (i = j; i < n_execs; i++)
 				igt_assert_eq(data[i].data, 0xc0ffee);
 	}
 
-	for (i = 0; i < n_exec_queues; i++) {
-		xe_exec_queue_destroy(fd, exec_queues[i]);
-		if (bind_exec_queues[i])
-			xe_exec_queue_destroy(fd, bind_exec_queues[i]);
-	}
+	destory_exec_queue(fd, exec_queues, bind_exec_queues, n_exec_queues);
 
 	if (bo) {
 		munmap(data, bo_size);
-- 
2.25.1



More information about the Intel-xe mailing list