All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test
@ 2019-12-13 21:54 Niranjana Vishwanathapura
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 1/7] drm-uapi: Import SVM UAPI Niranjana Vishwanathapura
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Niranjana Vishwanathapura @ 2019-12-13 21:54 UTC (permalink / raw)
  To: igt-dev
  Cc: kenneth.w.graunke, sanjay.k.kumar, jason.ekstrand, dave.hansen,
	jglisse, jon.bloomfield, daniel.vetter, dan.j.williams,
	ira.weiny, jgg

Shared Virtual Memory (SVM) allows the programmer to use a single virtual
address space which will be shared between threads executing on CPUs and GPUs.
It abstracts away from the user the location of the backing memory, and hence
simplifies the user programming model.
SVM supports two types of virtual memory allocation methods.
Runtime allocator requires a driver to provide memory allocation and
management interface like buffer object (BO) interface.
Whereas system allocator makes use of default OS memory allocation and
management support (like malloc()).

This patch series validates both SVM system and runtime allocator support.

The patch series adds driver interface and some test cases.
It tests for
 - Binding an address range or a BO in device page table
 - Migrating of pages to and from device memory
 - GPU access to memory through shared virtual address space
 - Implicit migration back to host memory upon CPU access
 - SVM capability and configurability on per vm basis
 - Large mappings
 - Both CPU copy and blitter copy of pages
 - Multiple context/vm support
 - Proper unbinding when the buffer is freed
 - Different allocation methods
 - Stress test
 - etc.

Niranjana (1):
  drm-uapi: Import SVM UAPI

Niranjana Vishwanathapura (6):
  lib: Add interface to support SVM
  tests/i915/svm: Add basic SVM RT allocator test support
  tests/i915/svm: Add mmap support for SVM RT allocator
  tests/i915/svm: Add basic SVM SYS allocator test support
  tests/i915/svm: Add multiple process tests
  tests/i915/svm: Add stress test

 include/drm-uapi/i915_drm.h |  74 ++++
 lib/i915/gem_context.c      |  27 ++
 lib/i915/gem_context.h      |   2 +
 lib/i915/gem_vm.c           |  48 +++
 lib/i915/gem_vm.h           |   6 +
 lib/ioctl_wrappers.c        | 154 +++++++
 lib/ioctl_wrappers.h        |  14 +
 tests/Makefile.sources      |   3 +
 tests/i915/i915_svm_basic.c | 808 ++++++++++++++++++++++++++++++++++++
 tests/meson.build           |   1 +
 10 files changed, 1137 insertions(+)
 create mode 100644 tests/i915/i915_svm_basic.c

-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [igt-dev] [RFC i-g-t 1/7] drm-uapi: Import SVM UAPI
  2019-12-13 21:54 [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjana Vishwanathapura
@ 2019-12-13 21:54 ` Niranjana Vishwanathapura
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 2/7] lib: Add interface to support SVM Niranjana Vishwanathapura
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Niranjana Vishwanathapura @ 2019-12-13 21:54 UTC (permalink / raw)
  To: igt-dev
  Cc: kenneth.w.graunke, sanjay.k.kumar, jason.ekstrand, dave.hansen,
	jglisse, jon.bloomfield, daniel.vetter, dan.j.williams,
	ira.weiny, jgg

From: Niranjana <nvishwa1@nvishwa1-DESK1.sc.intel.com>

Import Shared Virtual Memory (SVM) user API. It includes SVM capability
defintion and the bind and prefetch ioctl defintions.

Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com>
---
 include/drm-uapi/i915_drm.h | 74 +++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
index 9b72e821..de51c7e4 100644
--- a/include/drm-uapi/i915_drm.h
+++ b/include/drm-uapi/i915_drm.h
@@ -361,6 +361,10 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_GEM_VM_CREATE		0x3a
 #define DRM_I915_GEM_VM_DESTROY		0x3b
 #define DRM_I915_GEM_OBJECT_SETPARAM	DRM_I915_GEM_CONTEXT_SETPARAM
+#define DRM_I915_GEM_VM_GETPARAM        DRM_I915_GEM_CONTEXT_GETPARAM
+#define DRM_I915_GEM_VM_SETPARAM        DRM_I915_GEM_CONTEXT_SETPARAM
+#define DRM_I915_GEM_VM_BIND		0x3c
+#define DRM_I915_GEM_VM_PREFETCH	0x3d
 /* Must be kept compact -- no holes */
 
 #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
@@ -425,6 +429,10 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_VM_CREATE	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_CREATE, struct drm_i915_gem_vm_control)
 #define DRM_IOCTL_I915_GEM_VM_DESTROY	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_VM_DESTROY, struct drm_i915_gem_vm_control)
 #define DRM_IOCTL_I915_GEM_OBJECT_SETPARAM	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_OBJECT_SETPARAM, struct drm_i915_gem_object_param)
+#define DRM_IOCTL_I915_GEM_VM_GETPARAM		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_GETPARAM, struct drm_i915_gem_vm_param)
+#define DRM_IOCTL_I915_GEM_VM_SETPARAM		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_SETPARAM, struct drm_i915_gem_vm_param)
+#define DRM_IOCTL_I915_GEM_VM_BIND		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_VM_PREFETCH		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_PREFETCH, struct drm_i915_gem_vm_prefetch)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
@@ -622,6 +630,9 @@ typedef struct drm_i915_irq_wait {
  */
 #define I915_PARAM_PERF_REVISION	54
 
+/* Shared Virtual Memory (SVM) support capability */
+#define I915_PARAM_HAS_SVM		55
+
 /* Must be kept compact -- no holes and well documented */
 
 typedef struct drm_i915_getparam {
@@ -1848,6 +1859,17 @@ struct drm_i915_gem_vm_control {
 	__u32 vm_id;
 };
 
+struct drm_i915_gem_vm_param {
+	__u32 vm_id;
+	__u32 rsvd;
+
+#define I915_VM_PARAM     (2ull << 32)
+#define I915_GEM_VM_PARAM_SVM   0x1
+	__u64 param;
+
+	__u64 value;
+};
+
 struct drm_i915_reg_read {
 	/*
 	 * Register offset.
@@ -2399,6 +2421,58 @@ struct drm_i915_query_memory_region_info {
 	struct drm_i915_memory_region_info regions[];
 };
 
+/**
+ * struct drm_i915_gem_vm_bind
+ *
+ * Bind an object/buffer in a vm's page table.
+ */
+struct drm_i915_gem_vm_bind {
+	/** VA start to bind **/
+	__u64 start;
+
+	/**
+	 * VA length to [un]bind
+	 * length only required while binding buffers.
+	 */
+	__u64 length;
+
+	/** Type of memory to [un]bind **/
+	__u32 type;
+#define I915_GEM_VM_BIND_SVM_OBJ      0
+#define I915_GEM_VM_BIND_SVM_BUFFER   1
+
+	/** Object handle to [un]bind for I915_GEM_VM_BIND_SVM_OBJ type **/
+	__u32 handle;
+
+	/** vm to [un]bind **/
+	__u32 vm_id;
+
+	/** Flags **/
+	__u32 flags;
+#define I915_GEM_VM_BIND_UNBIND      (1 << 0)
+#define I915_GEM_VM_BIND_READONLY    (1 << 1)
+};
+
+/**
+ * struct drm_i915_gem_vm_prefetch
+ *
+ * Prefetch an address range to a memory region.
+ */
+struct drm_i915_gem_vm_prefetch {
+	/** Type of memory to prefetch **/
+	__u32 type;
+#define I915_GEM_VM_PREFETCH_SVM_BUFFER   0
+
+	/** Memory region to prefetch to **/
+	__u32 region;
+
+	/** VA start to prefetch **/
+	__u64 start;
+
+	/** VA length to prefetch **/
+	__u64 length;
+};
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [igt-dev] [RFC i-g-t 2/7] lib: Add interface to support SVM
  2019-12-13 21:54 [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjana Vishwanathapura
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 1/7] drm-uapi: Import SVM UAPI Niranjana Vishwanathapura
@ 2019-12-13 21:54 ` Niranjana Vishwanathapura
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 3/7] tests/i915/svm: Add basic SVM RT allocator test support Niranjana Vishwanathapura
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Niranjana Vishwanathapura @ 2019-12-13 21:54 UTC (permalink / raw)
  To: igt-dev
  Cc: kenneth.w.graunke, sanjay.k.kumar, jason.ekstrand, dave.hansen,
	jglisse, jon.bloomfield, daniel.vetter, dan.j.williams,
	ira.weiny, jgg

Add required interfaces to support Shared Virtual Memory (SVM)
functionality. It includes SVM capability handling functions
and the bind and prefetch ioctl wrappers.

Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com>
---
 lib/i915/gem_context.c |  27 ++++++++
 lib/i915/gem_context.h |   2 +
 lib/i915/gem_vm.c      |  48 +++++++++++++
 lib/i915/gem_vm.h      |   6 ++
 lib/ioctl_wrappers.c   | 154 +++++++++++++++++++++++++++++++++++++++++
 lib/ioctl_wrappers.h   |  14 ++++
 6 files changed, 251 insertions(+)

diff --git a/lib/i915/gem_context.c b/lib/i915/gem_context.c
index 1fae5191..e202b47a 100644
--- a/lib/i915/gem_context.c
+++ b/lib/i915/gem_context.c
@@ -403,3 +403,30 @@ bool gem_context_has_engine(int fd, uint32_t ctx, uint64_t engine)
 
 	return __gem_execbuf(fd, &execbuf) == -ENOENT;
 }
+
+uint32_t gem_ctx_get_vm(int fd, uint32_t ctx_id)
+{
+	struct drm_i915_gem_context_param arg;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.param = I915_CONTEXT_PARAM_VM;
+	arg.ctx_id = ctx_id;
+	gem_context_get_param(fd, &arg);
+	igt_assert(arg.value);
+
+	return arg.value;
+}
+
+uint32_t gem_ctx_set_vm(int fd, uint32_t ctx_id, uint32_t vm_id)
+{
+	struct drm_i915_gem_context_param arg;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.param = I915_CONTEXT_PARAM_VM;
+	arg.ctx_id = ctx_id;
+	arg.value = vm_id;
+	gem_context_set_param(fd, &arg);
+	igt_assert(arg.value);
+
+	return arg.value;
+}
diff --git a/lib/i915/gem_context.h b/lib/i915/gem_context.h
index c0d4c961..4cfc6ed8 100644
--- a/lib/i915/gem_context.h
+++ b/lib/i915/gem_context.h
@@ -68,4 +68,6 @@ void gem_context_set_persistence(int i915, uint32_t ctx, bool state);
 
 bool gem_context_has_engine(int fd, uint32_t ctx, uint64_t engine);
 
+uint32_t gem_ctx_get_vm(int fd, uint32_t ctx_id);
+uint32_t gem_ctx_set_vm(int fd, uint32_t ctx_id, uint32_t vm_id);
 #endif /* GEM_CONTEXT_H */
diff --git a/lib/i915/gem_vm.c b/lib/i915/gem_vm.c
index 9a022a56..64e6a319 100644
--- a/lib/i915/gem_vm.c
+++ b/lib/i915/gem_vm.c
@@ -128,3 +128,51 @@ void gem_vm_destroy(int i915, uint32_t vm_id)
 {
 	igt_assert_eq(__gem_vm_destroy(i915, vm_id), 0);
 }
+
+int __gem_vm_set_param(int fd, struct drm_i915_gem_vm_param *p)
+{
+	int err = 0;
+
+	if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_VM_SETPARAM, p)) {
+		err = -errno;
+		igt_assume(err);
+	}
+
+	errno = 0;
+	return err;
+}
+
+/**
+ * gem_vm_set_param:
+ * @fd: open i915 drm file descriptor
+ * @param: i915 vm parameter
+ *
+ * Feature test macro to query whether context parameter support for @param
+ * is available. Automatically skips through igt_require() if not.
+ */
+void gem_vm_set_param(int fd, struct drm_i915_gem_vm_param *p)
+{
+	igt_assert_eq(__gem_vm_set_param(fd, p), 0);
+}
+
+void gem_vm_enable_svm(int fd, uint32_t vm_id)
+{
+	struct drm_i915_gem_vm_param arg;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.param = (I915_VM_PARAM | I915_GEM_VM_PARAM_SVM);
+	arg.vm_id = vm_id;
+	arg.value = 1;
+	gem_vm_set_param(fd, &arg);
+}
+
+void gem_vm_disable_svm(int fd, uint32_t vm_id)
+{
+	struct drm_i915_gem_vm_param arg;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.param = (I915_VM_PARAM | I915_GEM_VM_PARAM_SVM);
+	arg.vm_id = vm_id;
+	arg.value = 0;
+	gem_vm_set_param(fd, &arg);
+}
diff --git a/lib/i915/gem_vm.h b/lib/i915/gem_vm.h
index 27af899d..bb279483 100644
--- a/lib/i915/gem_vm.h
+++ b/lib/i915/gem_vm.h
@@ -35,4 +35,10 @@ int __gem_vm_create(int i915, uint32_t *vm_id);
 void gem_vm_destroy(int i915, uint32_t vm_id);
 int __gem_vm_destroy(int i915, uint32_t vm_id);
 
+void gem_vm_set_param(int fd, struct drm_i915_gem_vm_param *p);
+int __gem_vm_set_param(int fd, struct drm_i915_gem_vm_param *p);
+
+void gem_vm_enable_svm(int fd, uint32_t vm_id);
+void gem_vm_disable_svm(int fd, uint32_t vm_id);
+
 #endif /* GEM_VM_H */
diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 627717d2..3c42581d 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -1454,3 +1454,157 @@ int __kms_addfb(int fd, uint32_t handle,
 
 	return ret < 0 ? -errno : ret;
 }
+
+/* SVM */
+
+bool igt_has_svm(int fd)
+{
+	int val = -1;
+	struct drm_i915_getparam gp = {
+		.param = I915_PARAM_HAS_SVM,
+		.value = &val,
+	};
+	ioctl(fd, DRM_IOCTL_I915_GETPARAM , &gp);
+	return val > 0;
+}
+
+void igt_require_svm(int fd)
+{
+	igt_require(igt_has_svm(fd));
+}
+
+int __gem_svm_bind(int fd, uint64_t start, uint32_t handle,
+		   uint32_t vm_id, uint32_t flags)
+{
+	struct drm_i915_gem_vm_bind bind;
+	int err = 0;
+
+	memset(&bind, 0, sizeof(bind));
+	bind.start = start;
+	bind.type = I915_GEM_VM_BIND_SVM_OBJ;
+	bind.handle = handle;
+	bind.vm_id = vm_id;
+	bind.flags = flags;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_VM_BIND, &bind))
+		err = -errno;
+	return err;
+}
+
+/**
+ * gem_svm_bind:
+ * @fd: open i915 drm file descriptor
+ * @start: VA to bind
+ * @handle: object handle
+ * @vm_id: address space id
+ * @rdonly: read only
+ *
+ * This wraps the BIND ioctl to bind an object to the specified address space.
+ */
+void gem_svm_bind(int fd, uint64_t start, uint32_t handle,
+		  uint32_t vm_id, bool rdonly)
+{
+	uint32_t flags = rdonly ? I915_GEM_VM_BIND_READONLY : 0;
+
+	igt_assert_eq(__gem_svm_bind(fd, start, handle, vm_id, flags), 0);
+}
+
+/**
+ * gem_svm_unbind:
+ * @fd: open i915 drm file descriptor
+ * @handle: object handle
+ * @vm_id: address space id
+ *
+ * This wraps the BIND ioctl to unbind an object from the
+ * specified address space.
+ */
+void gem_svm_unbind(int fd, uint32_t handle, uint32_t vm_id)
+{
+	igt_assert_eq(__gem_svm_bind(fd, 0, handle, vm_id,
+				     I915_GEM_VM_BIND_UNBIND), 0);
+}
+
+int __svm_bind(int fd, const void *buf, uint64_t length,
+	       uint32_t vm_id, uint32_t flags)
+{
+	struct drm_i915_gem_vm_bind bind;
+	int err = 0;
+
+	memset(&bind, 0, sizeof(bind));
+	bind.start = (uint64_t)buf;
+	bind.length = length;
+	bind.type = I915_GEM_VM_BIND_SVM_BUFFER;
+	bind.vm_id = vm_id;
+	bind.flags = flags;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_VM_BIND, &bind))
+		err = -errno;
+	return err;
+}
+
+/**
+ * svm_bind:
+ * @fd: open i915 drm file descriptor
+ * @buf: pointer to the data to write into the buffer
+ * @length: size of the subrange
+ * @vm_id: address space id
+ * @rdonly: read only
+ *
+ * This wraps the BIND ioctl to bind an address range to the
+ * specified address space.
+ */
+void svm_bind(int fd, const void *buf, uint64_t length,
+	      uint32_t vm_id, bool rdonly)
+{
+	uint32_t flags = rdonly ? I915_GEM_VM_BIND_READONLY : 0;
+
+	igt_assert_eq(__svm_bind(fd, buf, length, vm_id, flags), 0);
+}
+
+/**
+ * svm_unbind:
+ * @fd: open i915 drm file descriptor
+ * @start: VA to bind
+ * @buf: pointer to the data to write into the buffer
+ * @length: size of the subrange
+ * @vm_id: address space id
+ *
+ * This wraps the BIND ioctl to unbind an address range from the
+ * specified address space.
+ */
+void svm_unbind(int fd, const void *buf, uint64_t length, uint32_t vm_id)
+{
+	igt_assert_eq(__svm_bind(fd, buf, length, vm_id,
+				 I915_GEM_VM_BIND_UNBIND), 0);
+}
+
+int __svm_prefetch(int fd, const void *buf, uint64_t length, uint32_t region)
+{
+	struct drm_i915_gem_vm_prefetch prefetch;
+	int err = 0;
+
+	memset(&prefetch, 0, sizeof(prefetch));
+	prefetch.type = I915_GEM_VM_PREFETCH_SVM_BUFFER;
+	prefetch.start = (uint64_t)buf;
+	prefetch.length = length;
+	prefetch.region = region;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_VM_PREFETCH, &prefetch))
+		err = -errno;
+	return err;
+}
+
+/**
+ * svm_prefetch:
+ * @fd: open i915 drm file descriptor
+ * @buf: pointer to the data to write into the buffer
+ * @length: size of the subrange
+ * @region: memory region
+ *
+ * This wraps the VM_PREFETCH ioctl, which is to prefetch specified
+ * memory range to the specified memory region.
+ */
+void svm_prefetch(int fd, const void *buf, uint64_t length, uint32_t region)
+{
+	igt_assert_eq(__svm_prefetch(fd, buf, length, region), 0);
+}
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 86743ace..14736a20 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -85,6 +85,18 @@ void gem_execbuf_wr(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
 int __gem_execbuf_wr(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
 void gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
 int __gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
+int __gem_svm_bind(int fd, uint64_t start, uint32_t handle,
+		   uint32_t vm_id, uint32_t flags);
+void gem_svm_bind(int fd, uint64_t start, uint32_t handle,
+		  uint32_t vm_id, bool rdonly);
+void gem_svm_unbind(int fd, uint32_t handle, uint32_t vm_id);
+int __svm_bind(int fd, const void *buf, uint64_t length,
+	       uint32_t vm_id, uint32_t flags);
+void svm_bind(int fd, const void *buf, uint64_t length,
+	      uint32_t vm_id, bool rdonly);
+void svm_unbind(int fd, const void *buf, uint64_t length, uint32_t vm_id);
+int __svm_prefetch(int fd, const void *buf, uint64_t length, uint32_t region);
+void svm_prefetch(int fd, const void *buf, uint64_t length, uint32_t region);
 
 #ifndef I915_GEM_DOMAIN_WC
 #define I915_GEM_DOMAIN_WC 0x80
@@ -141,6 +153,8 @@ uint64_t gem_global_aperture_size(int fd);
 uint64_t gem_mappable_aperture_size(void);
 bool gem_has_softpin(int fd);
 bool gem_has_exec_fence(int fd);
+bool igt_has_svm(int fd);
+void igt_require_svm(int fd);
 
 /* check functions which auto-skip tests by calling igt_skip() */
 void gem_require_caching(int fd);
-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [igt-dev] [RFC i-g-t 3/7] tests/i915/svm: Add basic SVM RT allocator test support
  2019-12-13 21:54 [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjana Vishwanathapura
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 1/7] drm-uapi: Import SVM UAPI Niranjana Vishwanathapura
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 2/7] lib: Add interface to support SVM Niranjana Vishwanathapura
@ 2019-12-13 21:54 ` Niranjana Vishwanathapura
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 4/7] tests/i915/svm: Add mmap support for SVM RT allocator Niranjana Vishwanathapura
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Niranjana Vishwanathapura @ 2019-12-13 21:54 UTC (permalink / raw)
  To: igt-dev
  Cc: kenneth.w.graunke, sanjay.k.kumar, jason.ekstrand, dave.hansen,
	jglisse, jon.bloomfield, daniel.vetter, dan.j.williams,
	ira.weiny, jgg

Add basic tests for Shared Virtual Memory (SVM) runtime (RT) allocator
functionality. Explicitly bind the buffer objects in device page table
using a shared virtual address and have GPU copy the data from a source
buffer object to destination buffer object. Softpin the batch buffer.
Test for different buffer sizes, allocation method and with multiple
contexts.

Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/Makefile.sources      |   3 +
 tests/i915/i915_svm_basic.c | 447 ++++++++++++++++++++++++++++++++++++
 tests/meson.build           |   1 +
 3 files changed, 451 insertions(+)
 create mode 100644 tests/i915/i915_svm_basic.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 806eb02d..40f05605 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -478,6 +478,9 @@ gem_workarounds_SOURCES = i915/gem_workarounds.c
 TESTS_progs += gem_write_read_ring_switch
 gem_write_read_ring_switch_SOURCES = i915/gem_write_read_ring_switch.c
 
+TESTS_progs += i915_svm_basic
+i915_svm_basic_SOURCES = i915/i915_svm_basic.c
+
 TESTS_progs += gen3_mixed_blits
 gen3_mixed_blits_SOURCES = i915/gen3_mixed_blits.c
 
diff --git a/tests/i915/i915_svm_basic.c b/tests/i915/i915_svm_basic.c
new file mode 100644
index 00000000..66949039
--- /dev/null
+++ b/tests/i915/i915_svm_basic.c
@@ -0,0 +1,447 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2019 Intel Corporation. All rights reserved.
+ */
+
+/** @file i915_svm_basic.c
+ *
+ * This is the basic test for Shared Virtual Memory (SVM) functionality.
+ *
+ * The goal is to simply ensure that basics work.
+ * This test in part is derived from gem_exec_blt.c
+ */
+
+#include "igt.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include "drm.h"
+#include "i915/gem_vm.h"
+
+#define PAGE_SIZE   4096
+#define PAGE_SHIFT  12
+
+#define COPY_BLT_CMD		(2<<29|0x53<<22|0x6)
+#define BLT_WRITE_ALPHA		(1<<21)
+#define BLT_WRITE_RGB		(1<<20)
+
+#define LOCAL_I915_EXEC_NO_RELOC   (1<<11)
+#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
+
+#define DEFAULT_BUFF_SIZE  (4 * PAGE_SIZE)
+#define BATCH_VA_STRIDE    PAGE_SIZE
+
+#define MAX_CTXTS   4
+
+#define svm_info    igt_info
+#define svm_debug   igt_debug
+
+/* gen8_canonical_addr
+ * Used to convert any address into canonical form, i.e. [63:48] == [47].
+ * Based on kernel's sign_extend64 implementation.
+ * @address - a virtual address
+ */
+#define GEN8_HIGH_ADDRESS_BIT 47
+static uint64_t gen8_canonical_addr(uint64_t address)
+{
+	__u8 shift = 63 - GEN8_HIGH_ADDRESS_BIT;
+	return (__s64)(address << shift) >> shift;
+}
+
+static inline uint32_t lower_32_bits(uint64_t x)
+{
+	return x & 0xffffffff;
+}
+
+static inline uint32_t upper_32_bits(uint64_t x)
+{
+	return x >> 32;
+}
+
+static void print_buffer(void *buf, uint32_t size,
+			 const char *str, bool full)
+{
+	uint32_t i = 0;
+
+	svm_debug("Printing %s 0x%lx size 0x%x\n", str, (uint64_t)buf, size);
+	while (i < size) {
+		uint32_t *b = buf + i;
+
+		svm_debug("\t%s[0x%04x]: 0x%08x 0x%08x 0x%08x 0x%08x %s\n",
+			  str, i, b[0], b[1], b[2], b[3], full ? "" : "...");
+		i += full ? 16 : PAGE_SIZE;
+	}
+}
+
+static void print_object(int fd, uint32_t handle, uint32_t size,
+			 const char *str, bool full)
+{
+	void *buf;
+
+	buf = malloc(size);
+	gem_read(fd, handle, 0, buf, size);
+	print_buffer(buf, size, str, full);
+	free(buf);
+}
+
+static int objcmp(int fd, uint32_t src, uint32_t dst, uint32_t size)
+{
+	void *buf_src, *buf_dst;
+	int ret;
+
+	buf_src = malloc(size);
+	buf_dst = malloc(size);
+	gem_read(fd, src, 0, buf_src, size);
+	gem_read(fd, dst, 0, buf_dst, size);
+	ret = memcmp(buf_src, buf_dst, size);
+	free(buf_src);
+	free(buf_dst);
+	return ret;
+}
+
+static int gem_linear_blt(int devid, uint32_t *batch, void *src,
+			  void *dst, uint32_t length)
+{
+	uint32_t *b = batch;
+	int height = length / (16 * 1024);
+	uint64_t src_va = (uint64_t)src;
+	uint64_t dst_va = (uint64_t)dst;
+
+	igt_assert_lte(height, 1 << 16);
+
+	if (height) {
+		int i = 0;
+		b[i++] = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB;
+		if (intel_gen(devid) >= 8)
+			b[i-1]+=2;
+		b[i++] = 0xcc << 16 | 1 << 25 | 1 << 24 | (16*1024);
+		b[i++] = 0;
+		b[i++] = height << 16 | (4*1024);
+		b[i++] = lower_32_bits(dst_va);
+		if (intel_gen(devid) >= 8)
+			b[i++] = upper_32_bits(dst_va);
+
+		b[i++] = 0;
+		b[i++] = 16*1024;
+		b[i++] = lower_32_bits(src_va);
+		if (intel_gen(devid) >= 8)
+			b[i++] = upper_32_bits(src_va);
+
+		b += i;
+		length -= height * 16*1024;
+	}
+
+	if (length) {
+		int i = 0;
+		b[i++] = COPY_BLT_CMD | BLT_WRITE_ALPHA | BLT_WRITE_RGB;
+		if (intel_gen(devid) >= 8)
+			b[i-1]+=2;
+		b[i++] = 0xcc << 16 | 1 << 25 | 1 << 24 | (16*1024);
+		b[i++] = height << 16;
+		b[i++] = (1+height) << 16 | (length / 4);
+		b[i++] = lower_32_bits(dst_va);
+		if (intel_gen(devid) >= 8)
+			b[i++] = upper_32_bits(dst_va);
+
+		b[i++] = height << 16;
+		b[i++] = 16*1024;
+		b[i++] = lower_32_bits(src_va);
+		if (intel_gen(devid) >= 8)
+			b[i++] = upper_32_bits(src_va);
+
+		b += i;
+	}
+
+	b[0] = MI_BATCH_BUFFER_END;
+	b[1] = 0;
+
+	return (b + 2 - batch) * sizeof(uint32_t);
+}
+
+/* Softpin batch buffer in non-conflicting higher address space */
+static uint64_t get_batch_va(int fd)
+{
+	struct drm_i915_gem_context_param arg = { 0 };
+
+	arg.param = I915_CONTEXT_PARAM_GTT_SIZE;
+	gem_context_get_param(fd, &arg);
+	return gen8_canonical_addr(arg.value >> 1);
+}
+
+static void __gem_copy(int fd, uint32_t src_obj, uint32_t dst_obj,
+		       void *src, void *dst, uint32_t offset, uint32_t size,
+		       uint32_t ctx_id, uint32_t handle, uint64_t batch_va)
+{
+	struct drm_i915_gem_exec_object2 exec[3] = { 0 };
+	struct drm_i915_gem_execbuffer2 execbuf;
+	uint32_t buf[20], len, i = 0, ring = 0;
+	int devid = intel_get_drm_devid(fd);
+
+	len = gem_linear_blt(devid, buf, src + offset, dst + offset, size);
+
+	gem_write(fd, handle, 0, buf, len);
+	print_buffer(buf, len, "batch", true);
+	if (src_obj) {
+		exec[i].handle = src_obj;
+		exec[i].offset = (uint64_t)src;
+		exec[i++].flags = EXEC_OBJECT_PINNED |
+				  EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+	}
+	if (dst_obj) {
+		exec[i].handle = dst_obj;
+		exec[i].offset = (uint64_t)dst;
+		exec[i++].flags = EXEC_OBJECT_PINNED |
+				  EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+	}
+	exec[i].handle = handle;
+	exec[i].offset = batch_va;
+	exec[i++].flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+	if (HAS_BLT_RING(devid))
+		ring = I915_EXEC_BLT;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&exec);
+	execbuf.buffer_count = i;
+	execbuf.batch_len = len;
+	execbuf.flags = ring;
+	execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
+	execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
+	i915_execbuffer2_set_context_id(execbuf, ctx_id);
+	gem_execbuf(fd, &execbuf);
+}
+
+static void gem_copy(int fd, uint32_t src_obj, uint32_t dst_obj,
+		     void *src, void *dst, uint32_t size,
+		     uint32_t *ctx_id, int num_ctxts)
+{
+	uint32_t i, handle[MAX_CTXTS], rem = size;
+	uint32_t delta, npages = size / PAGE_SIZE;
+	uint64_t batch_va = get_batch_va(fd);
+
+	delta = (npages / num_ctxts) * PAGE_SIZE;
+	delta += (npages % num_ctxts) ? PAGE_SIZE : 0;
+	for (i = 0; i < num_ctxts; i++) {
+		handle[i] = gem_create(fd, PAGE_SIZE);
+		svm_info("Issuing gem copy on ctx 0x%x\n", ctx_id[i]);
+		__gem_copy(fd, src_obj, dst_obj, src, dst, (i * delta),
+			   min(rem, delta), ctx_id[i], handle[i], batch_va);
+		rem -= delta;
+		batch_va += BATCH_VA_STRIDE;
+	}
+
+	for (i = 0; i < num_ctxts; i++) {
+		gem_sync(fd, handle[i]);
+		svm_info("gem copy completed on ctx 0x%x\n", ctx_id[i]);
+		gem_close(fd, handle[i]);
+	}
+}
+
+static void run_rt(int fd, uint32_t size, bool migrate, bool copy,
+		   bool bind, bool unbind, int32_t num_ctxts)
+{
+	uint32_t i, npages = size / PAGE_SIZE;
+	uint32_t shared_vm_id, vm_id[MAX_CTXTS];
+	uint32_t ctx_id[MAX_CTXTS];
+	uint64_t src_va, dst_va;
+	uint32_t src, dst;
+	bool share_vm;
+	void *buf;
+
+	/* Fix parmeters; -ve num_ctxts means all contexts share the vm */
+	num_ctxts = num_ctxts ? : 1;
+	share_vm = num_ctxts < 0;
+	if (num_ctxts < 0)
+		num_ctxts = -num_ctxts;
+
+	/* For shared VM, we need to bind,unbind,en/disable SVM only once */
+	if (share_vm)
+		shared_vm_id = gem_vm_create(fd);
+
+	/* Create contexts and enable svm */
+	num_ctxts = min(MAX_CTXTS, num_ctxts);
+	for (i = 0; i < num_ctxts; i++) {
+		ctx_id[i] = gem_context_create(fd);
+		if (share_vm) {
+			vm_id[i] = shared_vm_id;
+			gem_ctx_set_vm(fd, ctx_id[i], vm_id[i]);
+		} else {
+			vm_id[i] = gem_ctx_get_vm(fd, ctx_id[i]);
+		}
+	}
+	for (i = 0; i < num_ctxts; i++) {
+		gem_vm_enable_svm(fd, vm_id[i]);
+		if (share_vm)
+			break;
+	}
+
+	/* Create objects */
+	src = gem_create(fd, size);
+	dst = gem_create(fd, size);
+
+	/* Static assignment */
+	src_va = 0xa000000;
+	dst_va = 0xb000000;
+
+	/* Allocate buffer and fill pattern */
+	buf = malloc(size);
+	for (i = 0; i < npages; i++)
+		memset(buf + i * PAGE_SIZE, i + 1, PAGE_SIZE);
+	gem_write(fd, src, 0, buf, size);
+	print_buffer(buf, size, "src_obj", false);
+	free(buf);
+
+	if (migrate) {
+		svm_info("Migrating obj 0x%x to smem region\n", src);
+		gem_migrate_to_smem(fd, src);
+
+		svm_info("Migrating obj 0x%x to smem region\n", dst);
+		gem_migrate_to_smem(fd, dst);
+	}
+
+	/* Bind the buffers to device page table */
+	/* XXX: Test READ_ONLY bindings */
+	for (i = 0; bind && (i < num_ctxts); i++) {
+		svm_info("Binding obj 0x%x at 0x%lx size 0x%x vm 0x%x\n",
+			 src, src_va, size, vm_id[i]);
+		gem_svm_bind(fd, src_va, src, vm_id[i], false);
+
+		svm_info("Binding obj 0x%x at 0x%lx size 0x%x vm 0x%x\n",
+			 dst, dst_va, size, vm_id[i]);
+		gem_svm_bind(fd, dst_va, dst, vm_id[i], false);
+
+		if (share_vm)
+			break;
+	}
+
+	/* Have GPU do the copy */
+	if (copy) {
+		if (bind)
+			gem_copy(fd, 0, 0, (void *)src_va, (void *)dst_va,
+				 size, ctx_id, num_ctxts);
+		else
+			gem_copy(fd, src, dst, (void *)src_va, (void *)dst_va,
+				 size, ctx_id, num_ctxts);
+	}
+
+	/*
+	 * Unbind buffers from device page table.
+	 * If not, it should get unbound while freeing the buffer.
+	 */
+	for (i = 0; unbind && (i < num_ctxts); i++) {
+		svm_info("Unbinding obj 0x%x vm 0x%x\n", src, vm_id[i]);
+		gem_svm_unbind(fd, src, vm_id[i]);
+
+		svm_info("Unbinding obj 0x%x vm 0x%x\n", dst, vm_id[i]);
+		gem_svm_unbind(fd, dst, vm_id[i]);
+
+		if (share_vm)
+			break;
+	}
+
+	if (migrate) {
+		svm_info("Migrating obj 0x%x to lmem region\n", src);
+		gem_migrate_to_lmem(fd, src);
+
+		svm_info("Migrating obj 0x%x to lmem region\n", dst);
+		gem_migrate_to_lmem(fd, dst);
+	}
+
+	print_object(fd, dst, size, "dst_obj", false);
+
+	/* Validate */
+	if (copy)
+		 igt_assert(objcmp(fd, src, dst, size) == 0);
+
+	/* Free the objects */
+	svm_debug("Closing object 0x%x\n", src);
+	gem_close(fd, src);
+	svm_debug("Closing object 0x%x\n", dst);
+	gem_close(fd, dst);
+
+	sleep(2); /* Wait for handles to get freed */
+
+	/* Done with the contexts */
+	for (i = 0; i < num_ctxts; i++) {
+		gem_vm_disable_svm(fd, vm_id[i]);
+		if (share_vm)
+			break;
+	}
+	for (i = 0; i < num_ctxts; i++) {
+		svm_debug("Destroying context 0x%x\n", ctx_id[i]);
+		gem_context_destroy(fd, ctx_id[i]);
+	}
+
+	if (share_vm)
+		gem_vm_destroy(fd, shared_vm_id);
+}
+
+igt_main
+{
+	struct {
+		const char *name;
+		uint32_t size;
+		bool migrate;
+		bool copy;
+		bool bind;
+		bool unbind;
+		int32_t num_ctxts;
+	} *r, rt_tests[] = {
+		/* Basic runtime allocator test */
+		{"rt_basic", 0, false, true, true, true, 1},
+
+		/* Skip GPU copy */
+		{"rt_no_gpu_copy", 0, false, false, true, true, 1},
+
+		/* Skip unbinding */
+		{"rt_no_unbind",  0, false, true, true, false, 1},
+
+		/* Skip explicit binding and bind in the execbuf path  */
+		{"rt_no_bind",  0, false, true, false, true, 1},
+
+		/* Use multiple contexts */
+		{"rt_multi_ctxts", 0, false, true, true, true, 2},
+
+		/* Use multiple contexts and share vm (-ve num_ctxts) */
+		{"rt_multi_ctxts_share_vm", 0, false, true, true, true, -2},
+
+		/* Use 64K buffers */
+		{"rt_64K", (16 * PAGE_SIZE), false, true, true, true, 1},
+
+		/* Use 2M buffers */
+		{"rt_2M", (512 * PAGE_SIZE), false, true, true, true, 1},
+	};
+	int fd, idx;
+	uint32_t def_size;
+	bool has_lmem;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+		igt_require_svm(fd);
+		has_lmem = gem_has_lmem(fd);
+		def_size = DEFAULT_BUFF_SIZE;
+	}
+
+	/* Below are runtime (rt) allocator tests */
+	for (idx = 0, r = rt_tests; idx < ARRAY_SIZE(rt_tests); idx++, r++) {
+		bool migrate = has_lmem ? r->migrate : false;
+		uint32_t size = r->size ? : def_size;
+
+		igt_subtest_f("%s",r->name)
+			run_rt(fd, size, migrate, r->copy, r->bind, r->unbind,
+			       r->num_ctxts);
+	}
+
+	igt_fixture {
+		close(fd);
+	}
+
+	igt_exit();
+}
diff --git a/tests/meson.build b/tests/meson.build
index 570de545..87021902 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -226,6 +226,7 @@ i915_progs = [
 	'gem_wait',
 	'gem_workarounds',
 	'gem_write_read_ring_switch',
+	'i915_svm_basic',
 	'i915_fb_tiling',
 	'i915_getparams_basic',
 	'i915_hangman',
-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [igt-dev] [RFC i-g-t 4/7] tests/i915/svm: Add mmap support for SVM RT allocator
  2019-12-13 21:54 [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjana Vishwanathapura
                   ` (2 preceding siblings ...)
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 3/7] tests/i915/svm: Add basic SVM RT allocator test support Niranjana Vishwanathapura
@ 2019-12-13 21:54 ` Niranjana Vishwanathapura
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 5/7] tests/i915/svm: Add basic SVM SYS allocator test support Niranjana Vishwanathapura
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Niranjana Vishwanathapura @ 2019-12-13 21:54 UTC (permalink / raw)
  To: igt-dev
  Cc: kenneth.w.graunke, sanjay.k.kumar, jason.ekstrand, dave.hansen,
	jglisse, jon.bloomfield, daniel.vetter, dan.j.williams,
	ira.weiny, jgg

mmap and directly access the runtime (RT) allocator buffer objects.
This further tests the implicit migration of buffer objects.

Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Sudeep Dutt <sudeep.dutt@intel.com>
Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com>
---
 tests/i915/i915_svm_basic.c | 53 ++++++++++++++++++++++++++-----------
 1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/tests/i915/i915_svm_basic.c b/tests/i915/i915_svm_basic.c
index 66949039..90159443 100644
--- a/tests/i915/i915_svm_basic.c
+++ b/tests/i915/i915_svm_basic.c
@@ -244,11 +244,12 @@ static void gem_copy(int fd, uint32_t src_obj, uint32_t dst_obj,
 }
 
 static void run_rt(int fd, uint32_t size, bool migrate, bool copy,
-		   bool bind, bool unbind, int32_t num_ctxts)
+		   bool bind, bool unbind, int32_t num_ctxts, bool mmap)
 {
 	uint32_t i, npages = size / PAGE_SIZE;
 	uint32_t shared_vm_id, vm_id[MAX_CTXTS];
 	uint32_t ctx_id[MAX_CTXTS];
+	void *src_addr, *dst_addr;
 	uint64_t src_va, dst_va;
 	uint32_t src, dst;
 	bool share_vm;
@@ -285,18 +286,32 @@ static void run_rt(int fd, uint32_t size, bool migrate, bool copy,
 	src = gem_create(fd, size);
 	dst = gem_create(fd, size);
 
-	/* Static assignment */
-	src_va = 0xa000000;
-	dst_va = 0xb000000;
+	if (mmap) {
+		src_addr = gem_mmap__wc(fd, src, 0, size, PROT_WRITE);
+		dst_addr = gem_mmap__wc(fd, dst, 0, size, PROT_WRITE);
+	}
+
+	if (mmap) {
+		 src_va = (uint64_t)src_addr;
+		 dst_va = (uint64_t)dst_addr;
+	} else {
+		/* Static assignment */
+		src_va = 0xa000000;
+		dst_va = 0xb000000;
+	}
 
 	/* Allocate buffer and fill pattern */
 	buf = malloc(size);
 	for (i = 0; i < npages; i++)
 		memset(buf + i * PAGE_SIZE, i + 1, PAGE_SIZE);
 	gem_write(fd, src, 0, buf, size);
-	print_buffer(buf, size, "src_obj", false);
 	free(buf);
 
+	if (mmap)
+		print_buffer(src_addr, size, "src_obj_mmap", false);
+	else
+		print_object(fd, src, size, "src_obj", false);
+
 	if (migrate) {
 		svm_info("Migrating obj 0x%x to smem region\n", src);
 		gem_migrate_to_smem(fd, src);
@@ -353,7 +368,11 @@ static void run_rt(int fd, uint32_t size, bool migrate, bool copy,
 		gem_migrate_to_lmem(fd, dst);
 	}
 
-	print_object(fd, dst, size, "dst_obj", false);
+	/* Accessing the buffer will migrate the pages from device to host */
+	if (mmap)
+		print_buffer(dst_addr, size, "dst_obj_mmap", false);
+	else
+		print_object(fd, dst, size, "dst_obj", false);
 
 	/* Validate */
 	if (copy)
@@ -392,30 +411,34 @@ igt_main
 		bool bind;
 		bool unbind;
 		int32_t num_ctxts;
+		bool mmap;
 	} *r, rt_tests[] = {
 		/* Basic runtime allocator test */
-		{"rt_basic", 0, false, true, true, true, 1},
+		{"rt_basic", 0, false, true, true, true, 1, false},
+
+		/* Basic runtime allocator test with mmap reads */
+		{"rt_basic_mmap", 0, false, true, true, true, 1, true},
 
 		/* Skip GPU copy */
-		{"rt_no_gpu_copy", 0, false, false, true, true, 1},
+		{"rt_no_gpu_copy", 0, false, false, true, true, 1, false},
 
 		/* Skip unbinding */
-		{"rt_no_unbind",  0, false, true, true, false, 1},
+		{"rt_no_unbind",  0, false, true, true, false, 1, false},
 
 		/* Skip explicit binding and bind in the execbuf path  */
-		{"rt_no_bind",  0, false, true, false, true, 1},
+		{"rt_no_bind",  0, false, true, false, true, 1, false},
 
 		/* Use multiple contexts */
-		{"rt_multi_ctxts", 0, false, true, true, true, 2},
+		{"rt_multi_ctxts", 0, false, true, true, true, 2, false},
 
 		/* Use multiple contexts and share vm (-ve num_ctxts) */
-		{"rt_multi_ctxts_share_vm", 0, false, true, true, true, -2},
+		{"rt_multi_ctxts_share_vm", 0, false, true, true, true, -2, false},
 
 		/* Use 64K buffers */
-		{"rt_64K", (16 * PAGE_SIZE), false, true, true, true, 1},
+		{"rt_64K", (16 * PAGE_SIZE), false, true, true, true, 1, false},
 
 		/* Use 2M buffers */
-		{"rt_2M", (512 * PAGE_SIZE), false, true, true, true, 1},
+		{"rt_2M", (512 * PAGE_SIZE), false, true, true, true, 1, false},
 	};
 	int fd, idx;
 	uint32_t def_size;
@@ -436,7 +459,7 @@ igt_main
 
 		igt_subtest_f("%s",r->name)
 			run_rt(fd, size, migrate, r->copy, r->bind, r->unbind,
-			       r->num_ctxts);
+			       r->num_ctxts, r->mmap);
 	}
 
 	igt_fixture {
-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [igt-dev] [RFC i-g-t 5/7] tests/i915/svm: Add basic SVM SYS allocator test support
  2019-12-13 21:54 [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjana Vishwanathapura
                   ` (3 preceding siblings ...)
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 4/7] tests/i915/svm: Add mmap support for SVM RT allocator Niranjana Vishwanathapura
@ 2019-12-13 21:54 ` Niranjana Vishwanathapura
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 6/7] tests/i915/svm: Add multiple process tests Niranjana Vishwanathapura
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Niranjana Vishwanathapura @ 2019-12-13 21:54 UTC (permalink / raw)
  To: igt-dev
  Cc: kenneth.w.graunke, sanjay.k.kumar, jason.ekstrand, dave.hansen,
	jglisse, jon.bloomfield, daniel.vetter, dan.j.williams,
	ira.weiny, jgg

Add basic tests for Shared Virtual Memory (SVM) system (SYS) allocator
functionality. Have GPU copy the data from a source buffer to
destination buffer by explicitly binding buffers in device page
table using shared virtual addresses.
Explicitly migrate buffers from host to device memory and expect it to
be migrated back to host memory upon CPU access.
Test for different buffer sizes, allocation method and with multiple
contexts.

Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/i915_svm_basic.c | 207 ++++++++++++++++++++++++++++++++++++
 1 file changed, 207 insertions(+)

diff --git a/tests/i915/i915_svm_basic.c b/tests/i915/i915_svm_basic.c
index 90159443..22461ba9 100644
--- a/tests/i915/i915_svm_basic.c
+++ b/tests/i915/i915_svm_basic.c
@@ -40,9 +40,16 @@
 
 #define MAX_CTXTS   4
 
+#define I915_SVM_ALLOC_ALIGN    0
+#define I915_SVM_ALLOC_MMAP     1
+#define I915_SVM_NUM_ALLOC      2
+
 #define svm_info    igt_info
 #define svm_debug   igt_debug
 
+static const char *
+alloc_type_str[I915_SVM_NUM_ALLOC] = { "align", "mmap" };
+
 /* gen8_canonical_addr
  * Used to convert any address into canonical form, i.e. [63:48] == [47].
  * Based on kernel's sign_extend64 implementation.
@@ -65,6 +72,35 @@ static inline uint32_t upper_32_bits(uint64_t x)
 	return x >> 32;
 }
 
+static void *svm_alloc(int size, int alloc_type, void *addr)
+{
+	void *ptr;
+
+	if (alloc_type == I915_SVM_ALLOC_MMAP) {
+		int flags = MAP_ANONYMOUS | MAP_PRIVATE;
+
+		flags |= addr ? MAP_FIXED : 0;
+		ptr = mmap(addr, size, PROT_READ | PROT_WRITE, flags, -1, 0);
+		igt_assert(ptr != MAP_FAILED);
+	} else {
+		igt_assert(posix_memalign(&ptr, 512 * PAGE_SIZE, size) == 0);
+	}
+
+	svm_debug("Allocated %sed buf 0x%lx\n",
+		  alloc_type_str[alloc_type], (uint64_t)ptr);
+	return ptr;
+}
+
+static void svm_free(void *ptr, int size, int alloc_type)
+{
+	svm_debug("Freeing %s buf 0x%lx\n",
+		  alloc_type_str[alloc_type], (uint64_t)ptr);
+	if (alloc_type == I915_SVM_ALLOC_MMAP)
+		munmap(ptr, size);
+	else
+		free(ptr);
+}
+
 static void print_buffer(void *buf, uint32_t size,
 			 const char *str, bool full)
 {
@@ -401,8 +437,169 @@ static void run_rt(int fd, uint32_t size, bool migrate, bool copy,
 		gem_vm_destroy(fd, shared_vm_id);
 }
 
+static void run_sys(int fd, uint32_t size, bool migrate, bool copy,
+		    int alloc_type, bool unbind, int32_t num_ctxts)
+{
+	uint32_t region = INTEL_MEMORY_REGION_ID(I915_DEVICE_MEMORY);
+	uint32_t i, npages = size / PAGE_SIZE;
+	uint32_t shared_vm_id, vm_id[MAX_CTXTS];
+	uint32_t ctx_id[MAX_CTXTS];
+	void *src, *dst;
+	bool share_vm;
+
+	/* Fix parmeters; -ve num_ctxts means all contexts share the vm */
+	num_ctxts = num_ctxts ? : 1;
+	share_vm = num_ctxts < 0;
+	if (num_ctxts < 0)
+		num_ctxts = -num_ctxts;
+
+	/* For shared VM, we need to bind,unbind,en/disable SVM only once */
+	if (share_vm)
+		shared_vm_id = gem_vm_create(fd);
+
+	/* Create contexts and enable svm */
+	num_ctxts = min(MAX_CTXTS, num_ctxts);
+	for (i = 0; i < num_ctxts; i++) {
+		ctx_id[i] = gem_context_create(fd);
+		if (share_vm) {
+			vm_id[i] = shared_vm_id;
+			gem_ctx_set_vm(fd, ctx_id[i], vm_id[i]);
+		} else {
+			vm_id[i] = gem_ctx_get_vm(fd, ctx_id[i]);
+		}
+	}
+	for (i = 0; i < num_ctxts; i++) {
+		gem_vm_enable_svm(fd, vm_id[i]);
+		if (share_vm)
+			break;
+	}
+
+	/* Allocate buffers */
+	src = svm_alloc(size, alloc_type, NULL);
+	dst = svm_alloc(size, alloc_type, NULL);
+
+	/* Fill patterns */
+	memset(dst, 0, size);
+	for (i = 0; i < npages; i++)
+		memset(src + i * PAGE_SIZE, i + 1, PAGE_SIZE);
+
+	print_buffer(src, size, "src", false);
+	print_buffer(dst, size, "dst", false);
+
+	/*
+	 * Explicitly migrate buffers to device memory, if specified.
+	 * Otherwise, buffers remain in host memory.
+	 */
+	if (migrate) {
+		svm_info("Migrating 0x%lx size 0x%x to mem region 0x%x\n",
+			 (uint64_t)src, size, region);
+		svm_prefetch(fd, src, size, region);
+
+		svm_info("Migrating 0x%lx size 0x%x to mem region 0x%x\n",
+			 (uint64_t)dst, size, region);
+		svm_prefetch(fd, dst, size, region);
+	}
+
+	/* Bind the buffers to device page table */
+	/* XXX: Test READ_ONLY bindings */
+	for (i = 0; i < num_ctxts; i++) {
+		svm_info("Binding 0x%lx size 0x%x vm 0x%x\n",
+			 (uint64_t)src, size, vm_id[i]);
+		svm_bind(fd, src, size, vm_id[i], false);
+
+		svm_info("Binding 0x%lx size 0x%x vm 0x%x\n",
+			 (uint64_t)dst, size, vm_id[i]);
+		svm_bind(fd, dst, size, vm_id[i], false);
+
+		if (share_vm)
+			break;
+	}
+
+	/* Have GPU do the copy */
+	if (copy)
+		gem_copy(fd, 0, 0, src, dst, size, ctx_id, num_ctxts);
+
+	/*
+	 * Unbind buffers from device page table.
+	 * If not, it should get unbound while freeing the buffer.
+	 */
+	if (unbind) {
+		for (i = 0; i < num_ctxts; i++) {
+			svm_info("Unbinding 0x%lx size 0x%x vm 0x%x\n",
+				 (uint64_t)src, size, vm_id[i]);
+			svm_unbind(fd, src, size, vm_id[i]);
+
+			svm_info("Unbinding 0x%lx size 0x%x vm 0x%x\n",
+				 (uint64_t)dst, size, vm_id[i]);
+			svm_unbind(fd, dst, size, vm_id[i]);
+
+			if (share_vm)
+				break;
+		}
+	}
+
+	/* Accessing the buffer will migrate the pages from device to host */
+	print_buffer(dst, size, "dst", false);
+
+	/* Validate */
+	if (copy)
+		igt_assert(memcmp(src, dst, size) == 0);
+
+	/* Free the buffers */
+	svm_free(dst, size, alloc_type);
+	svm_free(src, size, alloc_type);
+
+	/* Done with the contexts */
+	for (i = 0; i < num_ctxts; i++) {
+		gem_vm_disable_svm(fd, vm_id[i]);
+		if (share_vm)
+			break;
+	}
+	for (i = 0; i < num_ctxts; i++) {
+		svm_debug("Destroying context 0x%x\n", ctx_id[i]);
+		gem_context_destroy(fd, ctx_id[i]);
+	}
+
+	if (share_vm)
+		gem_vm_destroy(fd, shared_vm_id);
+}
+
 igt_main
 {
+	struct {
+		const char *name;
+		uint32_t size;
+		bool migrate;
+		bool copy;
+		int alloc_type;
+		bool unbind;
+		int32_t num_ctxts;
+	}*s, sys_tests[] = {
+		/* Basic test */
+		{"sys_basic", 0, true, true, I915_SVM_ALLOC_ALIGN, true, 1},
+
+		/* Skip GPU copy */
+		{"sys_no_gpu_copy", 0, true, false, I915_SVM_ALLOC_ALIGN, true, 1},
+
+		/* Skip unbinding; should get unbound while freeing */
+		{"sys_no_unbind", 0, true, true, I915_SVM_ALLOC_ALIGN, false, 1},
+
+		/* Use multiple contexts */
+		{"sys_multi_ctxts", 0, true, true, I915_SVM_ALLOC_ALIGN, true, 2},
+
+		/* Use multiple contexts and share vm (-ve num_ctxts) */
+		{"sys_multi_ctxts_share_vm", 0, true, true, I915_SVM_ALLOC_ALIGN, true, -2},
+
+		/* Use 64K buffers */
+		{"sys_64K", (16 * PAGE_SIZE), true, true, I915_SVM_ALLOC_ALIGN, true, 1},
+
+		/* Use 2M buffers */
+		{"sys_2M", (512 * PAGE_SIZE), true, true, I915_SVM_ALLOC_ALIGN, true, 1},
+
+		/* Allocate using mmap */
+		{"sys_mmap", 0, true, true, I915_SVM_ALLOC_MMAP, true, 1},
+	};
+
 	struct {
 		const char *name;
 		uint32_t size;
@@ -452,6 +649,16 @@ igt_main
 		def_size = DEFAULT_BUFF_SIZE;
 	}
 
+	/* Below are System (sys) allocator tests */
+	for (idx = 0, s = sys_tests; idx < ARRAY_SIZE(sys_tests); idx++, s++) {
+		bool migrate = has_lmem ? s->migrate : false;
+		uint32_t size = s->size ? : def_size;
+
+		igt_subtest_f("%s",s->name)
+			run_sys(fd, size, migrate, s->copy, s->alloc_type,
+				s->unbind, s->num_ctxts);
+	}
+
 	/* Below are runtime (rt) allocator tests */
 	for (idx = 0, r = rt_tests; idx < ARRAY_SIZE(rt_tests); idx++, r++) {
 		bool migrate = has_lmem ? r->migrate : false;
-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [igt-dev] [RFC i-g-t 6/7] tests/i915/svm: Add multiple process tests
  2019-12-13 21:54 [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjana Vishwanathapura
                   ` (4 preceding siblings ...)
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 5/7] tests/i915/svm: Add basic SVM SYS allocator test support Niranjana Vishwanathapura
@ 2019-12-13 21:54 ` Niranjana Vishwanathapura
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 7/7] tests/i915/svm: Add stress test Niranjana Vishwanathapura
  2019-12-13 22:01 ` [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjan Vishwanathapura
  7 siblings, 0 replies; 9+ messages in thread
From: Niranjana Vishwanathapura @ 2019-12-13 21:54 UTC (permalink / raw)
  To: igt-dev
  Cc: kenneth.w.graunke, sanjay.k.kumar, jason.ekstrand, dave.hansen,
	jglisse, jon.bloomfield, daniel.vetter, dan.j.williams,
	ira.weiny, jgg

Test with multiple processes as each has its own address space.

Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Sudeep Dutt <sudeep.dutt@intel.com>
Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com>
---
 tests/i915/i915_svm_basic.c | 70 ++++++++++++++++++++++++++++++++-----
 1 file changed, 62 insertions(+), 8 deletions(-)

diff --git a/tests/i915/i915_svm_basic.c b/tests/i915/i915_svm_basic.c
index 22461ba9..568ee321 100644
--- a/tests/i915/i915_svm_basic.c
+++ b/tests/i915/i915_svm_basic.c
@@ -44,8 +44,10 @@
 #define I915_SVM_ALLOC_MMAP     1
 #define I915_SVM_NUM_ALLOC      2
 
-#define svm_info    igt_info
-#define svm_debug   igt_debug
+#define NUM_PROCS   2
+
+#define svm_info(f, ...)   igt_info("PID-%d: "f, getpid(), __VA_ARGS__)
+#define svm_debug(f, ...)  igt_debug("PID-%d: "f, getpid(), __VA_ARGS__)
 
 static const char *
 alloc_type_str[I915_SVM_NUM_ALLOC] = { "align", "mmap" };
@@ -279,8 +281,8 @@ static void gem_copy(int fd, uint32_t src_obj, uint32_t dst_obj,
 	}
 }
 
-static void run_rt(int fd, uint32_t size, bool migrate, bool copy,
-		   bool bind, bool unbind, int32_t num_ctxts, bool mmap)
+static void do_run_rt(int fd, uint32_t size, bool migrate, bool copy,
+		      bool bind, bool unbind, int32_t num_ctxts, bool mmap)
 {
 	uint32_t i, npages = size / PAGE_SIZE;
 	uint32_t shared_vm_id, vm_id[MAX_CTXTS];
@@ -437,8 +439,25 @@ static void run_rt(int fd, uint32_t size, bool migrate, bool copy,
 		gem_vm_destroy(fd, shared_vm_id);
 }
 
-static void run_sys(int fd, uint32_t size, bool migrate, bool copy,
-		    int alloc_type, bool unbind, int32_t num_ctxts)
+static void run_rt(int fd, uint32_t size, bool migrate, bool copy,
+		   bool bind, bool unbind, int32_t num_ctxts,
+		   bool mmap, uint32_t num_child)
+{
+	if (!num_child) {
+		do_run_rt(fd, size, migrate, copy, bind, unbind,
+			  num_ctxts, mmap);
+		return;
+	}
+
+	igt_fork(child, num_child) {
+		do_run_rt(fd, size, migrate, copy, bind, unbind,
+			  num_ctxts, mmap);
+	}
+	igt_waitchildren();
+}
+
+static void do_run_sys(int fd, uint32_t size, bool migrate, bool copy,
+		       int alloc_type, bool unbind, int32_t num_ctxts)
 {
 	uint32_t region = INTEL_MEMORY_REGION_ID(I915_DEVICE_MEMORY);
 	uint32_t i, npages = size / PAGE_SIZE;
@@ -564,6 +583,23 @@ static void run_sys(int fd, uint32_t size, bool migrate, bool copy,
 		gem_vm_destroy(fd, shared_vm_id);
 }
 
+static void run_sys(int fd, uint32_t size, bool migrate, bool copy,
+		    int alloc_type, bool unbind, int32_t num_ctxts,
+		    uint32_t num_child)
+{
+	if (!num_child) {
+		do_run_sys(fd, size, migrate, copy, alloc_type,
+			   unbind, num_ctxts);
+		return;
+	}
+
+	igt_fork(child, num_child) {
+		do_run_sys(fd, size, migrate, copy, alloc_type,
+			   unbind, num_ctxts);
+	}
+	igt_waitchildren();
+}
+
 igt_main
 {
 	struct {
@@ -656,7 +692,16 @@ igt_main
 
 		igt_subtest_f("%s",s->name)
 			run_sys(fd, size, migrate, s->copy, s->alloc_type,
-				s->unbind, s->num_ctxts);
+				s->unbind, s->num_ctxts, 0);
+	}
+
+	for (idx = 0, s = sys_tests; idx < ARRAY_SIZE(sys_tests); idx++, s++) {
+		bool migrate = has_lmem ? s->migrate : false;
+		uint32_t size = s->size ? : def_size;
+
+		igt_subtest_f("%s_mprocs",s->name)
+			run_sys(fd, size, migrate, s->copy, s->alloc_type,
+				s->unbind, s->num_ctxts, NUM_PROCS);
 	}
 
 	/* Below are runtime (rt) allocator tests */
@@ -666,7 +711,16 @@ igt_main
 
 		igt_subtest_f("%s",r->name)
 			run_rt(fd, size, migrate, r->copy, r->bind, r->unbind,
-			       r->num_ctxts, r->mmap);
+			       r->num_ctxts, r->mmap, 0);
+	}
+
+	for (idx = 0, r = rt_tests; idx < ARRAY_SIZE(rt_tests); idx++, r++) {
+		bool migrate = has_lmem ? r->migrate : false;
+		uint32_t size = r->size ? : def_size;
+
+		igt_subtest_f("%s_mprocs",r->name)
+			run_rt(fd, size, migrate, r->copy, r->bind, r->unbind,
+			       r->num_ctxts, r->mmap, NUM_PROCS);
 	}
 
 	igt_fixture {
-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [igt-dev] [RFC i-g-t 7/7] tests/i915/svm: Add stress test
  2019-12-13 21:54 [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjana Vishwanathapura
                   ` (5 preceding siblings ...)
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 6/7] tests/i915/svm: Add multiple process tests Niranjana Vishwanathapura
@ 2019-12-13 21:54 ` Niranjana Vishwanathapura
  2019-12-13 22:01 ` [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjan Vishwanathapura
  7 siblings, 0 replies; 9+ messages in thread
From: Niranjana Vishwanathapura @ 2019-12-13 21:54 UTC (permalink / raw)
  To: igt-dev
  Cc: kenneth.w.graunke, sanjay.k.kumar, jason.ekstrand, dave.hansen,
	jglisse, jon.bloomfield, daniel.vetter, dan.j.williams,
	ira.weiny, jgg

Run multiple processes in parallel each running a number of random
tests. Make number of processes and number of tests to run configurable.

Usage:
./i915_svm_basic --stress
./i915_svm_basic -s 0x00xxyyzz
where,
xx = delay b/w tests
yy = number of tests each process should run
zz = number of proccesses to run in parallel

Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: Vanshidhar Konda <vanshidhar.r.konda@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/i915_svm_basic.c | 81 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 2 deletions(-)

diff --git a/tests/i915/i915_svm_basic.c b/tests/i915/i915_svm_basic.c
index 568ee321..e8ff671d 100644
--- a/tests/i915/i915_svm_basic.c
+++ b/tests/i915/i915_svm_basic.c
@@ -600,7 +600,41 @@ static void run_sys(int fd, uint32_t size, bool migrate, bool copy,
 	igt_waitchildren();
 }
 
-igt_main
+static uint8_t stress_num_child = 2;
+static uint8_t stress_iters = 2;
+static uint8_t stress_delay = 2;
+static bool stress;
+
+static int opt_handler(int opt, int opt_index, void *data)
+{
+	uint32_t tmp;
+
+	switch (opt) {
+	case 's':
+		stress = true;
+		if (optarg) {
+			tmp = strtoul(optarg, NULL, 0);
+			stress_num_child = tmp & 0xff;
+			stress_iters = (tmp & 0x0000ff00) >> 8;
+			stress_delay = (tmp & 0x00ff0000) >> 16;
+		}
+		if (!stress_num_child || !stress_iters)
+			return IGT_OPT_HANDLER_ERROR;
+		break;
+	default:
+		return IGT_OPT_HANDLER_ERROR;
+	}
+
+	return IGT_OPT_HANDLER_SUCCESS;
+}
+
+const char *help_str = "  --stress|-s\t\tRun the stress test.\n";
+static struct option long_options[] = {
+	{"stress", 0, 0, 's'},
+	{ NULL, 0, 0, 0 }
+};
+
+igt_main_args("s:", long_options, help_str, opt_handler, NULL)
 {
 	struct {
 		const char *name;
@@ -685,6 +719,49 @@ igt_main
 		def_size = DEFAULT_BUFF_SIZE;
 	}
 
+	if (stress) {
+		igt_subtest_f("stress") {
+			igt_fork(child, stress_num_child) {
+				uint32_t num_sys_tests, num_rt_tests;
+				uint32_t i, n, type, size;
+				bool migrate;
+
+				srand(__INT_MAX__);
+				num_sys_tests = ARRAY_SIZE(sys_tests);
+				num_rt_tests = ARRAY_SIZE(rt_tests);
+
+				for (i = 0; i < stress_iters; i++) {
+					svm_info("Running iter %d\n", i + 1);
+					type = rand() % 2;
+					if (type) {
+						n = rand() % num_sys_tests;
+						s = &sys_tests[n];
+						migrate = has_lmem ? s->migrate : false;
+						size = s->size ? : def_size;
+
+						svm_info("Running test %s\n", s->name);
+						run_sys(fd, size, migrate, s->copy,
+							s->alloc_type, s->unbind,
+							s->num_ctxts, 0);
+					} else {
+						n = rand() % num_rt_tests;
+						r = &rt_tests[n];
+						migrate = has_lmem ? r->migrate : false;
+						size = r->size ? : def_size;
+
+						svm_info("Running test %s\n", r->name);
+						run_rt(fd, size, migrate, r->copy, r->bind,
+						       r->unbind, r->num_ctxts, r->mmap, 0);
+					}
+					if (stress_delay)
+						sleep(stress_delay);
+				}
+			}
+			igt_waitchildren();
+		}
+		goto out;
+	}
+
 	/* Below are System (sys) allocator tests */
 	for (idx = 0, s = sys_tests; idx < ARRAY_SIZE(sys_tests); idx++, s++) {
 		bool migrate = has_lmem ? s->migrate : false;
@@ -722,7 +799,7 @@ igt_main
 			run_rt(fd, size, migrate, r->copy, r->bind, r->unbind,
 			       r->num_ctxts, r->mmap, NUM_PROCS);
 	}
-
+out:
 	igt_fixture {
 		close(fd);
 	}
-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test
  2019-12-13 21:54 [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjana Vishwanathapura
                   ` (6 preceding siblings ...)
  2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 7/7] tests/i915/svm: Add stress test Niranjana Vishwanathapura
@ 2019-12-13 22:01 ` Niranjan Vishwanathapura
  7 siblings, 0 replies; 9+ messages in thread
From: Niranjan Vishwanathapura @ 2019-12-13 22:01 UTC (permalink / raw)
  To: igt-dev
  Cc: kenneth.w.graunke, sanjay.k.kumar, jason.ekstrand, dave.hansen,
	jglisse, jon.bloomfield, daniel.vetter, dan.j.williams,
	ira.weiny, jgg

On Fri, Dec 13, 2019 at 01:54:22PM -0800, Niranjana Vishwanathapura wrote:
>Shared Virtual Memory (SVM) allows the programmer to use a single virtual
>address space which will be shared between threads executing on CPUs and GPUs.
>It abstracts away from the user the location of the backing memory, and hence
>simplifies the user programming model.
>SVM supports two types of virtual memory allocation methods.
>Runtime allocator requires a driver to provide memory allocation and
>management interface like buffer object (BO) interface.
>Whereas system allocator makes use of default OS memory allocation and
>management support (like malloc()).
>
>This patch series validates both SVM system and runtime allocator support.
>
>The patch series adds driver interface and some test cases.
>It tests for
> - Binding an address range or a BO in device page table
> - Migrating of pages to and from device memory
> - GPU access to memory through shared virtual address space
> - Implicit migration back to host memory upon CPU access
> - SVM capability and configurability on per vm basis
> - Large mappings
> - Both CPU copy and blitter copy of pages
> - Multiple context/vm support
> - Proper unbinding when the buffer is freed
> - Different allocation methods
> - Stress test
> - etc.
>

Required i915 driver support is posted here.
https://lists.freedesktop.org/archives/intel-gfx/2019-December/223480.html

Thanks,
Niranjana

>Niranjana (1):
>  drm-uapi: Import SVM UAPI
>
>Niranjana Vishwanathapura (6):
>  lib: Add interface to support SVM
>  tests/i915/svm: Add basic SVM RT allocator test support
>  tests/i915/svm: Add mmap support for SVM RT allocator
>  tests/i915/svm: Add basic SVM SYS allocator test support
>  tests/i915/svm: Add multiple process tests
>  tests/i915/svm: Add stress test
>
> include/drm-uapi/i915_drm.h |  74 ++++
> lib/i915/gem_context.c      |  27 ++
> lib/i915/gem_context.h      |   2 +
> lib/i915/gem_vm.c           |  48 +++
> lib/i915/gem_vm.h           |   6 +
> lib/ioctl_wrappers.c        | 154 +++++++
> lib/ioctl_wrappers.h        |  14 +
> tests/Makefile.sources      |   3 +
> tests/i915/i915_svm_basic.c | 808 ++++++++++++++++++++++++++++++++++++
> tests/meson.build           |   1 +
> 10 files changed, 1137 insertions(+)
> create mode 100644 tests/i915/i915_svm_basic.c
>
>-- 
>2.21.0.rc0.32.g243a4c7e27
>
>_______________________________________________
>igt-dev mailing list
>igt-dev@lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-12-13 22:13 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-13 21:54 [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjana Vishwanathapura
2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 1/7] drm-uapi: Import SVM UAPI Niranjana Vishwanathapura
2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 2/7] lib: Add interface to support SVM Niranjana Vishwanathapura
2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 3/7] tests/i915/svm: Add basic SVM RT allocator test support Niranjana Vishwanathapura
2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 4/7] tests/i915/svm: Add mmap support for SVM RT allocator Niranjana Vishwanathapura
2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 5/7] tests/i915/svm: Add basic SVM SYS allocator test support Niranjana Vishwanathapura
2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 6/7] tests/i915/svm: Add multiple process tests Niranjana Vishwanathapura
2019-12-13 21:54 ` [igt-dev] [RFC i-g-t 7/7] tests/i915/svm: Add stress test Niranjana Vishwanathapura
2019-12-13 22:01 ` [igt-dev] [RFC i-g-t 0/7] tests/i915/svm: Shared Virtual Memory (SVM) test Niranjan Vishwanathapura

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.